aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2013-08-23 17:46:38 +0000
committerEd Maste <emaste@FreeBSD.org>2013-08-23 17:46:38 +0000
commitf034231a6a1fd5d6395206c1651de8cd9402cca3 (patch)
treef561dabc721ad515599172c16da3a4400b7f4aec /include
downloadsrc-f034231a6a1fd5d6395206c1651de8cd9402cca3.tar.gz
src-f034231a6a1fd5d6395206c1651de8cd9402cca3.zip
Import lldb as of SVN r188801
(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=254721
Diffstat (limited to 'include')
-rw-r--r--include/lldb/API/LLDB.h54
-rw-r--r--include/lldb/API/SBAddress.h150
-rw-r--r--include/lldb/API/SBBlock.h123
-rw-r--r--include/lldb/API/SBBreakpoint.h175
-rw-r--r--include/lldb/API/SBBreakpointLocation.h110
-rw-r--r--include/lldb/API/SBBroadcaster.h97
-rw-r--r--include/lldb/API/SBCommandInterpreter.h193
-rw-r--r--include/lldb/API/SBCommandReturnObject.h133
-rw-r--r--include/lldb/API/SBCommunication.h99
-rw-r--r--include/lldb/API/SBCompileUnit.h116
-rw-r--r--include/lldb/API/SBData.h180
-rw-r--r--include/lldb/API/SBDebugger.h339
-rw-r--r--include/lldb/API/SBDeclaration.h89
-rw-r--r--include/lldb/API/SBDefines.h84
-rw-r--r--include/lldb/API/SBError.h106
-rw-r--r--include/lldb/API/SBEvent.h102
-rw-r--r--include/lldb/API/SBExpressionOptions.h89
-rw-r--r--include/lldb/API/SBFileSpec.h96
-rw-r--r--include/lldb/API/SBFileSpecList.h72
-rw-r--r--include/lldb/API/SBFrame.h242
-rw-r--r--include/lldb/API/SBFunction.h93
-rw-r--r--include/lldb/API/SBHostOS.h57
-rw-r--r--include/lldb/API/SBInputReader.h97
-rw-r--r--include/lldb/API/SBInstruction.h94
-rw-r--r--include/lldb/API/SBInstructionList.h71
-rw-r--r--include/lldb/API/SBLineEntry.h99
-rw-r--r--include/lldb/API/SBListener.h135
-rw-r--r--include/lldb/API/SBModule.h287
-rw-r--r--include/lldb/API/SBModuleSpec.h154
-rw-r--r--include/lldb/API/SBProcess.h295
-rw-r--r--include/lldb/API/SBSection.h104
-rw-r--r--include/lldb/API/SBSourceManager.h53
-rw-r--r--include/lldb/API/SBStream.h111
-rw-r--r--include/lldb/API/SBStringList.h71
-rw-r--r--include/lldb/API/SBSymbol.h109
-rw-r--r--include/lldb/API/SBSymbolContext.h94
-rw-r--r--include/lldb/API/SBSymbolContextList.h69
-rw-r--r--include/lldb/API/SBTarget.h828
-rw-r--r--include/lldb/API/SBThread.h220
-rw-r--r--include/lldb/API/SBType.h244
-rw-r--r--include/lldb/API/SBTypeCategory.h168
-rw-r--r--include/lldb/API/SBTypeFilter.h92
-rw-r--r--include/lldb/API/SBTypeFormat.h84
-rw-r--r--include/lldb/API/SBTypeNameSpecifier.h77
-rw-r--r--include/lldb/API/SBTypeSummary.h115
-rw-r--r--include/lldb/API/SBTypeSynthetic.h102
-rw-r--r--include/lldb/API/SBValue.h488
-rw-r--r--include/lldb/API/SBValueList.h93
-rw-r--r--include/lldb/API/SBWatchpoint.h104
-rw-r--r--include/lldb/Breakpoint/Breakpoint.h630
-rw-r--r--include/lldb/Breakpoint/BreakpointID.h117
-rw-r--r--include/lldb/Breakpoint/BreakpointIDList.h82
-rw-r--r--include/lldb/Breakpoint/BreakpointList.h193
-rw-r--r--include/lldb/Breakpoint/BreakpointLocation.h401
-rw-r--r--include/lldb/Breakpoint/BreakpointLocationCollection.h209
-rw-r--r--include/lldb/Breakpoint/BreakpointLocationList.h269
-rw-r--r--include/lldb/Breakpoint/BreakpointOptions.h358
-rw-r--r--include/lldb/Breakpoint/BreakpointResolver.h147
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverAddress.h74
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverFileLine.h74
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverFileRegex.h68
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverName.h122
-rw-r--r--include/lldb/Breakpoint/BreakpointSite.h295
-rw-r--r--include/lldb/Breakpoint/BreakpointSiteList.h216
-rw-r--r--include/lldb/Breakpoint/Stoppoint.h63
-rw-r--r--include/lldb/Breakpoint/StoppointCallbackContext.h58
-rw-r--r--include/lldb/Breakpoint/StoppointLocation.h147
-rw-r--r--include/lldb/Breakpoint/Watchpoint.h252
-rw-r--r--include/lldb/Breakpoint/WatchpointList.h276
-rw-r--r--include/lldb/Breakpoint/WatchpointOptions.h255
-rw-r--r--include/lldb/Core/Address.h570
-rw-r--r--include/lldb/Core/AddressRange.h284
-rw-r--r--include/lldb/Core/AddressResolver.h89
-rw-r--r--include/lldb/Core/AddressResolverFileLine.h59
-rw-r--r--include/lldb/Core/AddressResolverName.h68
-rw-r--r--include/lldb/Core/ArchSpec.h422
-rw-r--r--include/lldb/Core/Baton.h62
-rw-r--r--include/lldb/Core/Broadcaster.h475
-rw-r--r--include/lldb/Core/ClangForward.h136
-rw-r--r--include/lldb/Core/Communication.h413
-rw-r--r--include/lldb/Core/Connection.h162
-rw-r--r--include/lldb/Core/ConnectionFileDescriptor.h139
-rw-r--r--include/lldb/Core/ConnectionMachPort.h92
-rw-r--r--include/lldb/Core/ConnectionSharedMemory.h70
-rw-r--r--include/lldb/Core/ConstString.h507
-rw-r--r--include/lldb/Core/DataBuffer.h94
-rw-r--r--include/lldb/Core/DataBufferHeap.h139
-rw-r--r--include/lldb/Core/DataBufferMemoryMap.h160
-rw-r--r--include/lldb/Core/DataEncoder.h459
-rw-r--r--include/lldb/Core/DataExtractor.h1298
-rw-r--r--include/lldb/Core/Debugger.h397
-rw-r--r--include/lldb/Core/Disassembler.h422
-rw-r--r--include/lldb/Core/EmulateInstruction.h641
-rw-r--r--include/lldb/Core/Error.h312
-rw-r--r--include/lldb/Core/Event.h217
-rw-r--r--include/lldb/Core/FileLineResolver.h81
-rw-r--r--include/lldb/Core/FileSpecList.h243
-rw-r--r--include/lldb/Core/Flags.h253
-rw-r--r--include/lldb/Core/History.h177
-rw-r--r--include/lldb/Core/IOStreamMacros.h38
-rw-r--r--include/lldb/Core/InputReader.h274
-rw-r--r--include/lldb/Core/InputReaderEZ.h87
-rw-r--r--include/lldb/Core/InputReaderStack.h58
-rw-r--r--include/lldb/Core/Language.h117
-rw-r--r--include/lldb/Core/Listener.h194
-rw-r--r--include/lldb/Core/Log.h236
-rw-r--r--include/lldb/Core/Mangled.h306
-rw-r--r--include/lldb/Core/MappedHash.h552
-rw-r--r--include/lldb/Core/Module.h1085
-rw-r--r--include/lldb/Core/ModuleChild.h90
-rw-r--r--include/lldb/Core/ModuleList.h556
-rw-r--r--include/lldb/Core/ModuleSpec.h594
-rw-r--r--include/lldb/Core/Opcode.h270
-rw-r--r--include/lldb/Core/PluginInterface.h37
-rw-r--r--include/lldb/Core/PluginManager.h352
-rw-r--r--include/lldb/Core/RangeMap.h1543
-rw-r--r--include/lldb/Core/RegisterValue.h406
-rw-r--r--include/lldb/Core/RegularExpression.h253
-rw-r--r--include/lldb/Core/STLUtils.h94
-rw-r--r--include/lldb/Core/Scalar.h341
-rw-r--r--include/lldb/Core/SearchFilter.h447
-rw-r--r--include/lldb/Core/Section.h313
-rw-r--r--include/lldb/Core/SourceManager.h196
-rw-r--r--include/lldb/Core/State.h78
-rw-r--r--include/lldb/Core/Stream.h612
-rw-r--r--include/lldb/Core/StreamAsynchronousIO.h42
-rw-r--r--include/lldb/Core/StreamBuffer.h87
-rw-r--r--include/lldb/Core/StreamCallback.h47
-rw-r--r--include/lldb/Core/StreamFile.h75
-rw-r--r--include/lldb/Core/StreamString.h64
-rw-r--r--include/lldb/Core/StreamTee.h175
-rw-r--r--include/lldb/Core/StringList.h107
-rw-r--r--include/lldb/Core/ThreadSafeSTLMap.h184
-rw-r--r--include/lldb/Core/ThreadSafeValue.h96
-rw-r--r--include/lldb/Core/Timer.h160
-rw-r--r--include/lldb/Core/UUID.h109
-rw-r--r--include/lldb/Core/UniqueCStringMap.h361
-rw-r--r--include/lldb/Core/UserID.h130
-rw-r--r--include/lldb/Core/UserSettingsController.h98
-rw-r--r--include/lldb/Core/VMRange.h181
-rw-r--r--include/lldb/Core/Value.h314
-rw-r--r--include/lldb/Core/ValueObject.h1375
-rw-r--r--include/lldb/Core/ValueObjectCast.h87
-rw-r--r--include/lldb/Core/ValueObjectChild.h122
-rw-r--r--include/lldb/Core/ValueObjectConstResult.h179
-rw-r--r--include/lldb/Core/ValueObjectConstResultChild.h77
-rw-r--r--include/lldb/Core/ValueObjectConstResultImpl.h96
-rw-r--r--include/lldb/Core/ValueObjectDynamicValue.h133
-rw-r--r--include/lldb/Core/ValueObjectList.h90
-rw-r--r--include/lldb/Core/ValueObjectMemory.h91
-rw-r--r--include/lldb/Core/ValueObjectRegister.h195
-rw-r--r--include/lldb/Core/ValueObjectSyntheticFilter.h182
-rw-r--r--include/lldb/Core/ValueObjectVariable.h90
-rw-r--r--include/lldb/Core/dwarf.h64
-rw-r--r--include/lldb/DataFormatters/CXXFormatterFunctions.h874
-rw-r--r--include/lldb/DataFormatters/DataVisualization.h174
-rw-r--r--include/lldb/DataFormatters/FormatCache.h101
-rw-r--r--include/lldb/DataFormatters/FormatClasses.h128
-rw-r--r--include/lldb/DataFormatters/FormatManager.h251
-rw-r--r--include/lldb/DataFormatters/FormatNavigator.h690
-rw-r--r--include/lldb/DataFormatters/TypeCategory.h230
-rw-r--r--include/lldb/DataFormatters/TypeCategoryMap.h148
-rw-r--r--include/lldb/DataFormatters/TypeFormat.h220
-rw-r--r--include/lldb/DataFormatters/TypeSummary.h547
-rw-r--r--include/lldb/DataFormatters/TypeSynthetic.h594
-rw-r--r--include/lldb/Expression/ASTDumper.h43
-rw-r--r--include/lldb/Expression/ASTResultSynthesizer.h184
-rw-r--r--include/lldb/Expression/ASTStructExtractor.h156
-rw-r--r--include/lldb/Expression/ClangASTSource.h530
-rw-r--r--include/lldb/Expression/ClangExpression.h153
-rw-r--r--include/lldb/Expression/ClangExpressionDeclMap.h698
-rw-r--r--include/lldb/Expression/ClangExpressionParser.h151
-rw-r--r--include/lldb/Expression/ClangExpressionVariable.h451
-rw-r--r--include/lldb/Expression/ClangFunction.h652
-rw-r--r--include/lldb/Expression/ClangPersistentVariables.h75
-rw-r--r--include/lldb/Expression/ClangUserExpression.h432
-rw-r--r--include/lldb/Expression/ClangUtilityFunction.h179
-rw-r--r--include/lldb/Expression/DWARFExpression.h424
-rw-r--r--include/lldb/Expression/ExpressionSourceCode.h78
-rw-r--r--include/lldb/Expression/IRDynamicChecks.h169
-rw-r--r--include/lldb/Expression/IRExecutionUnit.h495
-rw-r--r--include/lldb/Expression/IRForTarget.h733
-rw-r--r--include/lldb/Expression/IRInterpreter.h64
-rw-r--r--include/lldb/Expression/IRMemoryMap.h126
-rw-r--r--include/lldb/Expression/IRToDWARF.h111
-rw-r--r--include/lldb/Expression/Materializer.h173
-rw-r--r--include/lldb/Host/Condition.h124
-rw-r--r--include/lldb/Host/Config.h35
-rw-r--r--include/lldb/Host/DynamicLibrary.h51
-rw-r--r--include/lldb/Host/Endian.h33
-rw-r--r--include/lldb/Host/File.h500
-rw-r--r--include/lldb/Host/FileSpec.h692
-rw-r--r--include/lldb/Host/Host.h502
-rw-r--r--include/lldb/Host/Mutex.h312
-rw-r--r--include/lldb/Host/Predicate.h509
-rw-r--r--include/lldb/Host/ProcessRunLock.h165
-rw-r--r--include/lldb/Host/SocketAddress.h256
-rw-r--r--include/lldb/Host/Symbols.h69
-rw-r--r--include/lldb/Host/Terminal.h254
-rw-r--r--include/lldb/Host/TimeValue.h107
-rw-r--r--include/lldb/Host/freebsd/Config.h28
-rw-r--r--include/lldb/Interpreter/Args.h467
-rw-r--r--include/lldb/Interpreter/CommandCompletions.h307
-rw-r--r--include/lldb/Interpreter/CommandHistory.h76
-rw-r--r--include/lldb/Interpreter/CommandInterpreter.h486
-rw-r--r--include/lldb/Interpreter/CommandObject.h608
-rw-r--r--include/lldb/Interpreter/CommandObjectMultiword.h187
-rw-r--r--include/lldb/Interpreter/CommandObjectRegexCommand.h81
-rw-r--r--include/lldb/Interpreter/CommandReturnObject.h183
-rw-r--r--include/lldb/Interpreter/OptionGroupArchitecture.h73
-rw-r--r--include/lldb/Interpreter/OptionGroupBoolean.h83
-rw-r--r--include/lldb/Interpreter/OptionGroupFile.h142
-rw-r--r--include/lldb/Interpreter/OptionGroupFormat.h133
-rw-r--r--include/lldb/Interpreter/OptionGroupOutputFile.h76
-rw-r--r--include/lldb/Interpreter/OptionGroupPlatform.h120
-rw-r--r--include/lldb/Interpreter/OptionGroupString.h82
-rw-r--r--include/lldb/Interpreter/OptionGroupUInt64.h82
-rw-r--r--include/lldb/Interpreter/OptionGroupUUID.h61
-rw-r--r--include/lldb/Interpreter/OptionGroupValueObjectDisplay.h85
-rw-r--r--include/lldb/Interpreter/OptionGroupVariable.h65
-rw-r--r--include/lldb/Interpreter/OptionGroupWatchpoint.h71
-rw-r--r--include/lldb/Interpreter/OptionValue.h384
-rw-r--r--include/lldb/Interpreter/OptionValueArch.h139
-rw-r--r--include/lldb/Interpreter/OptionValueArgs.h46
-rw-r--r--include/lldb/Interpreter/OptionValueArray.h178
-rw-r--r--include/lldb/Interpreter/OptionValueBoolean.h141
-rw-r--r--include/lldb/Interpreter/OptionValueDictionary.h139
-rw-r--r--include/lldb/Interpreter/OptionValueEnumeration.h126
-rw-r--r--include/lldb/Interpreter/OptionValueFileSpec.h129
-rw-r--r--include/lldb/Interpreter/OptionValueFileSpecList.h105
-rw-r--r--include/lldb/Interpreter/OptionValueFormat.h107
-rw-r--r--include/lldb/Interpreter/OptionValuePathMappings.h94
-rw-r--r--include/lldb/Interpreter/OptionValueProperties.h265
-rw-r--r--include/lldb/Interpreter/OptionValueRegex.h98
-rw-r--r--include/lldb/Interpreter/OptionValueSInt64.h172
-rw-r--r--include/lldb/Interpreter/OptionValueString.h227
-rw-r--r--include/lldb/Interpreter/OptionValueUInt64.h134
-rw-r--r--include/lldb/Interpreter/OptionValueUUID.h106
-rw-r--r--include/lldb/Interpreter/OptionValues.h31
-rw-r--r--include/lldb/Interpreter/Options.h487
-rw-r--r--include/lldb/Interpreter/Property.h109
-rw-r--r--include/lldb/Interpreter/PythonDataObjects.h233
-rw-r--r--include/lldb/Interpreter/ScriptInterpreter.h519
-rw-r--r--include/lldb/Interpreter/ScriptInterpreterNone.h35
-rw-r--r--include/lldb/Interpreter/ScriptInterpreterPython.h407
-rw-r--r--include/lldb/Symbol/Block.h496
-rw-r--r--include/lldb/Symbol/ClangASTContext.h441
-rw-r--r--include/lldb/Symbol/ClangASTImporter.h371
-rw-r--r--include/lldb/Symbol/ClangASTType.h679
-rw-r--r--include/lldb/Symbol/ClangExternalASTSourceCallbacks.h171
-rw-r--r--include/lldb/Symbol/ClangExternalASTSourceCommon.h188
-rw-r--r--include/lldb/Symbol/ClangNamespaceDecl.h103
-rw-r--r--include/lldb/Symbol/CompileUnit.h422
-rw-r--r--include/lldb/Symbol/DWARFCallFrameInfo.h150
-rw-r--r--include/lldb/Symbol/Declaration.h278
-rw-r--r--include/lldb/Symbol/FuncUnwinders.h106
-rw-r--r--include/lldb/Symbol/Function.h638
-rw-r--r--include/lldb/Symbol/LineEntry.h174
-rw-r--r--include/lldb/Symbol/LineTable.h422
-rw-r--r--include/lldb/Symbol/ObjectContainer.h236
-rw-r--r--include/lldb/Symbol/ObjectFile.h706
-rw-r--r--include/lldb/Symbol/Symbol.h317
-rw-r--r--include/lldb/Symbol/SymbolContext.h566
-rw-r--r--include/lldb/Symbol/SymbolContextScope.h137
-rw-r--r--include/lldb/Symbol/SymbolFile.h167
-rw-r--r--include/lldb/Symbol/SymbolVendor.h207
-rw-r--r--include/lldb/Symbol/Symtab.h160
-rw-r--r--include/lldb/Symbol/TaggedASTType.h61
-rw-r--r--include/lldb/Symbol/Type.h596
-rw-r--r--include/lldb/Symbol/TypeList.h88
-rw-r--r--include/lldb/Symbol/TypeVendor.h61
-rw-r--r--include/lldb/Symbol/UnwindPlan.h499
-rw-r--r--include/lldb/Symbol/UnwindTable.h69
-rw-r--r--include/lldb/Symbol/Variable.h184
-rw-r--r--include/lldb/Symbol/VariableList.h95
-rw-r--r--include/lldb/Symbol/VerifyDecl.h20
-rw-r--r--include/lldb/Target/ABI.h137
-rw-r--r--include/lldb/Target/CPPLanguageRuntime.h158
-rw-r--r--include/lldb/Target/DynamicLoader.h239
-rw-r--r--include/lldb/Target/ExecutionContext.h778
-rw-r--r--include/lldb/Target/ExecutionContextScope.h74
-rw-r--r--include/lldb/Target/LanguageRuntime.h113
-rw-r--r--include/lldb/Target/Memory.h196
-rw-r--r--include/lldb/Target/ObjCLanguageRuntime.h604
-rw-r--r--include/lldb/Target/OperatingSystem.h101
-rw-r--r--include/lldb/Target/PathMappingList.h171
-rw-r--r--include/lldb/Target/Platform.h755
-rw-r--r--include/lldb/Target/Process.h3786
-rw-r--r--include/lldb/Target/RegisterContext.h213
-rw-r--r--include/lldb/Target/SectionLoadList.h89
-rw-r--r--include/lldb/Target/StackFrame.h207
-rw-r--r--include/lldb/Target/StackFrameList.h157
-rw-r--r--include/lldb/Target/StackID.h149
-rw-r--r--include/lldb/Target/StopInfo.h227
-rw-r--r--include/lldb/Target/Target.h1223
-rw-r--r--include/lldb/Target/TargetList.h239
-rw-r--r--include/lldb/Target/Thread.h1067
-rw-r--r--include/lldb/Target/ThreadList.h163
-rw-r--r--include/lldb/Target/ThreadPlan.h658
-rw-r--r--include/lldb/Target/ThreadPlanBase.h71
-rw-r--r--include/lldb/Target/ThreadPlanCallFunction.h193
-rw-r--r--include/lldb/Target/ThreadPlanCallUserExpression.h65
-rw-r--r--include/lldb/Target/ThreadPlanRunToAddress.h85
-rw-r--r--include/lldb/Target/ThreadPlanShouldStopHere.h94
-rw-r--r--include/lldb/Target/ThreadPlanStepInRange.h110
-rw-r--r--include/lldb/Target/ThreadPlanStepInstruction.h64
-rw-r--r--include/lldb/Target/ThreadPlanStepOut.h90
-rw-r--r--include/lldb/Target/ThreadPlanStepOverBreakpoint.h57
-rw-r--r--include/lldb/Target/ThreadPlanStepOverRange.h52
-rw-r--r--include/lldb/Target/ThreadPlanStepRange.h94
-rw-r--r--include/lldb/Target/ThreadPlanStepThrough.h71
-rw-r--r--include/lldb/Target/ThreadPlanStepUntil.h80
-rw-r--r--include/lldb/Target/ThreadPlanTracer.h131
-rw-r--r--include/lldb/Target/ThreadSpec.h155
-rw-r--r--include/lldb/Target/UnixSignals.h144
-rw-r--r--include/lldb/Target/Unwind.h120
-rw-r--r--include/lldb/Target/UnwindAssembly.h58
-rw-r--r--include/lldb/Utility/AnsiTerminal.h156
-rw-r--r--include/lldb/Utility/CleanUp.h322
-rw-r--r--include/lldb/Utility/PriorityPointerPair.h150
-rw-r--r--include/lldb/Utility/PseudoTerminal.h266
-rw-r--r--include/lldb/Utility/PythonPointer.h77
-rw-r--r--include/lldb/Utility/Range.h89
-rw-r--r--include/lldb/Utility/RefCounter.h56
-rw-r--r--include/lldb/Utility/SharedCluster.h108
-rw-r--r--include/lldb/Utility/SharingPtr.h816
-rw-r--r--include/lldb/Utility/Utils.h22
-rw-r--r--include/lldb/lldb-defines.h125
-rw-r--r--include/lldb/lldb-enumerations.h685
-rw-r--r--include/lldb/lldb-forward.h378
-rw-r--r--include/lldb/lldb-private-enumerations.h245
-rw-r--r--include/lldb/lldb-private-interfaces.h46
-rw-r--r--include/lldb/lldb-private-log.h90
-rw-r--r--include/lldb/lldb-private-types.h74
-rw-r--r--include/lldb/lldb-private.h84
-rw-r--r--include/lldb/lldb-public.h18
-rw-r--r--include/lldb/lldb-python.h29
-rw-r--r--include/lldb/lldb-types.h83
-rw-r--r--include/lldb/lldb-versioning.h1607
339 files changed, 83266 insertions, 0 deletions
diff --git a/include/lldb/API/LLDB.h b/include/lldb/API/LLDB.h
new file mode 100644
index 000000000000..93bc3bc121e2
--- /dev/null
+++ b/include/lldb/API/LLDB.h
@@ -0,0 +1,54 @@
+//===-- LLDB.h --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_LLDB_h_
+#define LLDB_LLDB_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBAddress.h"
+#include "lldb/API/SBBlock.h"
+#include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBBroadcaster.h"
+#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBCommandReturnObject.h"
+#include "lldb/API/SBCommunication.h"
+#include "lldb/API/SBCompileUnit.h"
+#include "lldb/API/SBData.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBDeclaration.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBFrame.h"
+#include "lldb/API/SBFunction.h"
+#include "lldb/API/SBHostOS.h"
+#include "lldb/API/SBInputReader.h"
+#include "lldb/API/SBInstruction.h"
+#include "lldb/API/SBInstructionList.h"
+#include "lldb/API/SBLineEntry.h"
+#include "lldb/API/SBListener.h"
+#include "lldb/API/SBModule.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBSourceManager.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
+#include "lldb/API/SBSymbol.h"
+#include "lldb/API/SBSymbolContext.h"
+#include "lldb/API/SBTarget.h"
+#include "lldb/API/SBThread.h"
+#include "lldb/API/SBType.h"
+#include "lldb/API/SBValue.h"
+#include "lldb/API/SBValueList.h"
+
+#endif // LLDB_LLDB_h_
diff --git a/include/lldb/API/SBAddress.h b/include/lldb/API/SBAddress.h
new file mode 100644
index 000000000000..c5e8cc685a4c
--- /dev/null
+++ b/include/lldb/API/SBAddress.h
@@ -0,0 +1,150 @@
+//===-- SBAddress.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBAddress_h_
+#define LLDB_SBAddress_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBModule.h"
+
+namespace lldb {
+
+class SBAddress
+{
+public:
+
+ SBAddress ();
+
+ SBAddress (const lldb::SBAddress &rhs);
+
+ SBAddress (lldb::SBSection section, lldb::addr_t offset);
+
+ // Create an address by resolving a load address using the supplied target
+ SBAddress (lldb::addr_t load_addr, lldb::SBTarget &target);
+
+ ~SBAddress ();
+
+ const lldb::SBAddress &
+ operator = (const lldb::SBAddress &rhs);
+
+ bool
+ IsValid () const;
+
+ void
+ Clear ();
+
+ addr_t
+ GetFileAddress () const;
+
+ addr_t
+ GetLoadAddress (const lldb::SBTarget &target) const;
+
+ void
+ SetAddress (lldb::SBSection section, lldb::addr_t offset);
+
+ void
+ SetLoadAddress (lldb::addr_t load_addr,
+ lldb::SBTarget &target);
+ bool
+ OffsetAddress (addr_t offset);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ // The following queries can lookup symbol information for a given address.
+ // An address might refer to code or data from an existing module, or it
+ // might refer to something on the stack or heap. The following functions
+ // will only return valid values if the address has been resolved to a code
+ // or data address using "void SBAddress::SetLoadAddress(...)" or
+ // "lldb::SBAddress SBTarget::ResolveLoadAddress (...)".
+ lldb::SBSymbolContext
+ GetSymbolContext (uint32_t resolve_scope);
+
+
+ // The following functions grab individual objects for a given address and
+ // are less efficient if you want more than one symbol related objects.
+ // Use one of the following when you want multiple debug symbol related
+ // objects for an address:
+ // lldb::SBSymbolContext SBAddress::GetSymbolContext (uint32_t resolve_scope);
+ // lldb::SBSymbolContext SBTarget::ResolveSymbolContextForAddress (const SBAddress &addr, uint32_t resolve_scope);
+ // One or more bits from the SymbolContextItem enumerations can be logically
+ // OR'ed together to more efficiently retrieve multiple symbol objects.
+
+ lldb::SBSection
+ GetSection ();
+
+ lldb::addr_t
+ GetOffset ();
+
+ lldb::SBModule
+ GetModule ();
+
+ lldb::SBCompileUnit
+ GetCompileUnit ();
+
+ lldb::SBFunction
+ GetFunction ();
+
+ lldb::SBBlock
+ GetBlock ();
+
+ lldb::SBSymbol
+ GetSymbol ();
+
+ lldb::SBLineEntry
+ GetLineEntry ();
+
+ lldb::AddressClass
+ GetAddressClass ();
+
+protected:
+
+ friend class SBBlock;
+ friend class SBBreakpointLocation;
+ friend class SBFrame;
+ friend class SBFunction;
+ friend class SBLineEntry;
+ friend class SBInstruction;
+ friend class SBModule;
+ friend class SBSection;
+ friend class SBSymbol;
+ friend class SBSymbolContext;
+ friend class SBTarget;
+ friend class SBThread;
+ friend class SBValue;
+
+ lldb_private::Address *
+ operator->();
+
+ const lldb_private::Address *
+ operator->() const;
+
+ lldb_private::Address *
+ get ();
+
+ lldb_private::Address &
+ ref();
+
+ const lldb_private::Address &
+ ref() const;
+
+ SBAddress (const lldb_private::Address *lldb_object_ptr);
+
+ void
+ SetAddress (const lldb_private::Address *lldb_object_ptr);
+
+private:
+
+ std::unique_ptr<lldb_private::Address> m_opaque_ap;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBAddress_h_
diff --git a/include/lldb/API/SBBlock.h b/include/lldb/API/SBBlock.h
new file mode 100644
index 000000000000..b8e61fc6eb27
--- /dev/null
+++ b/include/lldb/API/SBBlock.h
@@ -0,0 +1,123 @@
+//===-- SBBlock.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBBlock_h_
+#define LLDB_SBBlock_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBFrame.h"
+#include "lldb/API/SBTarget.h"
+#include "lldb/API/SBValueList.h"
+
+namespace lldb {
+
+class SBBlock
+{
+public:
+
+ SBBlock ();
+
+ SBBlock (const lldb::SBBlock &rhs);
+
+ ~SBBlock ();
+
+ const lldb::SBBlock &
+ operator = (const lldb::SBBlock &rhs);
+
+ bool
+ IsInlined () const;
+
+ bool
+ IsValid () const;
+
+ const char *
+ GetInlinedName () const;
+
+ lldb::SBFileSpec
+ GetInlinedCallSiteFile () const;
+
+ uint32_t
+ GetInlinedCallSiteLine () const;
+
+ uint32_t
+ GetInlinedCallSiteColumn () const;
+
+ lldb::SBBlock
+ GetParent ();
+
+ lldb::SBBlock
+ GetSibling ();
+
+ lldb::SBBlock
+ GetFirstChild ();
+
+ uint32_t
+ GetNumRanges ();
+
+ lldb::SBAddress
+ GetRangeStartAddress (uint32_t idx);
+
+ lldb::SBAddress
+ GetRangeEndAddress (uint32_t idx);
+
+ uint32_t
+ GetRangeIndexForBlockAddress (lldb::SBAddress block_addr);
+
+ lldb::SBValueList
+ GetVariables (lldb::SBFrame& frame,
+ bool arguments,
+ bool locals,
+ bool statics,
+ lldb::DynamicValueType use_dynamic);
+
+ lldb::SBValueList
+ GetVariables (lldb::SBTarget& target,
+ bool arguments,
+ bool locals,
+ bool statics);
+ //------------------------------------------------------------------
+ /// Get the inlined block that contains this block.
+ ///
+ /// @return
+ /// If this block is inlined, it will return this block, else
+ /// parent blocks will be searched to see if any contain this
+ /// block and are themselves inlined. An invalid SBBlock will
+ /// be returned if this block nor any parent blocks are inlined
+ /// function blocks.
+ //------------------------------------------------------------------
+ lldb::SBBlock
+ GetContainingInlinedBlock ();
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+private:
+ friend class SBAddress;
+ friend class SBFrame;
+ friend class SBFunction;
+ friend class SBSymbolContext;
+
+ lldb_private::Block *
+ GetPtr ();
+
+ void
+ SetPtr (lldb_private::Block *lldb_object_ptr);
+
+ SBBlock (lldb_private::Block *lldb_object_ptr);
+
+ void
+ AppendVariables (bool can_create, bool get_parent_variables, lldb_private::VariableList *var_list);
+
+ lldb_private::Block *m_opaque_ptr;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBBlock_h_
diff --git a/include/lldb/API/SBBreakpoint.h b/include/lldb/API/SBBreakpoint.h
new file mode 100644
index 000000000000..be9c499798e1
--- /dev/null
+++ b/include/lldb/API/SBBreakpoint.h
@@ -0,0 +1,175 @@
+//===-- SBBreakpoint.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBBreakpoint_h_
+#define LLDB_SBBreakpoint_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBBreakpoint
+{
+public:
+
+ typedef bool (*BreakpointHitCallback) (void *baton,
+ SBProcess &process,
+ SBThread &thread,
+ lldb::SBBreakpointLocation &location);
+
+ SBBreakpoint ();
+
+ SBBreakpoint (const lldb::SBBreakpoint& rhs);
+
+ ~SBBreakpoint();
+
+ const lldb::SBBreakpoint &
+ operator = (const lldb::SBBreakpoint& rhs);
+
+ // Tests to see if the opaque breakpoint object in this object matches the
+ // opaque breakpoint object in "rhs".
+ bool
+ operator == (const lldb::SBBreakpoint& rhs);
+
+ bool
+ operator != (const lldb::SBBreakpoint& rhs);
+
+ break_id_t
+ GetID () const;
+
+ bool
+ IsValid() const;
+
+ void
+ ClearAllBreakpointSites ();
+
+ lldb::SBBreakpointLocation
+ FindLocationByAddress (lldb::addr_t vm_addr);
+
+ lldb::break_id_t
+ FindLocationIDByAddress (lldb::addr_t vm_addr);
+
+ lldb::SBBreakpointLocation
+ FindLocationByID (lldb::break_id_t bp_loc_id);
+
+ lldb::SBBreakpointLocation
+ GetLocationAtIndex (uint32_t index);
+
+ void
+ SetEnabled (bool enable);
+
+ bool
+ IsEnabled ();
+
+ void
+ SetOneShot (bool one_shot);
+
+ bool
+ IsOneShot () const;
+
+ bool
+ IsInternal ();
+
+ uint32_t
+ GetHitCount () const;
+
+ void
+ SetIgnoreCount (uint32_t count);
+
+ uint32_t
+ GetIgnoreCount () const;
+
+ void
+ SetCondition (const char *condition);
+
+ const char *
+ GetCondition ();
+
+ void
+ SetThreadID (lldb::tid_t sb_thread_id);
+
+ lldb::tid_t
+ GetThreadID ();
+
+ void
+ SetThreadIndex (uint32_t index);
+
+ uint32_t
+ GetThreadIndex() const;
+
+ void
+ SetThreadName (const char *thread_name);
+
+ const char *
+ GetThreadName () const;
+
+ void
+ SetQueueName (const char *queue_name);
+
+ const char *
+ GetQueueName () const;
+
+ void
+ SetCallback (BreakpointHitCallback callback, void *baton);
+
+ size_t
+ GetNumResolvedLocations() const;
+
+ size_t
+ GetNumLocations() const;
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ static bool
+ EventIsBreakpointEvent (const lldb::SBEvent &event);
+
+ static lldb::BreakpointEventType
+ GetBreakpointEventTypeFromEvent (const lldb::SBEvent& event);
+
+ static lldb::SBBreakpoint
+ GetBreakpointFromEvent (const lldb::SBEvent& event);
+
+ static lldb::SBBreakpointLocation
+ GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx);
+
+ static uint32_t
+ GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event_sp);
+
+
+private:
+ friend class SBBreakpointLocation;
+ friend class SBTarget;
+
+ SBBreakpoint (const lldb::BreakpointSP &bp_sp);
+
+ lldb_private::Breakpoint *
+ operator->() const;
+
+ lldb_private::Breakpoint *
+ get() const;
+
+ lldb::BreakpointSP &
+ operator *();
+
+ const lldb::BreakpointSP &
+ operator *() const;
+
+ static bool
+ PrivateBreakpointHitCallback (void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ lldb::BreakpointSP m_opaque_sp;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBBreakpoint_h_
diff --git a/include/lldb/API/SBBreakpointLocation.h b/include/lldb/API/SBBreakpointLocation.h
new file mode 100644
index 000000000000..3b2ca2cf88e8
--- /dev/null
+++ b/include/lldb/API/SBBreakpointLocation.h
@@ -0,0 +1,110 @@
+//===-- SBBreakpointLocation.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBBreakpointLocation_h_
+#define LLDB_SBBreakpointLocation_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBBreakpoint.h"
+
+namespace lldb {
+
+class SBBreakpointLocation
+{
+public:
+
+ SBBreakpointLocation ();
+
+ SBBreakpointLocation (const lldb::SBBreakpointLocation &rhs);
+
+ ~SBBreakpointLocation ();
+
+ const lldb::SBBreakpointLocation &
+ operator = (const lldb::SBBreakpointLocation &rhs);
+
+ break_id_t
+ GetID ();
+
+ bool
+ IsValid() const;
+
+ lldb::SBAddress
+ GetAddress ();
+
+ lldb::addr_t
+ GetLoadAddress ();
+
+ void
+ SetEnabled(bool enabled);
+
+ bool
+ IsEnabled ();
+
+ uint32_t
+ GetIgnoreCount ();
+
+ void
+ SetIgnoreCount (uint32_t n);
+
+ void
+ SetCondition (const char *condition);
+
+ const char *
+ GetCondition ();
+
+ void
+ SetThreadID (lldb::tid_t sb_thread_id);
+
+ lldb::tid_t
+ GetThreadID ();
+
+ void
+ SetThreadIndex (uint32_t index);
+
+ uint32_t
+ GetThreadIndex() const;
+
+ void
+ SetThreadName (const char *thread_name);
+
+ const char *
+ GetThreadName () const;
+
+ void
+ SetQueueName (const char *queue_name);
+
+ const char *
+ GetQueueName () const;
+
+ bool
+ IsResolved ();
+
+ bool
+ GetDescription (lldb::SBStream &description, DescriptionLevel level);
+
+ SBBreakpoint
+ GetBreakpoint ();
+
+ SBBreakpointLocation (const lldb::BreakpointLocationSP &break_loc_sp);
+
+private:
+ friend class SBBreakpoint;
+#ifndef LLDB_DISABLE_PYTHON
+ friend class lldb_private::ScriptInterpreterPython;
+#endif
+ void
+ SetLocation (const lldb::BreakpointLocationSP &break_loc_sp);
+
+ lldb::BreakpointLocationSP m_opaque_sp;
+
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBBreakpointLocation_h_
diff --git a/include/lldb/API/SBBroadcaster.h b/include/lldb/API/SBBroadcaster.h
new file mode 100644
index 000000000000..7b32d85faa0f
--- /dev/null
+++ b/include/lldb/API/SBBroadcaster.h
@@ -0,0 +1,97 @@
+//===-- SBBroadcaster.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBBroadcaster_h_
+#define LLDB_SBBroadcaster_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBBroadcaster
+{
+public:
+ SBBroadcaster ();
+
+ SBBroadcaster (const char *name);
+
+ SBBroadcaster (const SBBroadcaster &rhs);
+
+ const SBBroadcaster &
+ operator = (const SBBroadcaster &rhs);
+
+ ~SBBroadcaster();
+
+ bool
+ IsValid () const;
+
+ void
+ Clear ();
+
+ void
+ BroadcastEventByType (uint32_t event_type, bool unique = false);
+
+ void
+ BroadcastEvent (const lldb::SBEvent &event, bool unique = false);
+
+ void
+ AddInitialEventsToListener (const lldb::SBListener &listener, uint32_t requested_events);
+
+ uint32_t
+ AddListener (const lldb::SBListener &listener, uint32_t event_mask);
+
+ const char *
+ GetName () const;
+
+ bool
+ EventTypeHasListeners (uint32_t event_type);
+
+ bool
+ RemoveListener (const lldb::SBListener &listener, uint32_t event_mask = UINT32_MAX);
+
+ // This comparison is checking if the internal opaque pointer value
+ // is equal to that in "rhs".
+ bool
+ operator == (const lldb::SBBroadcaster &rhs) const;
+
+ // This comparison is checking if the internal opaque pointer value
+ // is not equal to that in "rhs".
+ bool
+ operator != (const lldb::SBBroadcaster &rhs) const;
+
+ // This comparison is checking if the internal opaque pointer value
+ // is less than that in "rhs" so SBBroadcaster objects can be contained
+ // in ordered containers.
+ bool
+ operator < (const lldb::SBBroadcaster &rhs) const;
+
+protected:
+ friend class SBCommandInterpreter;
+ friend class SBCommunication;
+ friend class SBEvent;
+ friend class SBListener;
+ friend class SBProcess;
+ friend class SBTarget;
+
+ SBBroadcaster (lldb_private::Broadcaster *broadcaster, bool owns);
+
+ lldb_private::Broadcaster *
+ get () const;
+
+ void
+ reset (lldb_private::Broadcaster *broadcaster, bool owns);
+
+private:
+ lldb::BroadcasterSP m_opaque_sp;
+ lldb_private::Broadcaster *m_opaque_ptr;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBBroadcaster_h_
diff --git a/include/lldb/API/SBCommandInterpreter.h b/include/lldb/API/SBCommandInterpreter.h
new file mode 100644
index 000000000000..9b2583cd85ca
--- /dev/null
+++ b/include/lldb/API/SBCommandInterpreter.h
@@ -0,0 +1,193 @@
+//===-- SBCommandInterpreter.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBCommandInterpreter_h_
+#define LLDB_SBCommandInterpreter_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBDebugger.h"
+
+namespace lldb {
+
+class SBCommandInterpreter
+{
+public:
+ enum
+ {
+ eBroadcastBitThreadShouldExit = (1 << 0),
+ eBroadcastBitResetPrompt = (1 << 1),
+ eBroadcastBitQuitCommandReceived = (1 << 2), // User entered quit
+ eBroadcastBitAsynchronousOutputData = (1 << 3),
+ eBroadcastBitAsynchronousErrorData = (1 << 4)
+ };
+
+ SBCommandInterpreter (const lldb::SBCommandInterpreter &rhs);
+
+ const lldb::SBCommandInterpreter &
+ operator = (const lldb::SBCommandInterpreter &rhs);
+
+ ~SBCommandInterpreter ();
+
+ static const char *
+ GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type);
+
+ static const char *
+ GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type);
+
+ bool
+ IsValid() const;
+
+ bool
+ CommandExists (const char *cmd);
+
+ bool
+ AliasExists (const char *cmd);
+
+ lldb::SBBroadcaster
+ GetBroadcaster ();
+
+ static const char *
+ GetBroadcasterClass ();
+
+ bool
+ HasCommands ();
+
+ bool
+ HasAliases ();
+
+ bool
+ HasAliasOptions ();
+
+ lldb::SBProcess
+ GetProcess ();
+
+ lldb::SBDebugger
+ GetDebugger ();
+
+ lldb::SBCommand
+ AddMultiwordCommand (const char* name, const char* help);
+
+ lldb::SBCommand
+ AddCommand (const char* name, lldb::SBCommandPluginInterface *impl, const char* help);
+
+ void
+ SourceInitFileInHomeDirectory (lldb::SBCommandReturnObject &result);
+
+ void
+ SourceInitFileInCurrentWorkingDirectory (lldb::SBCommandReturnObject &result);
+
+ lldb::ReturnStatus
+ HandleCommand (const char *command_line, lldb::SBCommandReturnObject &result, bool add_to_history = false);
+
+ // The pointer based interface is not useful in SWIG, since the cursor & last_char arguments are string pointers INTO current_line
+ // and you can't do that in a scripting language interface in general...
+
+ // In either case, the way this works is that the you give it a line and cursor position in the line. The function
+ // will return the number of completions. The matches list will contain number_of_completions + 1 elements. The first
+ // element is the common substring after the cursor position for all the matches. The rest of the elements are the
+ // matches. The first element is useful if you are emulating the common shell behavior where the tab completes
+ // to the string that is common among all the matches, then you should first check if the first element is non-empty,
+ // and if so just insert it and move the cursor to the end of the insertion. The next tab will return an empty
+ // common substring, and a list of choices (if any), at which point you should display the choices and let the user
+ // type further to disambiguate.
+
+ int
+ HandleCompletion (const char *current_line,
+ const char *cursor,
+ const char *last_char,
+ int match_start_point,
+ int max_return_elements,
+ lldb::SBStringList &matches);
+
+ int
+ HandleCompletion (const char *current_line,
+ uint32_t cursor_pos,
+ int match_start_point,
+ int max_return_elements,
+ lldb::SBStringList &matches);
+
+ // Catch commands before they execute by registering a callback that will
+ // get called when the command gets executed. This allows GUI or command
+ // line interfaces to intercept a command and stop it from happening
+ bool
+ SetCommandOverrideCallback (const char *command_name,
+ lldb::CommandOverrideCallback callback,
+ void *baton);
+
+ SBCommandInterpreter (lldb_private::CommandInterpreter *interpreter_ptr = NULL); // Access using SBDebugger::GetCommandInterpreter();
+
+protected:
+
+ lldb_private::CommandInterpreter &
+ ref ();
+
+ lldb_private::CommandInterpreter *
+ get ();
+
+ void
+ reset (lldb_private::CommandInterpreter *);
+private:
+ friend class SBDebugger;
+
+ static void
+ InitializeSWIG ();
+
+ lldb_private::CommandInterpreter *m_opaque_ptr;
+};
+
+class SBCommandPluginInterface
+{
+public:
+ virtual bool
+ DoExecute (lldb::SBDebugger debugger,
+ char** command,
+ lldb::SBCommandReturnObject &result)
+ {
+ return false;
+ }
+
+ virtual
+ ~SBCommandPluginInterface ()
+ {}
+};
+
+class SBCommand
+{
+public:
+
+ SBCommand ();
+
+ bool
+ IsValid ();
+
+ const char*
+ GetName ();
+
+ const char*
+ GetHelp ();
+
+ lldb::SBCommand
+ AddMultiwordCommand (const char* name, const char* help = NULL);
+
+ lldb::SBCommand
+ AddCommand (const char* name, lldb::SBCommandPluginInterface* impl, const char* help = NULL);
+
+private:
+
+ friend class SBDebugger;
+ friend class SBCommandInterpreter;
+
+ SBCommand (lldb::CommandObjectSP cmd_sp);
+
+ lldb::CommandObjectSP m_opaque_sp;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBCommandInterpreter_h_
diff --git a/include/lldb/API/SBCommandReturnObject.h b/include/lldb/API/SBCommandReturnObject.h
new file mode 100644
index 000000000000..f2d274802330
--- /dev/null
+++ b/include/lldb/API/SBCommandReturnObject.h
@@ -0,0 +1,133 @@
+//===-- SBCommandReturnObject.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBCommandReturnObject_h_
+#define LLDB_SBCommandReturnObject_h_
+
+#include <stdio.h>
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBCommandReturnObject
+{
+public:
+
+ SBCommandReturnObject ();
+
+ SBCommandReturnObject (const lldb::SBCommandReturnObject &rhs);
+
+ const lldb::SBCommandReturnObject &
+ operator = (const lldb::SBCommandReturnObject &rhs);
+
+
+ SBCommandReturnObject (lldb_private::CommandReturnObject *ptr);
+
+ lldb_private::CommandReturnObject *
+ Release ();
+
+ ~SBCommandReturnObject ();
+
+ bool
+ IsValid() const;
+
+ const char *
+ GetOutput ();
+
+ const char *
+ GetError ();
+
+ size_t
+ PutOutput (FILE *fh);
+
+ size_t
+ GetOutputSize ();
+
+ size_t
+ GetErrorSize ();
+
+ size_t
+ PutError (FILE *fh);
+
+ void
+ Clear();
+
+ lldb::ReturnStatus
+ GetStatus();
+
+ void
+ SetStatus (lldb::ReturnStatus status);
+
+ bool
+ Succeeded ();
+
+ bool
+ HasResult ();
+
+ void
+ AppendMessage (const char *message);
+
+ void
+ AppendWarning (const char *message);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ void
+ SetImmediateOutputFile (FILE *fh);
+
+ void
+ SetImmediateErrorFile (FILE *fh);
+
+ void
+ PutCString(const char* string, int len = -1);
+
+ size_t
+ Printf(const char* format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ const char *
+ GetOutput (bool only_if_no_immediate);
+
+ const char *
+ GetError (bool only_if_no_immediate);
+
+ void
+ SetError (lldb::SBError &error,
+ const char *fallback_error_cstr = NULL);
+
+ void
+ SetError (const char* error_cstr);
+
+protected:
+ friend class SBCommandInterpreter;
+ friend class SBOptions;
+
+ lldb_private::CommandReturnObject *
+ operator->() const;
+
+ lldb_private::CommandReturnObject *
+ get() const;
+
+ lldb_private::CommandReturnObject &
+ operator*() const;
+
+ lldb_private::CommandReturnObject &
+ ref() const;
+
+ void
+ SetLLDBObjectPtr (lldb_private::CommandReturnObject *ptr);
+
+ private:
+ std::unique_ptr<lldb_private::CommandReturnObject> m_opaque_ap;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBCommandReturnObject_h_
diff --git a/include/lldb/API/SBCommunication.h b/include/lldb/API/SBCommunication.h
new file mode 100644
index 000000000000..ecaaa3523c91
--- /dev/null
+++ b/include/lldb/API/SBCommunication.h
@@ -0,0 +1,99 @@
+//===-- SBCommunication.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBCommunication_h_
+#define LLDB_SBCommunication_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBError.h"
+
+namespace lldb {
+
+class SBCommunication
+{
+public:
+ enum {
+ eBroadcastBitDisconnected = (1 << 0), ///< Sent when the communications connection is lost.
+ eBroadcastBitReadThreadGotBytes = (1 << 1), ///< Sent by the read thread when bytes become available.
+ eBroadcastBitReadThreadDidExit = (1 << 2), ///< Sent by the read thread when it exits to inform clients.
+ eBroadcastBitReadThreadShouldExit = (1 << 3), ///< Sent by clients that need to cancel the read thread.
+ eBroadcastBitPacketAvailable = (1 << 4), ///< Sent when data received makes a complete packet.
+ eAllEventBits = 0xffffffff
+ };
+
+ typedef void (*ReadThreadBytesReceived) (void *baton, const void *src, size_t src_len);
+
+ SBCommunication ();
+ SBCommunication (const char * broadcaster_name);
+ ~SBCommunication ();
+
+
+ bool
+ IsValid () const;
+
+ lldb::SBBroadcaster
+ GetBroadcaster ();
+
+ static const char *GetBroadcasterClass();
+
+ lldb::ConnectionStatus
+ AdoptFileDesriptor (int fd, bool owns_fd);
+
+ lldb::ConnectionStatus
+ Connect (const char *url);
+
+ lldb::ConnectionStatus
+ Disconnect ();
+
+ bool
+ IsConnected () const;
+
+ bool
+ GetCloseOnEOF ();
+
+ void
+ SetCloseOnEOF (bool b);
+
+ size_t
+ Read (void *dst,
+ size_t dst_len,
+ uint32_t timeout_usec,
+ lldb::ConnectionStatus &status);
+
+ size_t
+ Write (const void *src,
+ size_t src_len,
+ lldb::ConnectionStatus &status);
+
+ bool
+ ReadThreadStart ();
+
+ bool
+ ReadThreadStop ();
+
+ bool
+ ReadThreadIsRunning ();
+
+ bool
+ SetReadThreadBytesReceivedCallback (ReadThreadBytesReceived callback,
+ void *callback_baton);
+
+
+private:
+
+ DISALLOW_COPY_AND_ASSIGN (SBCommunication);
+
+ lldb_private::Communication *m_opaque;
+ bool m_opaque_owned;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBCommunication_h_
diff --git a/include/lldb/API/SBCompileUnit.h b/include/lldb/API/SBCompileUnit.h
new file mode 100644
index 000000000000..95af3d4722ce
--- /dev/null
+++ b/include/lldb/API/SBCompileUnit.h
@@ -0,0 +1,116 @@
+//===-- SBCompileUnit.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBCompileUnit_h_
+#define LLDB_SBCompileUnit_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBFileSpec.h"
+
+namespace lldb {
+
+class SBCompileUnit
+{
+public:
+
+ SBCompileUnit ();
+
+ SBCompileUnit (const lldb::SBCompileUnit &rhs);
+
+ ~SBCompileUnit ();
+
+ const lldb::SBCompileUnit &
+ operator = (const lldb::SBCompileUnit &rhs);
+
+ bool
+ IsValid () const;
+
+ lldb::SBFileSpec
+ GetFileSpec () const;
+
+ uint32_t
+ GetNumLineEntries () const;
+
+ lldb::SBLineEntry
+ GetLineEntryAtIndex (uint32_t idx) const;
+
+ uint32_t
+ FindLineEntryIndex (uint32_t start_idx,
+ uint32_t line,
+ lldb::SBFileSpec *inline_file_spec) const;
+
+ uint32_t
+ FindLineEntryIndex (uint32_t start_idx,
+ uint32_t line,
+ lldb::SBFileSpec *inline_file_spec,
+ bool exact) const;
+
+ SBFileSpec
+ GetSupportFileAtIndex (uint32_t idx) const;
+
+ uint32_t
+ GetNumSupportFiles () const;
+
+ uint32_t
+ FindSupportFileIndex (uint32_t start_idx, const SBFileSpec &sb_file, bool full);
+
+ //------------------------------------------------------------------
+ /// Get all types matching \a type_mask from debug info in this
+ /// compile unit.
+ ///
+ /// @param[in] type_mask
+ /// A bitfield that consists of one or more bits logically OR'ed
+ /// together from the lldb::TypeClass enumeration. This allows
+ /// you to request only structure types, or only class, struct
+ /// and union types. Passing in lldb::eTypeClassAny will return
+ /// all types found in the debug information for this compile
+ /// unit.
+ ///
+ /// @return
+ /// A list of types in this compile unit that match \a type_mask
+ //------------------------------------------------------------------
+ lldb::SBTypeList
+ GetTypes (uint32_t type_mask = lldb::eTypeClassAny);
+
+ bool
+ operator == (const lldb::SBCompileUnit &rhs) const;
+
+ bool
+ operator != (const lldb::SBCompileUnit &rhs) const;
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+private:
+ friend class SBAddress;
+ friend class SBFrame;
+ friend class SBSymbolContext;
+ friend class SBModule;
+
+ SBCompileUnit (lldb_private::CompileUnit *lldb_object_ptr);
+
+ const lldb_private::CompileUnit *
+ operator->() const;
+
+ const lldb_private::CompileUnit &
+ operator*() const;
+
+ lldb_private::CompileUnit *
+ get ();
+
+ void
+ reset (lldb_private::CompileUnit *lldb_object_ptr);
+
+ lldb_private::CompileUnit *m_opaque_ptr;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBCompileUnit_h_
diff --git a/include/lldb/API/SBData.h b/include/lldb/API/SBData.h
new file mode 100644
index 000000000000..10c002247271
--- /dev/null
+++ b/include/lldb/API/SBData.h
@@ -0,0 +1,180 @@
+//===-- SBData.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBData_h_
+#define LLDB_SBData_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBData
+{
+public:
+
+ SBData ();
+
+ SBData (const SBData &rhs);
+
+ const SBData &
+ operator = (const SBData &rhs);
+
+ ~SBData ();
+
+ uint8_t
+ GetAddressByteSize ();
+
+ void
+ SetAddressByteSize (uint8_t addr_byte_size);
+
+ void
+ Clear ();
+
+ bool
+ IsValid();
+
+ size_t
+ GetByteSize ();
+
+ lldb::ByteOrder
+ GetByteOrder();
+
+ void
+ SetByteOrder (lldb::ByteOrder endian);
+
+ float
+ GetFloat (lldb::SBError& error, lldb::offset_t offset);
+
+ double
+ GetDouble (lldb::SBError& error, lldb::offset_t offset);
+
+ long double
+ GetLongDouble (lldb::SBError& error, lldb::offset_t offset);
+
+ lldb::addr_t
+ GetAddress (lldb::SBError& error, lldb::offset_t offset);
+
+ uint8_t
+ GetUnsignedInt8 (lldb::SBError& error, lldb::offset_t offset);
+
+ uint16_t
+ GetUnsignedInt16 (lldb::SBError& error, lldb::offset_t offset);
+
+ uint32_t
+ GetUnsignedInt32 (lldb::SBError& error, lldb::offset_t offset);
+
+ uint64_t
+ GetUnsignedInt64 (lldb::SBError& error, lldb::offset_t offset);
+
+ int8_t
+ GetSignedInt8 (lldb::SBError& error, lldb::offset_t offset);
+
+ int16_t
+ GetSignedInt16 (lldb::SBError& error, lldb::offset_t offset);
+
+ int32_t
+ GetSignedInt32 (lldb::SBError& error, lldb::offset_t offset);
+
+ int64_t
+ GetSignedInt64 (lldb::SBError& error, lldb::offset_t offset);
+
+ const char*
+ GetString (lldb::SBError& error, lldb::offset_t offset);
+
+ size_t
+ ReadRawData (lldb::SBError& error,
+ lldb::offset_t offset,
+ void *buf,
+ size_t size);
+
+ bool
+ GetDescription (lldb::SBStream &description, lldb::addr_t base_addr = LLDB_INVALID_ADDRESS);
+
+ // it would be nice to have SetData(SBError, const void*, size_t) when endianness and address size can be
+ // inferred from the existing DataExtractor, but having two SetData() signatures triggers a SWIG bug where
+ // the typemap isn't applied before resolving the overload, and thus the right function never gets called
+ void
+ SetData (lldb::SBError& error, const void *buf, size_t size, lldb::ByteOrder endian, uint8_t addr_size);
+
+ // see SetData() for why we don't have Append(const void* buf, size_t size)
+ bool
+ Append (const SBData& rhs);
+
+ static lldb::SBData
+ CreateDataFromCString (lldb::ByteOrder endian, uint32_t addr_byte_size, const char* data);
+
+ // in the following CreateData*() and SetData*() prototypes, the two parameters array and array_len
+ // should not be renamed or rearranged, because doing so will break the SWIG typemap
+ static lldb::SBData
+ CreateDataFromUInt64Array (lldb::ByteOrder endian, uint32_t addr_byte_size, uint64_t* array, size_t array_len);
+
+ static lldb::SBData
+ CreateDataFromUInt32Array (lldb::ByteOrder endian, uint32_t addr_byte_size, uint32_t* array, size_t array_len);
+
+ static lldb::SBData
+ CreateDataFromSInt64Array (lldb::ByteOrder endian, uint32_t addr_byte_size, int64_t* array, size_t array_len);
+
+ static lldb::SBData
+ CreateDataFromSInt32Array (lldb::ByteOrder endian, uint32_t addr_byte_size, int32_t* array, size_t array_len);
+
+ static lldb::SBData
+ CreateDataFromDoubleArray (lldb::ByteOrder endian, uint32_t addr_byte_size, double* array, size_t array_len);
+
+ bool
+ SetDataFromCString (const char* data);
+
+ bool
+ SetDataFromUInt64Array (uint64_t* array, size_t array_len);
+
+ bool
+ SetDataFromUInt32Array (uint32_t* array, size_t array_len);
+
+ bool
+ SetDataFromSInt64Array (int64_t* array, size_t array_len);
+
+ bool
+ SetDataFromSInt32Array (int32_t* array, size_t array_len);
+
+ bool
+ SetDataFromDoubleArray (double* array, size_t array_len);
+
+
+protected:
+
+ // Mimic shared pointer...
+ lldb_private::DataExtractor *
+ get() const;
+
+ lldb_private::DataExtractor *
+ operator->() const;
+
+ lldb::DataExtractorSP &
+ operator*();
+
+ const lldb::DataExtractorSP &
+ operator*() const;
+
+ SBData (const lldb::DataExtractorSP &data_sp);
+
+ void
+ SetOpaque (const lldb::DataExtractorSP &data_sp);
+
+private:
+ friend class SBInstruction;
+ friend class SBProcess;
+ friend class SBSection;
+ friend class SBValue;
+
+ lldb::DataExtractorSP m_opaque_sp;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBData_h_
diff --git a/include/lldb/API/SBDebugger.h b/include/lldb/API/SBDebugger.h
new file mode 100644
index 000000000000..518cbf67c932
--- /dev/null
+++ b/include/lldb/API/SBDebugger.h
@@ -0,0 +1,339 @@
+//===-- SBDebugger.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBDebugger_h_
+#define LLDB_SBDebugger_h_
+
+#include "lldb/API/SBDefines.h"
+#include <stdio.h>
+
+namespace lldb {
+
+class SBDebugger
+{
+public:
+
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ // Deprecated, use the one that takes a source_init_files bool.
+ static lldb::SBDebugger
+ Create();
+
+ static lldb::SBDebugger
+ Create(bool source_init_files);
+
+ static lldb::SBDebugger
+ Create(bool source_init_files, lldb::LogOutputCallback log_callback, void *baton);
+
+ static void
+ Destroy (lldb::SBDebugger &debugger);
+
+ static void
+ MemoryPressureDetected ();
+
+ SBDebugger();
+
+ SBDebugger(const lldb::SBDebugger &rhs);
+
+ SBDebugger(const lldb::DebuggerSP &debugger_sp);
+
+ lldb::SBDebugger &
+ operator = (const lldb::SBDebugger &rhs);
+
+ ~SBDebugger();
+
+ bool
+ IsValid() const;
+
+ void
+ Clear ();
+
+ void
+ SetAsync (bool b);
+
+ bool
+ GetAsync ();
+
+ void
+ SkipLLDBInitFiles (bool b);
+
+ void
+ SkipAppInitFiles (bool b);
+
+ void
+ SetInputFileHandle (FILE *f, bool transfer_ownership);
+
+ void
+ SetOutputFileHandle (FILE *f, bool transfer_ownership);
+
+ void
+ SetErrorFileHandle (FILE *f, bool transfer_ownership);
+
+ FILE *
+ GetInputFileHandle ();
+
+ FILE *
+ GetOutputFileHandle ();
+
+ FILE *
+ GetErrorFileHandle ();
+
+ void
+ SaveInputTerminalState();
+
+ void
+ RestoreInputTerminalState();
+
+ lldb::SBCommandInterpreter
+ GetCommandInterpreter ();
+
+ void
+ HandleCommand (const char *command);
+
+ lldb::SBListener
+ GetListener ();
+
+ void
+ HandleProcessEvent (const lldb::SBProcess &process,
+ const lldb::SBEvent &event,
+ FILE *out,
+ FILE *err);
+
+ lldb::SBTarget
+ CreateTarget (const char *filename,
+ const char *target_triple,
+ const char *platform_name,
+ bool add_dependent_modules,
+ lldb::SBError& error);
+
+ lldb::SBTarget
+ CreateTargetWithFileAndTargetTriple (const char *filename,
+ const char *target_triple);
+
+ lldb::SBTarget
+ CreateTargetWithFileAndArch (const char *filename,
+ const char *archname);
+
+ lldb::SBTarget
+ CreateTarget (const char *filename);
+
+ // Return true if target is deleted from the target list of the debugger.
+ bool
+ DeleteTarget (lldb::SBTarget &target);
+
+ lldb::SBTarget
+ GetTargetAtIndex (uint32_t idx);
+
+ uint32_t
+ GetIndexOfTarget (lldb::SBTarget target);
+
+ lldb::SBTarget
+ FindTargetWithProcessID (pid_t pid);
+
+ lldb::SBTarget
+ FindTargetWithFileAndArch (const char *filename,
+ const char *arch);
+
+ uint32_t
+ GetNumTargets ();
+
+ lldb::SBTarget
+ GetSelectedTarget ();
+
+ void
+ SetSelectedTarget (SBTarget& target);
+
+ lldb::SBSourceManager
+ GetSourceManager ();
+
+ // REMOVE: just for a quick fix, need to expose platforms through
+ // SBPlatform from this class.
+ lldb::SBError
+ SetCurrentPlatform (const char *platform_name);
+
+ bool
+ SetCurrentPlatformSDKRoot (const char *sysroot);
+
+ // FIXME: Once we get the set show stuff in place, the driver won't need
+ // an interface to the Set/Get UseExternalEditor.
+ bool
+ SetUseExternalEditor (bool input);
+
+ bool
+ GetUseExternalEditor ();
+
+ bool
+ SetUseColor (bool use_color);
+
+ bool
+ GetUseColor () const;
+
+ static bool
+ GetDefaultArchitecture (char *arch_name, size_t arch_name_len);
+
+ static bool
+ SetDefaultArchitecture (const char *arch_name);
+
+ lldb::ScriptLanguage
+ GetScriptingLanguage (const char *script_language_name);
+
+ static const char *
+ GetVersionString ();
+
+ static const char *
+ StateAsCString (lldb::StateType state);
+
+ static bool
+ StateIsRunningState (lldb::StateType state);
+
+ static bool
+ StateIsStoppedState (lldb::StateType state);
+
+ bool
+ EnableLog (const char *channel, const char **categories);
+
+ void
+ SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton);
+
+ // DEPRECATED
+ void
+ DispatchInput (void* baton,
+ const void* data,
+ size_t data_len);
+
+ void
+ DispatchInput (const void *data, size_t data_len);
+
+ void
+ DispatchInputInterrupt ();
+
+ void
+ DispatchInputEndOfFile ();
+
+ void
+ PushInputReader (lldb::SBInputReader &reader);
+
+ void
+ NotifyTopInputReader (lldb::InputReaderAction notification);
+
+ bool
+ InputReaderIsTopReader (const lldb::SBInputReader &reader);
+
+ const char *
+ GetInstanceName ();
+
+ static SBDebugger
+ FindDebuggerWithID (int id);
+
+ static lldb::SBError
+ SetInternalVariable (const char *var_name, const char *value, const char *debugger_instance_name);
+
+ static lldb::SBStringList
+ GetInternalVariableValue (const char *var_name, const char *debugger_instance_name);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ uint32_t
+ GetTerminalWidth () const;
+
+ void
+ SetTerminalWidth (uint32_t term_width);
+
+ lldb::user_id_t
+ GetID ();
+
+ const char *
+ GetPrompt() const;
+
+ void
+ SetPrompt (const char *prompt);
+
+ lldb::ScriptLanguage
+ GetScriptLanguage() const;
+
+ void
+ SetScriptLanguage (lldb::ScriptLanguage script_lang);
+
+ bool
+ GetCloseInputOnEOF () const;
+
+ void
+ SetCloseInputOnEOF (bool b);
+
+ SBTypeCategory
+ GetCategory (const char* category_name);
+
+ SBTypeCategory
+ CreateCategory (const char* category_name);
+
+ bool
+ DeleteCategory (const char* category_name);
+
+ uint32_t
+ GetNumCategories ();
+
+ SBTypeCategory
+ GetCategoryAtIndex (uint32_t);
+
+ SBTypeCategory
+ GetDefaultCategory();
+
+ SBTypeFormat
+ GetFormatForType (SBTypeNameSpecifier);
+
+#ifndef LLDB_DISABLE_PYTHON
+ SBTypeSummary
+ GetSummaryForType (SBTypeNameSpecifier);
+#endif
+
+ SBTypeFilter
+ GetFilterForType (SBTypeNameSpecifier);
+
+#ifndef LLDB_DISABLE_PYTHON
+ SBTypeSynthetic
+ GetSyntheticForType (SBTypeNameSpecifier);
+#endif
+
+private:
+
+ friend class SBCommandInterpreter;
+ friend class SBInputReader;
+ friend class SBListener;
+ friend class SBProcess;
+ friend class SBSourceManager;
+ friend class SBTarget;
+
+ lldb::SBTarget
+ FindTargetWithLLDBProcess (const lldb::ProcessSP &processSP);
+
+ void
+ reset (const lldb::DebuggerSP &debugger_sp);
+
+ lldb_private::Debugger *
+ get () const;
+
+ lldb_private::Debugger &
+ ref () const;
+
+ const lldb::DebuggerSP &
+ get_sp () const;
+
+ lldb::DebuggerSP m_opaque_sp;
+
+}; // class SBDebugger
+
+
+} // namespace lldb
+
+#endif // LLDB_SBDebugger_h_
diff --git a/include/lldb/API/SBDeclaration.h b/include/lldb/API/SBDeclaration.h
new file mode 100644
index 000000000000..190026c0d2d0
--- /dev/null
+++ b/include/lldb/API/SBDeclaration.h
@@ -0,0 +1,89 @@
+//===-- SBDeclaration.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBDeclaration_h_
+#define LLDB_SBDeclaration_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBFileSpec.h"
+
+namespace lldb {
+
+ class SBDeclaration
+ {
+ public:
+
+ SBDeclaration ();
+
+ SBDeclaration (const lldb::SBDeclaration &rhs);
+
+ ~SBDeclaration ();
+
+ const lldb::SBDeclaration &
+ operator = (const lldb::SBDeclaration &rhs);
+
+ bool
+ IsValid () const;
+
+ lldb::SBFileSpec
+ GetFileSpec () const;
+
+ uint32_t
+ GetLine () const;
+
+ uint32_t
+ GetColumn () const;
+
+ void
+ SetFileSpec (lldb::SBFileSpec filespec);
+
+ void
+ SetLine (uint32_t line);
+
+ void
+ SetColumn (uint32_t column);
+
+ bool
+ operator == (const lldb::SBDeclaration &rhs) const;
+
+ bool
+ operator != (const lldb::SBDeclaration &rhs) const;
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ protected:
+
+ lldb_private::Declaration *
+ get ();
+
+ private:
+ friend class SBValue;
+
+ const lldb_private::Declaration *
+ operator->() const;
+
+ lldb_private::Declaration &
+ ref();
+
+ const lldb_private::Declaration &
+ ref() const;
+
+ SBDeclaration (const lldb_private::Declaration *lldb_object_ptr);
+
+ void
+ SetDeclaration (const lldb_private::Declaration &lldb_object_ref);
+
+ std::unique_ptr<lldb_private::Declaration> m_opaque_ap;
+ };
+
+
+} // namespace lldb
+
+#endif // LLDB_SBDeclaration_h_
diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h
new file mode 100644
index 000000000000..2cdf92170d8d
--- /dev/null
+++ b/include/lldb/API/SBDefines.h
@@ -0,0 +1,84 @@
+//===-- SBDefines.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBDefines_h_
+#define LLDB_SBDefines_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+#include "lldb/lldb-versioning.h"
+
+// Forward Declarations
+
+namespace lldb {
+
+class SBAddress;
+class SBBlock;
+class SBBreakpoint;
+class SBBreakpointLocation;
+class SBBroadcaster;
+class SBCommand;
+class SBCommandInterpreter;
+class SBCommandPluginInterface;
+class SBCommandReturnObject;
+class SBCommunication;
+class SBCompileUnit;
+class SBData;
+class SBDebugger;
+class SBDeclaration;
+class SBError;
+class SBEvent;
+class SBEventList;
+class SBExpressionOptions;
+class SBFileSpec;
+class SBFileSpecList;
+class SBFrame;
+class SBFunction;
+class SBHostOS;
+class SBInputReader;
+class SBInstruction;
+class SBInstructionList;
+class SBLineEntry;
+class SBListener;
+class SBModule;
+class SBModuleSpec;
+class SBModuleSpecList;
+class SBProcess;
+class SBSourceManager;
+class SBStream;
+class SBStringList;
+class SBSymbol;
+class SBSymbolContext;
+class SBSymbolContextList;
+class SBTarget;
+class SBThread;
+class SBType;
+class SBTypeCategory;
+class SBTypeFilter;
+class SBTypeFormat;
+class SBTypeNameSpecifier;
+class SBTypeSummary;
+#ifndef LLDB_DISABLE_PYTHON
+class SBTypeSynthetic;
+#endif
+class SBTypeList;
+class SBValue;
+class SBValueList;
+class SBWatchpoint;
+
+}
+
+#endif // LLDB_SBDefines_h_
diff --git a/include/lldb/API/SBError.h b/include/lldb/API/SBError.h
new file mode 100644
index 000000000000..a6d3dacb4549
--- /dev/null
+++ b/include/lldb/API/SBError.h
@@ -0,0 +1,106 @@
+//===-- SBError.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBError_h_
+#define LLDB_SBError_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBError {
+public:
+ SBError ();
+
+ SBError (const lldb::SBError &rhs);
+
+ ~SBError();
+
+ const SBError &
+ operator =(const lldb::SBError &rhs);
+
+ const char *
+ GetCString () const;
+
+ void
+ Clear ();
+
+ bool
+ Fail () const;
+
+ bool
+ Success () const;
+
+ uint32_t
+ GetError () const;
+
+ lldb::ErrorType
+ GetType () const;
+
+ void
+ SetError (uint32_t err, lldb::ErrorType type);
+
+ void
+ SetErrorToErrno ();
+
+ void
+ SetErrorToGenericError ();
+
+ void
+ SetErrorString (const char *err_str);
+
+ int
+ SetErrorStringWithFormat (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ bool
+ IsValid () const;
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+protected:
+
+ friend class SBCommandReturnObject;
+ friend class SBData;
+ friend class SBDebugger;
+ friend class SBCommunication;
+ friend class SBHostOS;
+ friend class SBInputReader;
+ friend class SBProcess;
+ friend class SBThread;
+ friend class SBTarget;
+ friend class SBValue;
+ friend class SBWatchpoint;
+
+ lldb_private::Error *
+ get();
+
+ lldb_private::Error *
+ operator->();
+
+ const lldb_private::Error &
+ operator*() const;
+
+ lldb_private::Error &
+ ref();
+
+ void
+ SetError (const lldb_private::Error &lldb_error);
+
+private:
+ std::unique_ptr<lldb_private::Error> m_opaque_ap;
+
+ void
+ CreateIfNeeded ();
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBError_h_
diff --git a/include/lldb/API/SBEvent.h b/include/lldb/API/SBEvent.h
new file mode 100644
index 000000000000..6cb975a1ff7b
--- /dev/null
+++ b/include/lldb/API/SBEvent.h
@@ -0,0 +1,102 @@
+//===-- SBEvent.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBEvent_h_
+#define LLDB_SBEvent_h_
+
+#include "lldb/API/SBDefines.h"
+
+#include <stdio.h>
+#include <vector>
+
+
+namespace lldb {
+
+class SBBroadcaster;
+
+class SBEvent
+{
+public:
+ SBEvent();
+
+ SBEvent (const lldb::SBEvent &rhs);
+
+ // Make an event that contains a C string.
+ SBEvent (uint32_t event, const char *cstr, uint32_t cstr_len);
+
+ ~SBEvent();
+
+ const SBEvent &
+ operator = (const lldb::SBEvent &rhs);
+
+ bool
+ IsValid() const;
+
+ const char *
+ GetDataFlavor ();
+
+ uint32_t
+ GetType () const;
+
+ lldb::SBBroadcaster
+ GetBroadcaster () const;
+
+ const char *
+ GetBroadcasterClass () const;
+
+ bool
+ BroadcasterMatchesPtr (const lldb::SBBroadcaster *broadcaster);
+
+ bool
+ BroadcasterMatchesRef (const lldb::SBBroadcaster &broadcaster);
+
+ void
+ Clear();
+
+ static const char *
+ GetCStringFromEvent (const lldb::SBEvent &event);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ bool
+ GetDescription (lldb::SBStream &description) const;
+
+protected:
+ friend class SBListener;
+ friend class SBBroadcaster;
+ friend class SBBreakpoint;
+ friend class SBDebugger;
+ friend class SBProcess;
+ friend class SBThread;
+ friend class SBWatchpoint;
+
+ SBEvent (lldb::EventSP &event_sp);
+
+ lldb::EventSP &
+ GetSP () const;
+
+ void
+ reset (lldb::EventSP &event_sp);
+
+ void
+ reset (lldb_private::Event* event);
+
+ lldb_private::Event *
+ get () const;
+
+private:
+
+ mutable lldb::EventSP m_event_sp;
+ mutable lldb_private::Event *m_opaque_ptr;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBEvent_h_
diff --git a/include/lldb/API/SBExpressionOptions.h b/include/lldb/API/SBExpressionOptions.h
new file mode 100644
index 000000000000..eed9ed528bef
--- /dev/null
+++ b/include/lldb/API/SBExpressionOptions.h
@@ -0,0 +1,89 @@
+//===-- SBEvent.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBExpressionOptions_h_
+#define LLDB_SBExpressionOptions_h_
+
+#include "lldb/API/SBDefines.h"
+
+#include <vector>
+
+namespace lldb {
+
+
+class SBExpressionOptions
+{
+public:
+ SBExpressionOptions();
+
+ SBExpressionOptions (const lldb::SBExpressionOptions &rhs);
+
+ ~SBExpressionOptions();
+
+ const SBExpressionOptions &
+ operator = (const lldb::SBExpressionOptions &rhs);
+
+ bool
+ GetCoerceResultToId () const;
+
+ void
+ SetCoerceResultToId (bool coerce = true);
+
+ bool
+ GetUnwindOnError () const;
+
+ void
+ SetUnwindOnError (bool unwind = true);
+
+ bool
+ GetIgnoreBreakpoints () const;
+
+ void
+ SetIgnoreBreakpoints (bool ignore = true);
+
+ lldb::DynamicValueType
+ GetFetchDynamicValue () const;
+
+ void
+ SetFetchDynamicValue (lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget);
+
+ uint32_t
+ GetTimeoutInMicroSeconds () const;
+
+ void
+ SetTimeoutInMicroSeconds (uint32_t timeout = 0);
+
+ bool
+ GetTryAllThreads () const;
+
+ void
+ SetTryAllThreads (bool run_others = true);
+
+protected:
+
+ SBExpressionOptions (lldb_private::EvaluateExpressionOptions &expression_options);
+
+ lldb_private::EvaluateExpressionOptions *
+ get () const;
+
+ lldb_private::EvaluateExpressionOptions &
+ ref () const;
+
+ friend class SBFrame;
+ friend class SBValue;
+ friend class SBTarget;
+
+private:
+ // This auto_pointer is made in the constructor and is always valid.
+ mutable std::unique_ptr<lldb_private::EvaluateExpressionOptions> m_opaque_ap;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBExpressionOptions_h_
diff --git a/include/lldb/API/SBFileSpec.h b/include/lldb/API/SBFileSpec.h
new file mode 100644
index 000000000000..e44abe4759c6
--- /dev/null
+++ b/include/lldb/API/SBFileSpec.h
@@ -0,0 +1,96 @@
+//===-- SBFileSpec.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBFileSpec_h_
+#define LLDB_SBFileSpec_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBFileSpec
+{
+public:
+ SBFileSpec ();
+
+ SBFileSpec (const lldb::SBFileSpec &rhs);
+
+ SBFileSpec (const char *path);// Deprected, use SBFileSpec (const char *path, bool resolve)
+
+ SBFileSpec (const char *path, bool resolve);
+
+ ~SBFileSpec ();
+
+ const SBFileSpec &
+ operator = (const lldb::SBFileSpec &rhs);
+
+ bool
+ IsValid() const;
+
+ bool
+ Exists () const;
+
+ bool
+ ResolveExecutableLocation ();
+
+ const char *
+ GetFilename() const;
+
+ const char *
+ GetDirectory() const;
+
+ uint32_t
+ GetPath (char *dst_path, size_t dst_len) const;
+
+ static int
+ ResolvePath (const char *src_path, char *dst_path, size_t dst_len);
+
+ bool
+ GetDescription (lldb::SBStream &description) const;
+
+private:
+ friend class SBAttachInfo;
+ friend class SBBlock;
+ friend class SBCompileUnit;
+ friend class SBDeclaration;
+ friend class SBFileSpecList;
+ friend class SBHostOS;
+ friend class SBLaunchInfo;
+ friend class SBLineEntry;
+ friend class SBModule;
+ friend class SBModuleSpec;
+ friend class SBProcess;
+ friend class SBSourceManager;
+ friend class SBThread;
+ friend class SBTarget;
+
+ SBFileSpec (const lldb_private::FileSpec& fspec);
+
+ void
+ SetFileSpec (const lldb_private::FileSpec& fspec);
+
+ const lldb_private::FileSpec *
+ operator->() const;
+
+ const lldb_private::FileSpec *
+ get() const;
+
+ const lldb_private::FileSpec &
+ operator*() const;
+
+ const lldb_private::FileSpec &
+ ref() const;
+
+ std::unique_ptr<lldb_private::FileSpec> m_opaque_ap;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBFileSpec_h_
diff --git a/include/lldb/API/SBFileSpecList.h b/include/lldb/API/SBFileSpecList.h
new file mode 100644
index 000000000000..734e7d4d35cc
--- /dev/null
+++ b/include/lldb/API/SBFileSpecList.h
@@ -0,0 +1,72 @@
+//===-- SBFileSpecList.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBFileSpecList_h_
+#define LLDB_SBFileSpecList_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBFileSpecList
+{
+public:
+ SBFileSpecList ();
+
+ SBFileSpecList (const lldb::SBFileSpecList &rhs);
+
+ ~SBFileSpecList ();
+
+ const SBFileSpecList &
+ operator = (const lldb::SBFileSpecList &rhs);
+
+ uint32_t
+ GetSize () const;
+
+ bool
+ GetDescription (SBStream &description) const;
+
+ void
+ Append (const SBFileSpec &sb_file);
+
+ bool
+ AppendIfUnique (const SBFileSpec &sb_file);
+
+ void
+ Clear();
+
+ uint32_t
+ FindFileIndex (uint32_t idx, const SBFileSpec &sb_file, bool full);
+
+ const SBFileSpec
+ GetFileSpecAtIndex (uint32_t idx) const;
+
+private:
+
+friend class SBTarget;
+
+ const lldb_private::FileSpecList *
+ operator->() const;
+
+ const lldb_private::FileSpecList *
+ get() const;
+
+ const lldb_private::FileSpecList &
+ operator*() const;
+
+ const lldb_private::FileSpecList &
+ ref() const;
+
+ std::unique_ptr<lldb_private::FileSpecList> m_opaque_ap;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBFileSpecList_h_
diff --git a/include/lldb/API/SBFrame.h b/include/lldb/API/SBFrame.h
new file mode 100644
index 000000000000..4ae38c13bede
--- /dev/null
+++ b/include/lldb/API/SBFrame.h
@@ -0,0 +1,242 @@
+//===-- SBFrame.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBFrame_h_
+#define LLDB_SBFrame_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBValueList.h"
+
+namespace lldb {
+
+class SBFrame
+{
+public:
+ SBFrame ();
+
+ SBFrame (const lldb::SBFrame &rhs);
+
+ const lldb::SBFrame &
+ operator =(const lldb::SBFrame &rhs);
+
+ ~SBFrame();
+
+ bool
+ IsEqual (const lldb::SBFrame &that) const;
+
+ bool
+ IsValid() const;
+
+ uint32_t
+ GetFrameID () const;
+
+ lldb::addr_t
+ GetPC () const;
+
+ bool
+ SetPC (lldb::addr_t new_pc);
+
+ lldb::addr_t
+ GetSP () const;
+
+ lldb::addr_t
+ GetFP () const;
+
+ lldb::SBAddress
+ GetPCAddress () const;
+
+ lldb::SBSymbolContext
+ GetSymbolContext (uint32_t resolve_scope) const;
+
+ lldb::SBModule
+ GetModule () const;
+
+ lldb::SBCompileUnit
+ GetCompileUnit () const;
+
+ lldb::SBFunction
+ GetFunction () const;
+
+ lldb::SBSymbol
+ GetSymbol () const;
+
+ /// Gets the deepest block that contains the frame PC.
+ ///
+ /// See also GetFrameBlock().
+ lldb::SBBlock
+ GetBlock () const;
+
+ /// Get the appropriate function name for this frame. Inlined functions in
+ /// LLDB are represented by Blocks that have inlined function information, so
+ /// just looking at the SBFunction or SBSymbol for a frame isn't enough.
+ /// This function will return the appriopriate function, symbol or inlined
+ /// function name for the frame.
+ ///
+ /// This function returns:
+ /// - the name of the inlined function (if there is one)
+ /// - the name of the concrete function (if there is one)
+ /// - the name of the symbol (if there is one)
+ /// - NULL
+ ///
+ /// See also IsInlined().
+ const char *
+ GetFunctionName();
+
+ /// Return true if this frame represents an inlined function.
+ ///
+ /// See also GetFunctionName().
+ bool
+ IsInlined();
+
+ /// The version that doesn't supply a 'use_dynamic' value will use the
+ /// target's default.
+ lldb::SBValue
+ EvaluateExpression (const char *expr);
+
+ lldb::SBValue
+ EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic);
+
+ lldb::SBValue
+ EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic, bool unwind_on_error);
+
+ lldb::SBValue
+ EvaluateExpression (const char *expr, const SBExpressionOptions &options);
+
+ /// Gets the lexical block that defines the stack frame. Another way to think
+ /// of this is it will return the block that contains all of the variables
+ /// for a stack frame. Inlined functions are represented as SBBlock objects
+ /// that have inlined function information: the name of the inlined function,
+ /// where it was called from. The block that is returned will be the first
+ /// block at or above the block for the PC (SBFrame::GetBlock()) that defines
+ /// the scope of the frame. When a function contains no inlined functions,
+ /// this will be the top most lexical block that defines the function.
+ /// When a function has inlined functions and the PC is currently
+ /// in one of those inlined functions, this method will return the inlined
+ /// block that defines this frame. If the PC isn't currently in an inlined
+ /// function, the lexical block that defines the function is returned.
+ lldb::SBBlock
+ GetFrameBlock () const;
+
+ lldb::SBLineEntry
+ GetLineEntry () const;
+
+ lldb::SBThread
+ GetThread () const;
+
+ const char *
+ Disassemble () const;
+
+ void
+ Clear();
+
+ bool
+ operator == (const lldb::SBFrame &rhs) const;
+
+ bool
+ operator != (const lldb::SBFrame &rhs) const;
+
+ /// The version that doesn't supply a 'use_dynamic' value will use the
+ /// target's default.
+ lldb::SBValueList
+ GetVariables (bool arguments,
+ bool locals,
+ bool statics,
+ bool in_scope_only);
+
+ lldb::SBValueList
+ GetVariables (bool arguments,
+ bool locals,
+ bool statics,
+ bool in_scope_only,
+ lldb::DynamicValueType use_dynamic);
+
+ lldb::SBValueList
+ GetRegisters ();
+
+ lldb::SBValue
+ FindRegister (const char *name);
+
+ /// The version that doesn't supply a 'use_dynamic' value will use the
+ /// target's default.
+ lldb::SBValue
+ FindVariable (const char *var_name);
+
+ lldb::SBValue
+ FindVariable (const char *var_name, lldb::DynamicValueType use_dynamic);
+
+ // Find a value for a variable expression path like "rect.origin.x" or
+ // "pt_ptr->x", "*self", "*this->obj_ptr". The returned value is _not_
+ // and expression result and is not a constant object like
+ // SBFrame::EvaluateExpression(...) returns, but a child object of
+ // the variable value.
+ lldb::SBValue
+ GetValueForVariablePath (const char *var_expr_cstr,
+ DynamicValueType use_dynamic);
+
+ /// The version that doesn't supply a 'use_dynamic' value will use the
+ /// target's default.
+ lldb::SBValue
+ GetValueForVariablePath (const char *var_path);
+
+ /// Find variables, register sets, registers, or persistent variables using
+ /// the frame as the scope.
+ ///
+ /// NB. This function does not look up ivars in the function object pointer.
+ /// To do that use GetValueForVariablePath.
+ ///
+ /// The version that doesn't supply a 'use_dynamic' value will use the
+ /// target's default.
+ lldb::SBValue
+ FindValue (const char *name, ValueType value_type);
+
+ lldb::SBValue
+ FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic);
+
+ /// Find and watch a variable using the frame as the scope.
+ /// It returns an SBValue, similar to FindValue() method, if find-and-watch
+ /// operation succeeds. Otherwise, an invalid SBValue is returned.
+ /// You can use LLDB_WATCH_TYPE_READ | LLDB_WATCH_TYPE_WRITE for 'rw' watch.
+ lldb::SBValue
+ WatchValue (const char *name, ValueType value_type, uint32_t watch_type);
+
+ /// Find and watch the location pointed to by a variable using the frame as
+ /// the scope.
+ /// It returns an SBValue, similar to FindValue() method, if find-and-watch
+ /// operation succeeds. Otherwise, an invalid SBValue is returned.
+ /// You can use LLDB_WATCH_TYPE_READ | LLDB_WATCH_TYPE_WRITE for 'rw' watch.
+ lldb::SBValue
+ WatchLocation (const char *name, ValueType value_type, uint32_t watch_type, size_t size);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ SBFrame (const lldb::StackFrameSP &lldb_object_sp);
+
+protected:
+
+ friend class SBBlock;
+ friend class SBInstruction;
+ friend class SBThread;
+ friend class SBValue;
+#ifndef LLDB_DISABLE_PYTHON
+ friend class lldb_private::ScriptInterpreterPython;
+#endif
+
+ lldb::StackFrameSP
+ GetFrameSP() const;
+
+ void
+ SetFrameSP (const lldb::StackFrameSP &lldb_object_sp);
+
+ lldb::ExecutionContextRefSP m_opaque_sp;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBFrame_h_
diff --git a/include/lldb/API/SBFunction.h b/include/lldb/API/SBFunction.h
new file mode 100644
index 000000000000..49a3847efbec
--- /dev/null
+++ b/include/lldb/API/SBFunction.h
@@ -0,0 +1,93 @@
+//===-- SBFunction.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBFunction_h_
+#define LLDB_SBFunction_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBAddress.h"
+#include "lldb/API/SBInstructionList.h"
+
+namespace lldb {
+
+class SBFunction
+{
+public:
+
+ SBFunction ();
+
+ SBFunction (const lldb::SBFunction &rhs);
+
+ const lldb::SBFunction &
+ operator = (const lldb::SBFunction &rhs);
+
+ ~SBFunction ();
+
+ bool
+ IsValid () const;
+
+ const char *
+ GetName() const;
+
+ const char *
+ GetMangledName () const;
+
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target);
+
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target, const char *flavor);
+
+ lldb::SBAddress
+ GetStartAddress ();
+
+ lldb::SBAddress
+ GetEndAddress ();
+
+ uint32_t
+ GetPrologueByteSize ();
+
+ lldb::SBType
+ GetType ();
+
+ lldb::SBBlock
+ GetBlock ();
+
+ bool
+ operator == (const lldb::SBFunction &rhs) const;
+
+ bool
+ operator != (const lldb::SBFunction &rhs) const;
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+protected:
+
+ lldb_private::Function *
+ get ();
+
+ void
+ reset (lldb_private::Function *lldb_object_ptr);
+
+private:
+ friend class SBAddress;
+ friend class SBFrame;
+ friend class SBSymbolContext;
+
+ SBFunction (lldb_private::Function *lldb_object_ptr);
+
+
+ lldb_private::Function *m_opaque_ptr;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBFunction_h_
diff --git a/include/lldb/API/SBHostOS.h b/include/lldb/API/SBHostOS.h
new file mode 100644
index 000000000000..52754ea4e829
--- /dev/null
+++ b/include/lldb/API/SBHostOS.h
@@ -0,0 +1,57 @@
+//===-- SBHostOS.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBHostOS_h_
+#define LLDB_SBHostOS_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBFileSpec.h"
+
+namespace lldb {
+
+class SBHostOS
+{
+public:
+
+ static lldb::SBFileSpec
+ GetProgramFileSpec ();
+
+ static lldb::SBFileSpec
+ GetLLDBPythonPath ();
+
+ static void
+ ThreadCreated (const char *name);
+
+ static lldb::thread_t
+ ThreadCreate (const char *name,
+ void *(*thread_function)(void *),
+ void *thread_arg,
+ lldb::SBError *err);
+
+ static bool
+ ThreadCancel (lldb::thread_t thread,
+ lldb::SBError *err);
+
+ static bool
+ ThreadDetach (lldb::thread_t thread,
+ lldb::SBError *err);
+ static bool
+ ThreadJoin (lldb::thread_t thread,
+ void **result,
+ lldb::SBError *err);
+
+
+private:
+
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBHostOS_h_
diff --git a/include/lldb/API/SBInputReader.h b/include/lldb/API/SBInputReader.h
new file mode 100644
index 000000000000..61f7de4fde4c
--- /dev/null
+++ b/include/lldb/API/SBInputReader.h
@@ -0,0 +1,97 @@
+//===-- SBInputReader.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBInputReader_h_
+#define LLDB_SBInputReader_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBInputReader
+{
+public:
+
+ typedef size_t (*Callback) (void *baton,
+ SBInputReader *reader,
+ InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+ SBInputReader ();
+
+ SBInputReader (const lldb::InputReaderSP &reader_sp);
+
+ SBInputReader (const lldb::SBInputReader &rhs);
+
+ ~SBInputReader ();
+
+
+ SBError
+ Initialize (SBDebugger &debugger,
+ Callback callback,
+ void *callback_baton,
+ lldb::InputReaderGranularity granularity,
+ const char *end_token,
+ const char *prompt,
+ bool echo);
+
+ bool
+ IsValid () const;
+
+ const lldb::SBInputReader &
+ operator = (const lldb::SBInputReader &rhs);
+
+ bool
+ IsActive () const;
+
+ bool
+ IsDone () const;
+
+ void
+ SetIsDone (bool value);
+
+ InputReaderGranularity
+ GetGranularity ();
+
+protected:
+ friend class SBDebugger;
+
+ lldb_private::InputReader *
+ operator->() const;
+
+ lldb::InputReaderSP &
+ operator *();
+
+ const lldb::InputReaderSP &
+ operator *() const;
+
+ lldb_private::InputReader *
+ get() const;
+
+ lldb_private::InputReader &
+ ref() const;
+
+private:
+
+ static size_t
+ PrivateCallback (void *baton,
+ lldb_private::InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+ lldb::InputReaderSP m_opaque_sp;
+ Callback m_callback_function;
+ void *m_callback_baton;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBInputReader_h_
diff --git a/include/lldb/API/SBInstruction.h b/include/lldb/API/SBInstruction.h
new file mode 100644
index 000000000000..aad2d87f4f33
--- /dev/null
+++ b/include/lldb/API/SBInstruction.h
@@ -0,0 +1,94 @@
+//===-- SBInstruction.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBInstruction_h_
+#define LLDB_SBInstruction_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBData.h"
+
+#include <stdio.h>
+
+// There's a lot to be fixed here, but need to wait for underlying insn implementation
+// to be revised & settle down first.
+
+namespace lldb {
+
+class SBInstruction
+{
+public:
+
+ SBInstruction ();
+
+ SBInstruction (const SBInstruction &rhs);
+
+ const SBInstruction &
+ operator = (const SBInstruction &rhs);
+
+ ~SBInstruction ();
+
+ bool
+ IsValid();
+
+ SBAddress
+ GetAddress();
+
+ lldb::AddressClass
+ GetAddressClass ();
+
+ const char *
+ GetMnemonic (lldb::SBTarget target);
+
+ const char *
+ GetOperands (lldb::SBTarget target);
+
+ const char *
+ GetComment (lldb::SBTarget target);
+
+ lldb::SBData
+ GetData (lldb::SBTarget target);
+
+ size_t
+ GetByteSize ();
+
+ bool
+ DoesBranch ();
+
+ void
+ Print (FILE *out);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ bool
+ EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options);
+
+ bool
+ DumpEmulation (const char * triple); // triple is to specify the architecture, e.g. 'armv6' or 'armv7-apple-ios'
+
+ bool
+ TestEmulation (lldb::SBStream &output_stream, const char *test_file);
+
+protected:
+ friend class SBInstructionList;
+
+ SBInstruction (const lldb::InstructionSP &inst_sp);
+
+ void
+ SetOpaque (const lldb::InstructionSP &inst_sp);
+
+private:
+
+ lldb::InstructionSP m_opaque_sp;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBInstruction_h_
diff --git a/include/lldb/API/SBInstructionList.h b/include/lldb/API/SBInstructionList.h
new file mode 100644
index 000000000000..944e144a1480
--- /dev/null
+++ b/include/lldb/API/SBInstructionList.h
@@ -0,0 +1,71 @@
+//===-- SBInstructionList.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBInstructionList_h_
+#define LLDB_SBInstructionList_h_
+
+#include "lldb/API/SBDefines.h"
+
+#include <stdio.h>
+
+namespace lldb {
+
+class SBInstructionList
+{
+public:
+
+ SBInstructionList ();
+
+ SBInstructionList (const SBInstructionList &rhs);
+
+ const SBInstructionList &
+ operator = (const SBInstructionList &rhs);
+
+ ~SBInstructionList ();
+
+ bool
+ IsValid () const;
+
+ size_t
+ GetSize ();
+
+ lldb::SBInstruction
+ GetInstructionAtIndex (uint32_t idx);
+
+ void
+ Clear ();
+
+ void
+ AppendInstruction (lldb::SBInstruction inst);
+
+ void
+ Print (FILE *out);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ bool
+ DumpEmulationForAllInstructions (const char *triple);
+
+protected:
+ friend class SBFunction;
+ friend class SBSymbol;
+ friend class SBTarget;
+
+ void
+ SetDisassembler (const lldb::DisassemblerSP &opaque_sp);
+
+private:
+ lldb::DisassemblerSP m_opaque_sp;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBInstructionList_h_
diff --git a/include/lldb/API/SBLineEntry.h b/include/lldb/API/SBLineEntry.h
new file mode 100644
index 000000000000..2d099a297980
--- /dev/null
+++ b/include/lldb/API/SBLineEntry.h
@@ -0,0 +1,99 @@
+//===-- SBLineEntry.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBLineEntry_h_
+#define LLDB_SBLineEntry_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBAddress.h"
+#include "lldb/API/SBFileSpec.h"
+
+namespace lldb {
+
+class SBLineEntry
+{
+public:
+
+ SBLineEntry ();
+
+ SBLineEntry (const lldb::SBLineEntry &rhs);
+
+ ~SBLineEntry ();
+
+ const lldb::SBLineEntry &
+ operator = (const lldb::SBLineEntry &rhs);
+
+ lldb::SBAddress
+ GetStartAddress () const;
+
+ lldb::SBAddress
+ GetEndAddress () const;
+
+ bool
+ IsValid () const;
+
+ lldb::SBFileSpec
+ GetFileSpec () const;
+
+ uint32_t
+ GetLine () const;
+
+ uint32_t
+ GetColumn () const;
+
+ void
+ SetFileSpec (lldb::SBFileSpec filespec);
+
+ void
+ SetLine (uint32_t line);
+
+ void
+ SetColumn (uint32_t column);
+
+ bool
+ operator == (const lldb::SBLineEntry &rhs) const;
+
+ bool
+ operator != (const lldb::SBLineEntry &rhs) const;
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+protected:
+
+ lldb_private::LineEntry *
+ get ();
+
+private:
+ friend class SBAddress;
+ friend class SBCompileUnit;
+ friend class SBFrame;
+ friend class SBSymbolContext;
+
+ const lldb_private::LineEntry *
+ operator->() const;
+
+ lldb_private::LineEntry &
+ ref();
+
+ const lldb_private::LineEntry &
+ ref() const;
+
+ SBLineEntry (const lldb_private::LineEntry *lldb_object_ptr);
+
+ void
+ SetLineEntry (const lldb_private::LineEntry &lldb_object_ref);
+
+ std::unique_ptr<lldb_private::LineEntry> m_opaque_ap;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBLineEntry_h_
diff --git a/include/lldb/API/SBListener.h b/include/lldb/API/SBListener.h
new file mode 100644
index 000000000000..c5a047341741
--- /dev/null
+++ b/include/lldb/API/SBListener.h
@@ -0,0 +1,135 @@
+//===-- SBListener.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBListener_h_
+#define LLDB_SBListener_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBListener
+{
+public:
+ SBListener ();
+
+ SBListener (const char *name);
+
+ SBListener (const SBListener &rhs);
+
+ ~SBListener ();
+
+ const lldb::SBListener &
+ operator = (const lldb::SBListener &rhs);
+
+ void
+ AddEvent (const lldb::SBEvent &event);
+
+ void
+ Clear ();
+
+ bool
+ IsValid () const;
+
+ uint32_t
+ StartListeningForEventClass (SBDebugger &debugger,
+ const char *broadcaster_class,
+ uint32_t event_mask);
+
+ bool
+ StopListeningForEventClass (SBDebugger &debugger,
+ const char *broadcaster_class,
+ uint32_t event_mask);
+
+ uint32_t
+ StartListeningForEvents (const lldb::SBBroadcaster& broadcaster,
+ uint32_t event_mask);
+
+ bool
+ StopListeningForEvents (const lldb::SBBroadcaster& broadcaster,
+ uint32_t event_mask);
+
+ // Returns true if an event was recieved, false if we timed out.
+ bool
+ WaitForEvent (uint32_t num_seconds,
+ lldb::SBEvent &event);
+
+ bool
+ WaitForEventForBroadcaster (uint32_t num_seconds,
+ const lldb::SBBroadcaster &broadcaster,
+ lldb::SBEvent &sb_event);
+
+ bool
+ WaitForEventForBroadcasterWithType (uint32_t num_seconds,
+ const lldb::SBBroadcaster &broadcaster,
+ uint32_t event_type_mask,
+ lldb::SBEvent &sb_event);
+
+ bool
+ PeekAtNextEvent (lldb::SBEvent &sb_event);
+
+ bool
+ PeekAtNextEventForBroadcaster (const lldb::SBBroadcaster &broadcaster,
+ lldb::SBEvent &sb_event);
+
+ bool
+ PeekAtNextEventForBroadcasterWithType (const lldb::SBBroadcaster &broadcaster,
+ uint32_t event_type_mask,
+ lldb::SBEvent &sb_event);
+
+ bool
+ GetNextEvent (lldb::SBEvent &sb_event);
+
+ bool
+ GetNextEventForBroadcaster (const lldb::SBBroadcaster &broadcaster,
+ lldb::SBEvent &sb_event);
+
+ bool
+ GetNextEventForBroadcasterWithType (const lldb::SBBroadcaster &broadcaster,
+ uint32_t event_type_mask,
+ lldb::SBEvent &sb_event);
+
+ bool
+ HandleBroadcastEvent (const lldb::SBEvent &event);
+
+protected:
+ friend class SBBroadcaster;
+ friend class SBCommandInterpreter;
+ friend class SBDebugger;
+ friend class SBTarget;
+
+ SBListener (lldb_private::Listener &listener);
+
+private:
+
+ lldb_private::Listener *
+ operator->() const;
+
+ lldb_private::Listener *
+ get() const;
+
+ lldb_private::Listener &
+ ref() const;
+
+ lldb_private::Listener &
+ operator *();
+
+ const lldb_private::Listener &
+ operator *() const;
+
+ void
+ reset(lldb_private::Listener *listener, bool transfer_ownership);
+
+ lldb::ListenerSP m_opaque_sp;
+ lldb_private::Listener *m_opaque_ptr;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBListener_h_
diff --git a/include/lldb/API/SBModule.h b/include/lldb/API/SBModule.h
new file mode 100644
index 000000000000..a3c4879aa2f9
--- /dev/null
+++ b/include/lldb/API/SBModule.h
@@ -0,0 +1,287 @@
+//===-- SBModule.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBModule_h_
+#define LLDB_SBModule_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBSection.h"
+#include "lldb/API/SBSymbolContext.h"
+#include "lldb/API/SBValueList.h"
+
+namespace lldb {
+
+class SBModule
+{
+public:
+
+ SBModule ();
+
+ SBModule (const SBModule &rhs);
+
+ SBModule (const SBModuleSpec &module_spec);
+
+ const SBModule &
+ operator = (const SBModule &rhs);
+
+ SBModule (lldb::SBProcess &process,
+ lldb::addr_t header_addr);
+
+ ~SBModule ();
+
+ bool
+ IsValid () const;
+
+ void
+ Clear();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the module file specification.
+ ///
+ /// This function returns the file for the module on the host system
+ /// that is running LLDB. This can differ from the path on the
+ /// platform since we might be doing remote debugging.
+ ///
+ /// @return
+ /// A const reference to the file specification object.
+ //------------------------------------------------------------------
+ lldb::SBFileSpec
+ GetFileSpec () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the module platform file specification.
+ ///
+ /// Platform file refers to the path of the module as it is known on
+ /// the remote system on which it is being debugged. For local
+ /// debugging this is always the same as Module::GetFileSpec(). But
+ /// remote debugging might mention a file '/usr/lib/liba.dylib'
+ /// which might be locally downloaded and cached. In this case the
+ /// platform file could be something like:
+ /// '/tmp/lldb/platform-cache/remote.host.computer/usr/lib/liba.dylib'
+ /// The file could also be cached in a local developer kit directory.
+ ///
+ /// @return
+ /// A const reference to the file specification object.
+ //------------------------------------------------------------------
+ lldb::SBFileSpec
+ GetPlatformFileSpec () const;
+
+ bool
+ SetPlatformFileSpec (const lldb::SBFileSpec &platform_file);
+
+ lldb::ByteOrder
+ GetByteOrder ();
+
+ uint32_t
+ GetAddressByteSize();
+
+ const char *
+ GetTriple ();
+
+ const uint8_t *
+ GetUUIDBytes () const;
+
+ const char *
+ GetUUIDString () const;
+
+ bool
+ operator == (const lldb::SBModule &rhs) const;
+
+ bool
+ operator != (const lldb::SBModule &rhs) const;
+
+ lldb::SBSection
+ FindSection (const char *sect_name);
+
+ lldb::SBAddress
+ ResolveFileAddress (lldb::addr_t vm_addr);
+
+ lldb::SBSymbolContext
+ ResolveSymbolContextForAddress (const lldb::SBAddress& addr,
+ uint32_t resolve_scope);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ uint32_t
+ GetNumCompileUnits();
+
+ lldb::SBCompileUnit
+ GetCompileUnitAtIndex (uint32_t);
+
+ size_t
+ GetNumSymbols ();
+
+ lldb::SBSymbol
+ GetSymbolAtIndex (size_t idx);
+
+ lldb::SBSymbol
+ FindSymbol (const char *name,
+ lldb::SymbolType type = eSymbolTypeAny);
+
+ lldb::SBSymbolContextList
+ FindSymbols (const char *name,
+ lldb::SymbolType type = eSymbolTypeAny);
+
+ size_t
+ GetNumSections ();
+
+ lldb::SBSection
+ GetSectionAtIndex (size_t idx);
+ //------------------------------------------------------------------
+ /// Find functions by name.
+ ///
+ /// @param[in] name
+ /// The name of the function we are looking for.
+ ///
+ /// @param[in] name_type_mask
+ /// A logical OR of one or more FunctionNameType enum bits that
+ /// indicate what kind of names should be used when doing the
+ /// lookup. Bits include fully qualified names, base names,
+ /// C++ methods, or ObjC selectors.
+ /// See FunctionNameType for more details.
+ ///
+ /// @return
+ /// A lldb::SBSymbolContextList that gets filled in with all of
+ /// the symbol contexts for all the matches.
+ //------------------------------------------------------------------
+ lldb::SBSymbolContextList
+ FindFunctions (const char *name,
+ uint32_t name_type_mask = lldb::eFunctionNameTypeAny);
+
+ //------------------------------------------------------------------
+ /// Find global and static variables by name.
+ ///
+ /// @param[in] target
+ /// A valid SBTarget instance representing the debuggee.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @param[in] max_matches
+ /// Allow the number of matches to be limited to \a max_matches.
+ ///
+ /// @return
+ /// A list of matched variables in an SBValueList.
+ //------------------------------------------------------------------
+ lldb::SBValueList
+ FindGlobalVariables (lldb::SBTarget &target,
+ const char *name,
+ uint32_t max_matches);
+
+ //------------------------------------------------------------------
+ /// Find the first global (or static) variable by name.
+ ///
+ /// @param[in] target
+ /// A valid SBTarget instance representing the debuggee.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @return
+ /// An SBValue that gets filled in with the found variable (if any).
+ //------------------------------------------------------------------
+ lldb::SBValue
+ FindFirstGlobalVariable (lldb::SBTarget &target, const char *name);
+
+ lldb::SBType
+ FindFirstType (const char* name);
+
+ lldb::SBTypeList
+ FindTypes (const char* type);
+
+ lldb::SBType
+ GetBasicType(lldb::BasicType type);
+
+ //------------------------------------------------------------------
+ /// Get all types matching \a type_mask from debug info in this
+ /// module.
+ ///
+ /// @param[in] type_mask
+ /// A bitfield that consists of one or more bits logically OR'ed
+ /// together from the lldb::TypeClass enumeration. This allows
+ /// you to request only structure types, or only class, struct
+ /// and union types. Passing in lldb::eTypeClassAny will return
+ /// all types found in the debug information for this module.
+ ///
+ /// @return
+ /// A list of types in this module that match \a type_mask
+ //------------------------------------------------------------------
+ lldb::SBTypeList
+ GetTypes (uint32_t type_mask = lldb::eTypeClassAny);
+
+ //------------------------------------------------------------------
+ /// Get the module version numbers.
+ ///
+ /// Many object files have a set of version numbers that describe
+ /// the version of the executable or shared library. Typically there
+ /// are major, minor and build, but there may be more. This function
+ /// will extract the versions from object files if they are available.
+ ///
+ /// If \a versions is NULL, or if \a num_versions is 0, the return
+ /// value will indicate how many version numbers are available in
+ /// this object file. Then a subsequent call can be made to this
+ /// function with a value of \a versions and \a num_versions that
+ /// has enough storage to store some or all version numbers.
+ ///
+ /// @param[out] versions
+ /// A pointer to an array of uint32_t types that is \a num_versions
+ /// long. If this value is NULL, the return value will indicate
+ /// how many version numbers are required for a subsequent call
+ /// to this function so that all versions can be retrieved. If
+ /// the value is non-NULL, then at most \a num_versions of the
+ /// existing versions numbers will be filled into \a versions.
+ /// If there is no version information available, \a versions
+ /// will be filled with \a num_versions UINT32_MAX values
+ /// and zero will be returned.
+ ///
+ /// @param[in] num_versions
+ /// The maximum number of entries to fill into \a versions. If
+ /// this value is zero, then the return value will indicate
+ /// how many version numbers there are in total so another call
+ /// to this function can be make with adequate storage in
+ /// \a versions to get all of the version numbers. If \a
+ /// num_versions is less than the actual number of version
+ /// numbers in this object file, only \a num_versions will be
+ /// filled into \a versions (if \a versions is non-NULL).
+ ///
+ /// @return
+ /// This function always returns the number of version numbers
+ /// that this object file has regardless of the number of
+ /// version numbers that were copied into \a versions.
+ //------------------------------------------------------------------
+ uint32_t
+ GetVersion (uint32_t *versions,
+ uint32_t num_versions);
+
+private:
+ friend class SBAddress;
+ friend class SBFrame;
+ friend class SBSection;
+ friend class SBSymbolContext;
+ friend class SBTarget;
+
+ explicit SBModule (const lldb::ModuleSP& module_sp);
+
+ ModuleSP
+ GetSP () const;
+
+ void
+ SetSP (const ModuleSP &module_sp);
+
+ lldb::ModuleSP m_opaque_sp;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBModule_h_
diff --git a/include/lldb/API/SBModuleSpec.h b/include/lldb/API/SBModuleSpec.h
new file mode 100644
index 000000000000..a615e017cbc8
--- /dev/null
+++ b/include/lldb/API/SBModuleSpec.h
@@ -0,0 +1,154 @@
+//===-- SBModuleSpec.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBModuleSpec_h_
+#define LLDB_SBModuleSpec_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBFileSpec.h"
+
+namespace lldb {
+
+class SBModuleSpec
+{
+public:
+
+ SBModuleSpec ();
+
+ SBModuleSpec (const SBModuleSpec &rhs);
+
+ ~SBModuleSpec ();
+
+ const SBModuleSpec &
+ operator = (const SBModuleSpec &rhs);
+
+ bool
+ IsValid () const;
+
+ void
+ Clear();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the module file.
+ ///
+ /// This function returns the file for the module on the host system
+ /// that is running LLDB. This can differ from the path on the
+ /// platform since we might be doing remote debugging.
+ ///
+ /// @return
+ /// A const reference to the file specification object.
+ //------------------------------------------------------------------
+ lldb::SBFileSpec
+ GetFileSpec ();
+
+ void
+ SetFileSpec (const lldb::SBFileSpec &fspec);
+
+ //------------------------------------------------------------------
+ /// Get accessor for the module platform file.
+ ///
+ /// Platform file refers to the path of the module as it is known on
+ /// the remote system on which it is being debugged. For local
+ /// debugging this is always the same as Module::GetFileSpec(). But
+ /// remote debugging might mention a file '/usr/lib/liba.dylib'
+ /// which might be locally downloaded and cached. In this case the
+ /// platform file could be something like:
+ /// '/tmp/lldb/platform-cache/remote.host.computer/usr/lib/liba.dylib'
+ /// The file could also be cached in a local developer kit directory.
+ ///
+ /// @return
+ /// A const reference to the file specification object.
+ //------------------------------------------------------------------
+ lldb::SBFileSpec
+ GetPlatformFileSpec ();
+
+ void
+ SetPlatformFileSpec (const lldb::SBFileSpec &fspec);
+
+ lldb::SBFileSpec
+ GetSymbolFileSpec ();
+
+ void
+ SetSymbolFileSpec (const lldb::SBFileSpec &fspec);
+
+ const char *
+ GetObjectName ();
+
+ void
+ SetObjectName (const char *name);
+
+ const char *
+ GetTriple ();
+
+ void
+ SetTriple (const char *triple);
+
+ const uint8_t *
+ GetUUIDBytes ();
+
+ size_t
+ GetUUIDLength ();
+
+ bool
+ SetUUIDBytes (const uint8_t *uuid, size_t uuid_len);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+private:
+ friend class SBModuleSpecList;
+ friend class SBModule;
+ friend class SBTarget;
+
+ std::unique_ptr<lldb_private::ModuleSpec> m_opaque_ap;
+};
+
+class SBModuleSpecList
+{
+public:
+ SBModuleSpecList();
+
+ SBModuleSpecList (const SBModuleSpecList &rhs);
+
+ ~SBModuleSpecList();
+
+ SBModuleSpecList &
+ operator = (const SBModuleSpecList &rhs);
+
+ static SBModuleSpecList
+ GetModuleSpecifications (const char *path);
+
+ void
+ Append (const SBModuleSpec &spec);
+
+ void
+ Append (const SBModuleSpecList &spec_list);
+
+ SBModuleSpec
+ FindFirstMatchingSpec (const SBModuleSpec &match_spec);
+
+ SBModuleSpecList
+ FindMatchingSpecs (const SBModuleSpec &match_spec);
+
+ size_t
+ GetSize();
+
+ SBModuleSpec
+ GetSpecAtIndex (size_t i);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+private:
+ std::unique_ptr<lldb_private::ModuleSpecList> m_opaque_ap;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBModuleSpec_h_
diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h
new file mode 100644
index 000000000000..784f362122a9
--- /dev/null
+++ b/include/lldb/API/SBProcess.h
@@ -0,0 +1,295 @@
+//===-- SBProcess.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBProcess_h_
+#define LLDB_SBProcess_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBTarget.h"
+#include <stdio.h>
+
+namespace lldb {
+
+class SBEvent;
+
+class SBProcess
+{
+public:
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ enum
+ {
+ eBroadcastBitStateChanged = (1 << 0),
+ eBroadcastBitInterrupt = (1 << 1),
+ eBroadcastBitSTDOUT = (1 << 2),
+ eBroadcastBitSTDERR = (1 << 3),
+ eBroadcastBitProfileData = (1 << 4)
+ };
+
+ SBProcess ();
+
+ SBProcess (const lldb::SBProcess& rhs);
+
+ const lldb::SBProcess&
+ operator = (const lldb::SBProcess& rhs);
+
+ SBProcess (const lldb::ProcessSP &process_sp);
+
+ ~SBProcess();
+
+ static const char *
+ GetBroadcasterClassName ();
+
+ const char *
+ GetPluginName ();
+
+ // DEPRECATED: use GetPluginName()
+ const char *
+ GetShortPluginName ();
+
+ void
+ Clear ();
+
+ bool
+ IsValid() const;
+
+ lldb::SBTarget
+ GetTarget() const;
+
+ lldb::ByteOrder
+ GetByteOrder() const;
+
+ size_t
+ PutSTDIN (const char *src, size_t src_len);
+
+ size_t
+ GetSTDOUT (char *dst, size_t dst_len) const;
+
+ size_t
+ GetSTDERR (char *dst, size_t dst_len) const;
+
+ size_t
+ GetAsyncProfileData(char *dst, size_t dst_len) const;
+
+ void
+ ReportEventState (const lldb::SBEvent &event, FILE *out) const;
+
+ void
+ AppendEventStateReport (const lldb::SBEvent &event, lldb::SBCommandReturnObject &result);
+
+ //------------------------------------------------------------------
+ /// Remote connection related functions. These will fail if the
+ /// process is not in eStateConnected. They are intended for use
+ /// when connecting to an externally managed debugserver instance.
+ //------------------------------------------------------------------
+ bool
+ RemoteAttachToProcessWithID (lldb::pid_t pid,
+ lldb::SBError& error);
+
+ bool
+ RemoteLaunch (char const **argv,
+ char const **envp,
+ const char *stdin_path,
+ const char *stdout_path,
+ const char *stderr_path,
+ const char *working_directory,
+ uint32_t launch_flags,
+ bool stop_at_entry,
+ lldb::SBError& error);
+
+ //------------------------------------------------------------------
+ // Thread related functions
+ //------------------------------------------------------------------
+ uint32_t
+ GetNumThreads ();
+
+ lldb::SBThread
+ GetThreadAtIndex (size_t index);
+
+ lldb::SBThread
+ GetThreadByID (lldb::tid_t sb_thread_id);
+
+ lldb::SBThread
+ GetThreadByIndexID (uint32_t index_id);
+
+ lldb::SBThread
+ GetSelectedThread () const;
+
+ //------------------------------------------------------------------
+ // Function for lazily creating a thread using the current OS
+ // plug-in. This function will be removed in the future when there
+ // are APIs to create SBThread objects through the interface and add
+ // them to the process through the SBProcess API.
+ //------------------------------------------------------------------
+ lldb::SBThread
+ CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context);
+
+ bool
+ SetSelectedThread (const lldb::SBThread &thread);
+
+ bool
+ SetSelectedThreadByID (lldb::tid_t tid);
+
+ bool
+ SetSelectedThreadByIndexID (uint32_t index_id);
+
+ //------------------------------------------------------------------
+ // Stepping related functions
+ //------------------------------------------------------------------
+
+ lldb::StateType
+ GetState ();
+
+ int
+ GetExitStatus ();
+
+ const char *
+ GetExitDescription ();
+
+ //------------------------------------------------------------------
+ /// Gets the process ID
+ ///
+ /// Returns the process identifier for the process as it is known
+ /// on the system on which the process is running. For unix systems
+ /// this is typically the same as if you called "getpid()" in the
+ /// process.
+ ///
+ /// @return
+ /// Returns LLDB_INVALID_PROCESS_ID if this object does not
+ /// contain a valid process object, or if the process has not
+ /// been launched. Returns a valid process ID if the process is
+ /// valid.
+ //------------------------------------------------------------------
+ lldb::pid_t
+ GetProcessID ();
+
+ //------------------------------------------------------------------
+ /// Gets the unique ID associated with this process object
+ ///
+ /// Unique IDs start at 1 and increment up with each new process
+ /// instance. Since starting a process on a system might always
+ /// create a process with the same process ID, there needs to be a
+ /// way to tell two process instances apart.
+ ///
+ /// @return
+ /// Returns a non-zero integer ID if this object contains a
+ /// valid process object, zero if this object does not contain
+ /// a valid process object.
+ //------------------------------------------------------------------
+ uint32_t
+ GetUniqueID();
+
+ uint32_t
+ GetAddressByteSize() const;
+
+ lldb::SBError
+ Destroy ();
+
+ lldb::SBError
+ Continue ();
+
+ lldb::SBError
+ Stop ();
+
+ lldb::SBError
+ Kill ();
+
+ lldb::SBError
+ Detach ();
+
+ lldb::SBError
+ Detach (bool keep_stopped);
+
+ lldb::SBError
+ Signal (int signal);
+
+ void
+ SendAsyncInterrupt();
+
+ uint32_t
+ GetStopID(bool include_expression_stops = false);
+
+ size_t
+ ReadMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error);
+
+ size_t
+ WriteMemory (addr_t addr, const void *buf, size_t size, lldb::SBError &error);
+
+ size_t
+ ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error);
+
+ uint64_t
+ ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &error);
+
+ lldb::addr_t
+ ReadPointerFromMemory (addr_t addr, lldb::SBError &error);
+
+ // Events
+ static lldb::StateType
+ GetStateFromEvent (const lldb::SBEvent &event);
+
+ static bool
+ GetRestartedFromEvent (const lldb::SBEvent &event);
+
+ static size_t
+ GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event);
+
+ static const char *
+ GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx);
+
+ static lldb::SBProcess
+ GetProcessFromEvent (const lldb::SBEvent &event);
+
+ static bool
+ EventIsProcessEvent (const lldb::SBEvent &event);
+
+ lldb::SBBroadcaster
+ GetBroadcaster () const;
+
+ static const char *
+ GetBroadcasterClass ();
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ uint32_t
+ GetNumSupportedHardwareWatchpoints (lldb::SBError &error) const;
+
+ uint32_t
+ LoadImage (lldb::SBFileSpec &image_spec, lldb::SBError &error);
+
+ lldb::SBError
+ UnloadImage (uint32_t image_token);
+
+protected:
+ friend class SBAddress;
+ friend class SBBreakpoint;
+ friend class SBBreakpointLocation;
+ friend class SBCommandInterpreter;
+ friend class SBDebugger;
+ friend class SBFunction;
+ friend class SBModule;
+ friend class SBTarget;
+ friend class SBThread;
+ friend class SBValue;
+
+ lldb::ProcessSP
+ GetSP() const;
+
+ void
+ SetSP (const lldb::ProcessSP &process_sp);
+
+ lldb::ProcessWP m_opaque_wp;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBProcess_h_
diff --git a/include/lldb/API/SBSection.h b/include/lldb/API/SBSection.h
new file mode 100644
index 000000000000..3386484f6496
--- /dev/null
+++ b/include/lldb/API/SBSection.h
@@ -0,0 +1,104 @@
+//===-- SBSection.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBSection_h_
+#define LLDB_SBSection_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBData.h"
+
+namespace lldb {
+
+class SBSection
+{
+public:
+
+ SBSection ();
+
+ SBSection (const lldb::SBSection &rhs);
+
+ ~SBSection ();
+
+ const lldb::SBSection &
+ operator = (const lldb::SBSection &rhs);
+
+ bool
+ IsValid () const;
+
+ const char *
+ GetName ();
+
+ lldb::SBSection
+ GetParent();
+
+ lldb::SBSection
+ FindSubSection (const char *sect_name);
+
+ size_t
+ GetNumSubSections ();
+
+ lldb::SBSection
+ GetSubSectionAtIndex (size_t idx);
+
+ lldb::addr_t
+ GetFileAddress ();
+
+ lldb::addr_t
+ GetLoadAddress (lldb::SBTarget &target);
+
+ lldb::addr_t
+ GetByteSize ();
+
+ uint64_t
+ GetFileOffset ();
+
+ uint64_t
+ GetFileByteSize ();
+
+ lldb::SBData
+ GetSectionData ();
+
+ lldb::SBData
+ GetSectionData (uint64_t offset,
+ uint64_t size);
+
+ SectionType
+ GetSectionType ();
+
+ bool
+ operator == (const lldb::SBSection &rhs);
+
+ bool
+ operator != (const lldb::SBSection &rhs);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+
+private:
+
+ friend class SBAddress;
+ friend class SBModule;
+ friend class SBTarget;
+
+ SBSection (const lldb::SectionSP &section_sp);
+
+ lldb::SectionSP
+ GetSP() const;
+
+ void
+ SetSP(const lldb::SectionSP &section_sp);
+
+ lldb::SectionWP m_opaque_wp;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBSection_h_
diff --git a/include/lldb/API/SBSourceManager.h b/include/lldb/API/SBSourceManager.h
new file mode 100644
index 000000000000..5b52c49ff3ee
--- /dev/null
+++ b/include/lldb/API/SBSourceManager.h
@@ -0,0 +1,53 @@
+//===-- SBSourceManager.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBSourceManager_h_
+#define LLDB_SBSourceManager_h_
+
+#include "lldb/API/SBDefines.h"
+
+#include <stdio.h>
+
+namespace lldb {
+
+class SBSourceManager
+{
+public:
+ SBSourceManager (const SBDebugger &debugger);
+ SBSourceManager (const SBTarget &target);
+ SBSourceManager (const SBSourceManager &rhs);
+
+ ~SBSourceManager();
+
+ const lldb::SBSourceManager &
+ operator = (const lldb::SBSourceManager &rhs);
+
+ size_t
+ DisplaySourceLinesWithLineNumbers (const lldb::SBFileSpec &file,
+ uint32_t line,
+ uint32_t context_before,
+ uint32_t context_after,
+ const char* current_line_cstr,
+ lldb::SBStream &s);
+
+
+protected:
+ friend class SBCommandInterpreter;
+ friend class SBDebugger;
+
+ SBSourceManager(lldb_private::SourceManager *source_manager);
+
+private:
+
+ std::unique_ptr<lldb_private::SourceManagerImpl> m_opaque_ap;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBSourceManager_h_
diff --git a/include/lldb/API/SBStream.h b/include/lldb/API/SBStream.h
new file mode 100644
index 000000000000..038adf68542c
--- /dev/null
+++ b/include/lldb/API/SBStream.h
@@ -0,0 +1,111 @@
+//===-- SBStream.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBStream_h_
+#define LLDB_SBStream_h_
+
+#include <stdio.h>
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBStream
+{
+public:
+
+ SBStream ();
+
+ ~SBStream ();
+
+ bool
+ IsValid() const;
+
+ // If this stream is not redirected to a file, it will maintain a local
+ // cache for the stream data which can be accessed using this accessor.
+ const char *
+ GetData ();
+
+ // If this stream is not redirected to a file, it will maintain a local
+ // cache for the stream output whose length can be accessed using this
+ // accessor.
+ size_t
+ GetSize();
+
+ void
+ Printf (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ RedirectToFile (const char *path, bool append);
+
+ void
+ RedirectToFileHandle (FILE *fh, bool transfer_fh_ownership);
+
+ void
+ RedirectToFileDescriptor (int fd, bool transfer_fh_ownership);
+
+ // If the stream is redirected to a file, forget about the file and if
+ // ownership of the file was transfered to this object, close the file.
+ // If the stream is backed by a local cache, clear this cache.
+ void
+ Clear ();
+
+protected:
+ friend class SBAddress;
+ friend class SBBlock;
+ friend class SBBreakpoint;
+ friend class SBBreakpointLocation;
+ friend class SBCommandReturnObject;
+ friend class SBCompileUnit;
+ friend class SBData;
+ friend class SBDebugger;
+ friend class SBDeclaration;
+ friend class SBEvent;
+ friend class SBFileSpec;
+ friend class SBFileSpecList;
+ friend class SBFrame;
+ friend class SBFunction;
+ friend class SBInstruction;
+ friend class SBInstructionList;
+ friend class SBLineEntry;
+ friend class SBModule;
+ friend class SBModuleSpec;
+ friend class SBModuleSpecList;
+ friend class SBProcess;
+ friend class SBSection;
+ friend class SBSourceManager;
+ friend class SBSymbol;
+ friend class SBSymbolContext;
+ friend class SBSymbolContextList;
+ friend class SBTarget;
+ friend class SBThread;
+ friend class SBType;
+ friend class SBTypeMember;
+ friend class SBValue;
+ friend class SBWatchpoint;
+
+ lldb_private::Stream *
+ operator->();
+
+ lldb_private::Stream *
+ get();
+
+ lldb_private::Stream &
+ ref();
+
+private:
+
+ DISALLOW_COPY_AND_ASSIGN (SBStream);
+ std::unique_ptr<lldb_private::Stream> m_opaque_ap;
+ bool m_is_file;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBStream_h_
diff --git a/include/lldb/API/SBStringList.h b/include/lldb/API/SBStringList.h
new file mode 100644
index 000000000000..9d0be6e8a741
--- /dev/null
+++ b/include/lldb/API/SBStringList.h
@@ -0,0 +1,71 @@
+//===-- SBStringList.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBStringList_h_
+#define LLDB_SBStringList_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBStringList
+{
+public:
+
+ SBStringList ();
+
+ SBStringList (const lldb::SBStringList &rhs);
+
+ const SBStringList &
+ operator = (const SBStringList &rhs);
+
+ ~SBStringList ();
+
+ bool
+ IsValid() const;
+
+ void
+ AppendString (const char *str);
+
+ void
+ AppendList (const char **strv, int strc);
+
+ void
+ AppendList (const lldb::SBStringList &strings);
+
+ uint32_t
+ GetSize () const;
+
+ const char *
+ GetStringAtIndex (size_t idx);
+
+ void
+ Clear ();
+
+protected:
+ friend class SBCommandInterpreter;
+ friend class SBDebugger;
+
+ SBStringList (const lldb_private::StringList *lldb_strings);
+
+ const lldb_private::StringList *
+ operator->() const;
+
+ const lldb_private::StringList &
+ operator*() const;
+
+private:
+
+ std::unique_ptr<lldb_private::StringList> m_opaque_ap;
+
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBStringList_h_
diff --git a/include/lldb/API/SBSymbol.h b/include/lldb/API/SBSymbol.h
new file mode 100644
index 000000000000..0a528a9ac96f
--- /dev/null
+++ b/include/lldb/API/SBSymbol.h
@@ -0,0 +1,109 @@
+//===-- SBSymbol.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBSymbol_h_
+#define LLDB_SBSymbol_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBAddress.h"
+#include "lldb/API/SBInstructionList.h"
+#include "lldb/API/SBTarget.h"
+
+namespace lldb {
+
+class SBSymbol
+{
+public:
+
+ SBSymbol ();
+
+ ~SBSymbol ();
+
+ SBSymbol (const lldb::SBSymbol &rhs);
+
+ const lldb::SBSymbol &
+ operator = (const lldb::SBSymbol &rhs);
+
+ bool
+ IsValid () const;
+
+
+ const char *
+ GetName() const;
+
+ const char *
+ GetMangledName () const;
+
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target);
+
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target, const char *flavor_string);
+
+ SBAddress
+ GetStartAddress ();
+
+ SBAddress
+ GetEndAddress ();
+
+ uint32_t
+ GetPrologueByteSize ();
+
+ SymbolType
+ GetType ();
+
+ bool
+ operator == (const lldb::SBSymbol &rhs) const;
+
+ bool
+ operator != (const lldb::SBSymbol &rhs) const;
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ //----------------------------------------------------------------------
+ // Returns true if the symbol is externally visible in the module that
+ // it is defined in
+ //----------------------------------------------------------------------
+ bool
+ IsExternal();
+
+ //----------------------------------------------------------------------
+ // Returns true if the symbol was synthetically generated from something
+ // other than the actual symbol table itself in the object file.
+ //----------------------------------------------------------------------
+ bool
+ IsSynthetic();
+
+protected:
+
+ lldb_private::Symbol *
+ get ();
+
+ void
+ reset (lldb_private::Symbol *);
+
+private:
+ friend class SBAddress;
+ friend class SBFrame;
+ friend class SBModule;
+ friend class SBSymbolContext;
+
+ SBSymbol (lldb_private::Symbol *lldb_object_ptr);
+
+ void
+ SetSymbol (lldb_private::Symbol *lldb_object_ptr);
+
+ lldb_private::Symbol *m_opaque_ptr;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBSymbol_h_
diff --git a/include/lldb/API/SBSymbolContext.h b/include/lldb/API/SBSymbolContext.h
new file mode 100644
index 000000000000..fee2d19179d0
--- /dev/null
+++ b/include/lldb/API/SBSymbolContext.h
@@ -0,0 +1,94 @@
+//===-- SBSymbolContext.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBSymbolContext_h_
+#define LLDB_SBSymbolContext_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBBlock.h"
+#include "lldb/API/SBCompileUnit.h"
+#include "lldb/API/SBFunction.h"
+#include "lldb/API/SBLineEntry.h"
+#include "lldb/API/SBModule.h"
+#include "lldb/API/SBSymbol.h"
+
+namespace lldb {
+
+class SBSymbolContext
+{
+public:
+ SBSymbolContext ();
+
+ SBSymbolContext (const lldb::SBSymbolContext& rhs);
+
+ ~SBSymbolContext ();
+
+ bool
+ IsValid () const;
+
+ const lldb::SBSymbolContext &
+ operator = (const lldb::SBSymbolContext &rhs);
+
+ lldb::SBModule GetModule ();
+ lldb::SBCompileUnit GetCompileUnit ();
+ lldb::SBFunction GetFunction ();
+ lldb::SBBlock GetBlock ();
+ lldb::SBLineEntry GetLineEntry ();
+ lldb::SBSymbol GetSymbol ();
+
+ void SetModule (lldb::SBModule module);
+ void SetCompileUnit (lldb::SBCompileUnit compile_unit);
+ void SetFunction (lldb::SBFunction function);
+ void SetBlock (lldb::SBBlock block);
+ void SetLineEntry (lldb::SBLineEntry line_entry);
+ void SetSymbol (lldb::SBSymbol symbol);
+
+ SBSymbolContext
+ GetParentOfInlinedScope (const SBAddress &curr_frame_pc,
+ SBAddress &parent_frame_addr) const;
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+protected:
+ friend class SBAddress;
+ friend class SBFrame;
+ friend class SBModule;
+ friend class SBThread;
+ friend class SBTarget;
+ friend class SBSymbolContextList;
+
+ lldb_private::SymbolContext*
+ operator->() const;
+
+ lldb_private::SymbolContext&
+ operator*();
+
+ lldb_private::SymbolContext&
+ ref();
+
+ const lldb_private::SymbolContext&
+ operator*() const;
+
+ lldb_private::SymbolContext *
+ get() const;
+
+ SBSymbolContext (const lldb_private::SymbolContext *sc_ptr);
+
+ void
+ SetSymbolContext (const lldb_private::SymbolContext *sc_ptr);
+
+private:
+ std::unique_ptr<lldb_private::SymbolContext> m_opaque_ap;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBSymbolContext_h_
diff --git a/include/lldb/API/SBSymbolContextList.h b/include/lldb/API/SBSymbolContextList.h
new file mode 100644
index 000000000000..6cc78e472c6f
--- /dev/null
+++ b/include/lldb/API/SBSymbolContextList.h
@@ -0,0 +1,69 @@
+//===-- SBSymbolContextList.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBSymbolContextList_h_
+#define LLDB_SBSymbolContextList_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBSymbolContext.h"
+
+namespace lldb {
+
+class SBSymbolContextList
+{
+public:
+ SBSymbolContextList ();
+
+ SBSymbolContextList (const lldb::SBSymbolContextList& rhs);
+
+ ~SBSymbolContextList ();
+
+ const lldb::SBSymbolContextList &
+ operator = (const lldb::SBSymbolContextList &rhs);
+
+ bool
+ IsValid () const;
+
+ uint32_t
+ GetSize() const;
+
+ lldb::SBSymbolContext
+ GetContextAtIndex (uint32_t idx);
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ void
+ Append (lldb::SBSymbolContext &sc);
+
+ void
+ Append (lldb::SBSymbolContextList &sc_list);
+
+ void
+ Clear();
+
+protected:
+
+ friend class SBModule;
+ friend class SBTarget;
+
+ lldb_private::SymbolContextList*
+ operator->() const;
+
+ lldb_private::SymbolContextList&
+ operator*() const;
+
+private:
+ std::unique_ptr<lldb_private::SymbolContextList> m_opaque_ap;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBSymbolContextList_h_
diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h
new file mode 100644
index 000000000000..15aeed4b600c
--- /dev/null
+++ b/include/lldb/API/SBTarget.h
@@ -0,0 +1,828 @@
+//===-- SBTarget.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBTarget_h_
+#define LLDB_SBTarget_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBAddress.h"
+#include "lldb/API/SBBroadcaster.h"
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBFileSpecList.h"
+#include "lldb/API/SBSymbolContextList.h"
+#include "lldb/API/SBType.h"
+#include "lldb/API/SBValue.h"
+#include "lldb/API/SBWatchpoint.h"
+
+namespace lldb {
+
+class SBLaunchInfo
+{
+public:
+ SBLaunchInfo (const char **argv);
+
+ ~SBLaunchInfo();
+
+ uint32_t
+ GetUserID();
+
+ uint32_t
+ GetGroupID();
+
+ bool
+ UserIDIsValid ();
+
+ bool
+ GroupIDIsValid ();
+
+ void
+ SetUserID (uint32_t uid);
+
+ void
+ SetGroupID (uint32_t gid);
+
+ uint32_t
+ GetNumArguments ();
+
+ const char *
+ GetArgumentAtIndex (uint32_t idx);
+
+ void
+ SetArguments (const char **argv, bool append);
+
+ uint32_t
+ GetNumEnvironmentEntries ();
+
+ const char *
+ GetEnvironmentEntryAtIndex (uint32_t idx);
+
+ void
+ SetEnvironmentEntries (const char **envp, bool append);
+
+ void
+ Clear ();
+
+ const char *
+ GetWorkingDirectory () const;
+
+ void
+ SetWorkingDirectory (const char *working_dir);
+
+ uint32_t
+ GetLaunchFlags ();
+
+ void
+ SetLaunchFlags (uint32_t flags);
+
+ const char *
+ GetProcessPluginName ();
+
+ void
+ SetProcessPluginName (const char *plugin_name);
+
+ const char *
+ GetShell ();
+
+ void
+ SetShell (const char * path);
+
+ uint32_t
+ GetResumeCount ();
+
+ void
+ SetResumeCount (uint32_t c);
+
+ bool
+ AddCloseFileAction (int fd);
+
+ bool
+ AddDuplicateFileAction (int fd, int dup_fd);
+
+ bool
+ AddOpenFileAction (int fd, const char *path, bool read, bool write);
+
+ bool
+ AddSuppressFileAction (int fd, bool read, bool write);
+
+protected:
+ friend class SBTarget;
+
+ lldb_private::ProcessLaunchInfo &
+ ref ();
+
+ ProcessLaunchInfoSP m_opaque_sp;
+};
+
+class SBAttachInfo
+{
+public:
+ SBAttachInfo ();
+
+ SBAttachInfo (lldb::pid_t pid);
+
+ SBAttachInfo (const char *path, bool wait_for);
+
+ SBAttachInfo (const SBAttachInfo &rhs);
+
+ ~SBAttachInfo();
+
+ SBAttachInfo &
+ operator = (const SBAttachInfo &rhs);
+
+ lldb::pid_t
+ GetProcessID ();
+
+ void
+ SetProcessID (lldb::pid_t pid);
+
+ void
+ SetExecutable (const char *path);
+
+ void
+ SetExecutable (lldb::SBFileSpec exe_file);
+
+ bool
+ GetWaitForLaunch ();
+
+ void
+ SetWaitForLaunch (bool b);
+
+ bool
+ GetIgnoreExisting ();
+
+ void
+ SetIgnoreExisting (bool b);
+
+ uint32_t
+ GetResumeCount ();
+
+ void
+ SetResumeCount (uint32_t c);
+
+ const char *
+ GetProcessPluginName ();
+
+ void
+ SetProcessPluginName (const char *plugin_name);
+
+ uint32_t
+ GetUserID();
+
+ uint32_t
+ GetGroupID();
+
+ bool
+ UserIDIsValid ();
+
+ bool
+ GroupIDIsValid ();
+
+ void
+ SetUserID (uint32_t uid);
+
+ void
+ SetGroupID (uint32_t gid);
+
+ uint32_t
+ GetEffectiveUserID();
+
+ uint32_t
+ GetEffectiveGroupID();
+
+ bool
+ EffectiveUserIDIsValid ();
+
+ bool
+ EffectiveGroupIDIsValid ();
+
+ void
+ SetEffectiveUserID (uint32_t uid);
+
+ void
+ SetEffectiveGroupID (uint32_t gid);
+
+ lldb::pid_t
+ GetParentProcessID ();
+
+ void
+ SetParentProcessID (lldb::pid_t pid);
+
+ bool
+ ParentProcessIDIsValid();
+
+
+protected:
+ friend class SBTarget;
+
+ lldb_private::ProcessAttachInfo &
+ ref ();
+
+ ProcessAttachInfoSP m_opaque_sp;
+};
+
+class SBTarget
+{
+public:
+ //------------------------------------------------------------------
+ // Broadcaster bits.
+ //------------------------------------------------------------------
+ enum
+ {
+ eBroadcastBitBreakpointChanged = (1 << 0),
+ eBroadcastBitModulesLoaded = (1 << 1),
+ eBroadcastBitModulesUnloaded = (1 << 2),
+ eBroadcastBitWatchpointChanged = (1 << 3),
+ eBroadcastBitSymbolsLoaded = (1 << 4)
+ };
+
+ //------------------------------------------------------------------
+ // Constructors
+ //------------------------------------------------------------------
+ SBTarget ();
+
+ SBTarget (const lldb::SBTarget& rhs);
+
+ SBTarget (const lldb::TargetSP& target_sp);
+
+ const lldb::SBTarget&
+ operator = (const lldb::SBTarget& rhs);
+
+ //------------------------------------------------------------------
+ // Destructor
+ //------------------------------------------------------------------
+ ~SBTarget();
+
+ bool
+ IsValid() const;
+
+ static const char *
+ GetBroadcasterClassName ();
+
+ lldb::SBProcess
+ GetProcess ();
+
+ //------------------------------------------------------------------
+ /// Launch a new process.
+ ///
+ /// Launch a new process by spawning a new process using the
+ /// target object's executable module's file as the file to launch.
+ /// Arguments are given in \a argv, and the environment variables
+ /// are in \a envp. Standard input and output files can be
+ /// optionally re-directed to \a stdin_path, \a stdout_path, and
+ /// \a stderr_path.
+ ///
+ /// @param[in] listener
+ /// An optional listener that will receive all process events.
+ /// If \a listener is valid then \a listener will listen to all
+ /// process events. If not valid, then this target's debugger
+ /// (SBTarget::GetDebugger()) will listen to all process events.
+ ///
+ /// @param[in] argv
+ /// The argument array.
+ ///
+ /// @param[in] envp
+ /// The environment array.
+ ///
+ /// @param[in] launch_flags
+ /// Flags to modify the launch (@see lldb::LaunchFlags)
+ ///
+ /// @param[in] stdin_path
+ /// The path to use when re-directing the STDIN of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] stdout_path
+ /// The path to use when re-directing the STDOUT of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] stderr_path
+ /// The path to use when re-directing the STDERR of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] working_directory
+ /// The working directory to have the child process run in
+ ///
+ /// @param[in] launch_flags
+ /// Some launch options specified by logical OR'ing
+ /// lldb::LaunchFlags enumeration values together.
+ ///
+ /// @param[in] stop_at_endtry
+ /// If false do not stop the inferior at the entry point.
+ ///
+ /// @param[out]
+ /// An error object. Contains the reason if there is some failure.
+ ///
+ /// @return
+ /// A process object for the newly created process.
+ //------------------------------------------------------------------
+ lldb::SBProcess
+ Launch (SBListener &listener,
+ char const **argv,
+ char const **envp,
+ const char *stdin_path,
+ const char *stdout_path,
+ const char *stderr_path,
+ const char *working_directory,
+ uint32_t launch_flags, // See LaunchFlags
+ bool stop_at_entry,
+ lldb::SBError& error);
+
+
+ //------------------------------------------------------------------
+ /// Launch a new process with sensible defaults.
+ ///
+ /// @param[in] argv
+ /// The argument array.
+ ///
+ /// @param[in] envp
+ /// The environment array.
+ ///
+ /// @param[in] working_directory
+ /// The working directory to have the child process run in
+ ///
+ /// Default: listener
+ /// Set to the target's debugger (SBTarget::GetDebugger())
+ ///
+ /// Default: launch_flags
+ /// Empty launch flags
+ ///
+ /// Default: stdin_path
+ /// Default: stdout_path
+ /// Default: stderr_path
+ /// A pseudo terminal will be used.
+ ///
+ /// @return
+ /// A process object for the newly created process.
+ //------------------------------------------------------------------
+ SBProcess
+ LaunchSimple (const char **argv,
+ const char **envp,
+ const char *working_directory);
+
+ SBProcess
+ Launch (SBLaunchInfo &launch_info, SBError& error);
+
+ SBProcess
+ LoadCore (const char *core_file);
+
+ SBProcess
+ Attach (SBAttachInfo &attach_info, SBError& error);
+
+ //------------------------------------------------------------------
+ /// Attach to process with pid.
+ ///
+ /// @param[in] listener
+ /// An optional listener that will receive all process events.
+ /// If \a listener is valid then \a listener will listen to all
+ /// process events. If not valid, then this target's debugger
+ /// (SBTarget::GetDebugger()) will listen to all process events.
+ ///
+ /// @param[in] pid
+ /// The process ID to attach to.
+ ///
+ /// @param[out]
+ /// An error explaining what went wrong if attach fails.
+ ///
+ /// @return
+ /// A process object for the attached process.
+ //------------------------------------------------------------------
+ lldb::SBProcess
+ AttachToProcessWithID (SBListener &listener,
+ lldb::pid_t pid,
+ lldb::SBError& error);
+
+#if defined(__APPLE__)
+ // We need to keep this around for a build or two since Xcode links
+ // to the 32 bit version of this function. We will take it out soon.
+ lldb::SBProcess
+ AttachToProcessWithID (SBListener &listener,
+ ::pid_t pid, // 32 bit int process ID
+ lldb::SBError& error); // DEPRECATED
+#endif
+ //------------------------------------------------------------------
+ /// Attach to process with name.
+ ///
+ /// @param[in] listener
+ /// An optional listener that will receive all process events.
+ /// If \a listener is valid then \a listener will listen to all
+ /// process events. If not valid, then this target's debugger
+ /// (SBTarget::GetDebugger()) will listen to all process events.
+ ///
+ /// @param[in] name
+ /// Basename of process to attach to.
+ ///
+ /// @param[in] wait_for
+ /// If true wait for a new instance of 'name' to be launched.
+ ///
+ /// @param[out]
+ /// An error explaining what went wrong if attach fails.
+ ///
+ /// @return
+ /// A process object for the attached process.
+ //------------------------------------------------------------------
+ lldb::SBProcess
+ AttachToProcessWithName (SBListener &listener,
+ const char *name,
+ bool wait_for,
+ lldb::SBError& error);
+
+ //------------------------------------------------------------------
+ /// Connect to a remote debug server with url.
+ ///
+ /// @param[in] listener
+ /// An optional listener that will receive all process events.
+ /// If \a listener is valid then \a listener will listen to all
+ /// process events. If not valid, then this target's debugger
+ /// (SBTarget::GetDebugger()) will listen to all process events.
+ ///
+ /// @param[in] url
+ /// The url to connect to, e.g., 'connect://localhost:12345'.
+ ///
+ /// @param[in] plugin_name
+ /// The plugin name to be used; can be NULL.
+ ///
+ /// @param[out]
+ /// An error explaining what went wrong if the connect fails.
+ ///
+ /// @return
+ /// A process object for the connected process.
+ //------------------------------------------------------------------
+ lldb::SBProcess
+ ConnectRemote (SBListener &listener,
+ const char *url,
+ const char *plugin_name,
+ SBError& error);
+
+ lldb::SBFileSpec
+ GetExecutable ();
+
+ bool
+ AddModule (lldb::SBModule &module);
+
+ lldb::SBModule
+ AddModule (const char *path,
+ const char *triple,
+ const char *uuid);
+
+ lldb::SBModule
+ AddModule (const char *path,
+ const char *triple,
+ const char *uuid_cstr,
+ const char *symfile);
+
+ lldb::SBModule
+ AddModule (const SBModuleSpec &module_spec);
+
+ uint32_t
+ GetNumModules () const;
+
+ lldb::SBModule
+ GetModuleAtIndex (uint32_t idx);
+
+ bool
+ RemoveModule (lldb::SBModule module);
+
+ lldb::SBDebugger
+ GetDebugger() const;
+
+ lldb::SBModule
+ FindModule (const lldb::SBFileSpec &file_spec);
+
+ lldb::ByteOrder
+ GetByteOrder ();
+
+ uint32_t
+ GetAddressByteSize();
+
+ const char *
+ GetTriple ();
+
+ //------------------------------------------------------------------
+ /// Set the base load address for a module section.
+ ///
+ /// @param[in] section
+ /// The section whose base load address will be set within this
+ /// target.
+ ///
+ /// @param[in] section_base_addr
+ /// The base address for the section.
+ ///
+ /// @return
+ /// An error to indicate success, fail, and any reason for
+ /// failure.
+ //------------------------------------------------------------------
+ lldb::SBError
+ SetSectionLoadAddress (lldb::SBSection section,
+ lldb::addr_t section_base_addr);
+
+ //------------------------------------------------------------------
+ /// Clear the base load address for a module section.
+ ///
+ /// @param[in] section
+ /// The section whose base load address will be cleared within
+ /// this target.
+ ///
+ /// @return
+ /// An error to indicate success, fail, and any reason for
+ /// failure.
+ //------------------------------------------------------------------
+ lldb::SBError
+ ClearSectionLoadAddress (lldb::SBSection section);
+
+ //------------------------------------------------------------------
+ /// Slide all file addresses for all module sections so that \a module
+ /// appears to loaded at these slide addresses.
+ ///
+ /// When you need all sections within a module to be loaded at a
+ /// rigid slide from the addresses found in the module object file,
+ /// this function will allow you to easily and quickly slide all
+ /// module sections.
+ ///
+ /// @param[in] module
+ /// The module to load.
+ ///
+ /// @param[in] sections_offset
+ /// An offset that will be applied to all section file addresses
+ /// (the virtual addresses found in the object file itself).
+ ///
+ /// @return
+ /// An error to indicate success, fail, and any reason for
+ /// failure.
+ //------------------------------------------------------------------
+ lldb::SBError
+ SetModuleLoadAddress (lldb::SBModule module,
+ int64_t sections_offset);
+
+
+ //------------------------------------------------------------------
+ /// The the section base load addresses for all sections in a module.
+ ///
+ /// @param[in] module
+ /// The module to unload.
+ ///
+ /// @return
+ /// An error to indicate success, fail, and any reason for
+ /// failure.
+ //------------------------------------------------------------------
+ lldb::SBError
+ ClearModuleLoadAddress (lldb::SBModule module);
+
+ //------------------------------------------------------------------
+ /// Find functions by name.
+ ///
+ /// @param[in] name
+ /// The name of the function we are looking for.
+ ///
+ /// @param[in] name_type_mask
+ /// A logical OR of one or more FunctionNameType enum bits that
+ /// indicate what kind of names should be used when doing the
+ /// lookup. Bits include fully qualified names, base names,
+ /// C++ methods, or ObjC selectors.
+ /// See FunctionNameType for more details.
+ ///
+ /// @return
+ /// A lldb::SBSymbolContextList that gets filled in with all of
+ /// the symbol contexts for all the matches.
+ //------------------------------------------------------------------
+ lldb::SBSymbolContextList
+ FindFunctions (const char *name,
+ uint32_t name_type_mask = lldb::eFunctionNameTypeAny);
+
+ //------------------------------------------------------------------
+ /// Find global and static variables by name.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @param[in] max_matches
+ /// Allow the number of matches to be limited to \a max_matches.
+ ///
+ /// @return
+ /// A list of matched variables in an SBValueList.
+ //------------------------------------------------------------------
+ lldb::SBValueList
+ FindGlobalVariables (const char *name,
+ uint32_t max_matches);
+
+ //------------------------------------------------------------------
+ /// Find the first global (or static) variable by name.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @return
+ /// An SBValue that gets filled in with the found variable (if any).
+ //------------------------------------------------------------------
+ lldb::SBValue
+ FindFirstGlobalVariable (const char* name);
+
+ void
+ Clear ();
+
+ lldb::SBAddress
+ ResolveLoadAddress (lldb::addr_t vm_addr);
+
+ SBSymbolContext
+ ResolveSymbolContextForAddress (const SBAddress& addr,
+ uint32_t resolve_scope);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByLocation (const char *file, uint32_t line);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL);
+
+ // This version uses name_type_mask = eFunctionNameTypeAuto
+ lldb::SBBreakpoint
+ BreakpointCreateByName (const char *symbol_name,
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &comp_unit_list);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByName (const char *symbol_name,
+ uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &comp_unit_list);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByNames (const char *symbol_name[],
+ uint32_t num_names,
+ uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &comp_unit_list);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = NULL);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByRegex (const char *symbol_name_regex,
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &comp_unit_list);
+
+ lldb::SBBreakpoint
+ BreakpointCreateBySourceRegex (const char *source_regex,
+ const lldb::SBFileSpec &source_file,
+ const char *module_name = NULL);
+
+ lldb::SBBreakpoint
+ BreakpointCreateBySourceRegex (const char *source_regex,
+ const SBFileSpecList &module_list,
+ const lldb::SBFileSpecList &source_file);
+
+ lldb::SBBreakpoint
+ BreakpointCreateForException (lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByAddress (addr_t address);
+
+ uint32_t
+ GetNumBreakpoints () const;
+
+ lldb::SBBreakpoint
+ GetBreakpointAtIndex (uint32_t idx) const;
+
+ bool
+ BreakpointDelete (break_id_t break_id);
+
+ lldb::SBBreakpoint
+ FindBreakpointByID (break_id_t break_id);
+
+ bool
+ EnableAllBreakpoints ();
+
+ bool
+ DisableAllBreakpoints ();
+
+ bool
+ DeleteAllBreakpoints ();
+
+ uint32_t
+ GetNumWatchpoints () const;
+
+ lldb::SBWatchpoint
+ GetWatchpointAtIndex (uint32_t idx) const;
+
+ bool
+ DeleteWatchpoint (lldb::watch_id_t watch_id);
+
+ lldb::SBWatchpoint
+ FindWatchpointByID (lldb::watch_id_t watch_id);
+
+ lldb::SBWatchpoint
+ WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError& error);
+
+ bool
+ EnableAllWatchpoints ();
+
+ bool
+ DisableAllWatchpoints ();
+
+ bool
+ DeleteAllWatchpoints ();
+
+ lldb::SBBroadcaster
+ GetBroadcaster () const;
+
+ lldb::SBType
+ FindFirstType (const char* type);
+
+ lldb::SBTypeList
+ FindTypes (const char* type);
+
+ lldb::SBType
+ GetBasicType(lldb::BasicType type);
+
+ SBSourceManager
+ GetSourceManager();
+
+ lldb::SBInstructionList
+ ReadInstructions (lldb::SBAddress base_addr, uint32_t count);
+
+ lldb::SBInstructionList
+ ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string);
+
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size);
+
+ // The "WithFlavor" is necessary to keep SWIG from getting confused about overloaded arguments when
+ // using the buf + size -> Python Object magic.
+
+ lldb::SBInstructionList
+ GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size);
+
+ lldb::SBInstructionList
+ GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size);
+
+ lldb::SBInstructionList
+ GetInstructionsWithFlavor (lldb::addr_t base_addr, const char *flavor_string, const void *buf, size_t size);
+
+ lldb::SBSymbolContextList
+ FindSymbols (const char *name,
+ lldb::SymbolType type = eSymbolTypeAny);
+
+ bool
+ operator == (const lldb::SBTarget &rhs) const;
+
+ bool
+ operator != (const lldb::SBTarget &rhs) const;
+
+ bool
+ GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level);
+
+ lldb::SBValue
+ EvaluateExpression (const char *expr, const SBExpressionOptions &options);
+
+ lldb::addr_t
+ GetStackRedZoneSize();
+
+protected:
+ friend class SBAddress;
+ friend class SBBlock;
+ friend class SBDebugger;
+ friend class SBFunction;
+ friend class SBInstruction;
+ friend class SBModule;
+ friend class SBProcess;
+ friend class SBSection;
+ friend class SBSourceManager;
+ friend class SBSymbol;
+ friend class SBValue;
+
+ //------------------------------------------------------------------
+ // Constructors are private, use static Target::Create function to
+ // create an instance of this class.
+ //------------------------------------------------------------------
+
+ lldb::TargetSP
+ GetSP () const;
+
+ void
+ SetSP (const lldb::TargetSP& target_sp);
+
+
+private:
+ //------------------------------------------------------------------
+ // For Target only
+ //------------------------------------------------------------------
+
+ lldb::TargetSP m_opaque_sp;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBTarget_h_
diff --git a/include/lldb/API/SBThread.h b/include/lldb/API/SBThread.h
new file mode 100644
index 000000000000..9645f925035e
--- /dev/null
+++ b/include/lldb/API/SBThread.h
@@ -0,0 +1,220 @@
+//===-- SBThread.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBThread_h_
+#define LLDB_SBThread_h_
+
+#include "lldb/API/SBDefines.h"
+
+#include <stdio.h>
+
+namespace lldb {
+
+class SBFrame;
+
+class SBThread
+{
+public:
+ enum
+ {
+ eBroadcastBitStackChanged = (1 << 0),
+ eBroadcastBitThreadSuspended = (1 << 1),
+ eBroadcastBitThreadResumed = (1 << 2),
+ eBroadcastBitSelectedFrameChanged = (1 << 3),
+ eBroadcastBitThreadSelected = (1 << 4)
+ };
+
+ static const char *
+ GetBroadcasterClassName ();
+
+ SBThread ();
+
+ SBThread (const lldb::SBThread &thread);
+
+ SBThread (const lldb::ThreadSP& lldb_object_sp);
+
+ ~SBThread();
+
+ bool
+ IsValid() const;
+
+ void
+ Clear ();
+
+ lldb::StopReason
+ GetStopReason();
+
+ /// Get the number of words associated with the stop reason.
+ /// See also GetStopReasonDataAtIndex().
+ size_t
+ GetStopReasonDataCount();
+
+ //--------------------------------------------------------------------------
+ /// Get information associated with a stop reason.
+ ///
+ /// Breakpoint stop reasons will have data that consists of pairs of
+ /// breakpoint IDs followed by the breakpoint location IDs (they always come
+ /// in pairs).
+ ///
+ /// Stop Reason Count Data Type
+ /// ======================== ===== =========================================
+ /// eStopReasonNone 0
+ /// eStopReasonTrace 0
+ /// eStopReasonBreakpoint N duple: {breakpoint id, location id}
+ /// eStopReasonWatchpoint 1 watchpoint id
+ /// eStopReasonSignal 1 unix signal number
+ /// eStopReasonException N exception data
+ /// eStopReasonExec 0
+ /// eStopReasonPlanComplete 0
+ //--------------------------------------------------------------------------
+ uint64_t
+ GetStopReasonDataAtIndex(uint32_t idx);
+
+ size_t
+ GetStopDescription (char *dst, size_t dst_len);
+
+ SBValue
+ GetStopReturnValue ();
+
+ lldb::tid_t
+ GetThreadID () const;
+
+ uint32_t
+ GetIndexID () const;
+
+ const char *
+ GetName () const;
+
+ const char *
+ GetQueueName() const;
+
+ void
+ StepOver (lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
+
+ void
+ StepInto (lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
+
+ void
+ StepInto (const char *target_name, lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
+
+ void
+ StepOut ();
+
+ void
+ StepOutOfFrame (lldb::SBFrame &frame);
+
+ void
+ StepInstruction(bool step_over);
+
+ SBError
+ StepOverUntil (lldb::SBFrame &frame,
+ lldb::SBFileSpec &file_spec,
+ uint32_t line);
+
+ void
+ RunToAddress (lldb::addr_t addr);
+
+ SBError
+ ReturnFromFrame (SBFrame &frame, SBValue &return_value);
+
+ //--------------------------------------------------------------------------
+ /// LLDB currently supports process centric debugging which means when any
+ /// thread in a process stops, all other threads are stopped. The Suspend()
+ /// call here tells our process to suspend a thread and not let it run when
+ /// the other threads in a process are allowed to run. So when
+ /// SBProcess::Continue() is called, any threads that aren't suspended will
+ /// be allowed to run. If any of the SBThread functions for stepping are
+ /// called (StepOver, StepInto, StepOut, StepInstruction, RunToAddres), the
+ /// thread will not be allowed to run and these funtions will simply return.
+ ///
+ /// Eventually we plan to add support for thread centric debugging where
+ /// each thread is controlled individually and each thread would broadcast
+ /// its state, but we haven't implemented this yet.
+ ///
+ /// Likewise the SBThread::Resume() call will again allow the thread to run
+ /// when the process is continued.
+ ///
+ /// Suspend() and Resume() functions are not currently reference counted, if
+ /// anyone has the need for them to be reference counted, please let us
+ /// know.
+ //--------------------------------------------------------------------------
+ bool
+ Suspend();
+
+ bool
+ Resume ();
+
+ bool
+ IsSuspended();
+
+ bool
+ IsStopped();
+
+ uint32_t
+ GetNumFrames ();
+
+ lldb::SBFrame
+ GetFrameAtIndex (uint32_t idx);
+
+ lldb::SBFrame
+ GetSelectedFrame ();
+
+ lldb::SBFrame
+ SetSelectedFrame (uint32_t frame_idx);
+
+ static bool
+ EventIsThreadEvent (const SBEvent &event);
+
+ static SBFrame
+ GetStackFrameFromEvent (const SBEvent &event);
+
+ static SBThread
+ GetThreadFromEvent (const SBEvent &event);
+
+ lldb::SBProcess
+ GetProcess ();
+
+ const lldb::SBThread &
+ operator = (const lldb::SBThread &rhs);
+
+ bool
+ operator == (const lldb::SBThread &rhs) const;
+
+ bool
+ operator != (const lldb::SBThread &rhs) const;
+
+ bool
+ GetDescription (lldb::SBStream &description) const;
+
+ bool
+ GetStatus (lldb::SBStream &status) const;
+
+protected:
+ friend class SBBreakpoint;
+ friend class SBBreakpointLocation;
+ friend class SBFrame;
+ friend class SBProcess;
+ friend class SBDebugger;
+ friend class SBValue;
+
+ void
+ SetThread (const lldb::ThreadSP& lldb_object_sp);
+
+#ifndef SWIG
+ SBError
+ ResumeNewPlan (lldb_private::ExecutionContext &exe_ctx, lldb_private::ThreadPlan *new_plan);
+#endif
+
+private:
+ lldb::ExecutionContextRefSP m_opaque_sp;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBThread_h_
diff --git a/include/lldb/API/SBType.h b/include/lldb/API/SBType.h
new file mode 100644
index 000000000000..3729b2f84b90
--- /dev/null
+++ b/include/lldb/API/SBType.h
@@ -0,0 +1,244 @@
+//===-- SBType.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBType_h_
+#define LLDB_SBType_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBTypeList;
+
+class SBTypeMember
+{
+public:
+ SBTypeMember ();
+
+ SBTypeMember (const lldb::SBTypeMember& rhs);
+
+ ~SBTypeMember();
+
+ lldb::SBTypeMember&
+ operator = (const lldb::SBTypeMember& rhs);
+
+ bool
+ IsValid() const;
+
+ const char *
+ GetName ();
+
+ lldb::SBType
+ GetType ();
+
+ uint64_t
+ GetOffsetInBytes();
+
+ uint64_t
+ GetOffsetInBits();
+
+ bool
+ IsBitfield();
+
+ uint32_t
+ GetBitfieldSizeInBits();
+
+ bool
+ GetDescription (lldb::SBStream &description,
+ lldb::DescriptionLevel description_level);
+
+protected:
+ friend class SBType;
+
+ void
+ reset (lldb_private::TypeMemberImpl *);
+
+ lldb_private::TypeMemberImpl &
+ ref ();
+
+ const lldb_private::TypeMemberImpl &
+ ref () const;
+
+ std::unique_ptr<lldb_private::TypeMemberImpl> m_opaque_ap;
+};
+
+class SBType
+{
+public:
+
+ SBType();
+
+ SBType (const lldb::SBType &rhs);
+
+ ~SBType ();
+
+ bool
+ IsValid() const;
+
+ uint64_t
+ GetByteSize();
+
+ bool
+ IsPointerType();
+
+ bool
+ IsReferenceType();
+
+ bool
+ IsFunctionType ();
+
+ bool
+ IsPolymorphicClass ();
+
+ lldb::SBType
+ GetPointerType();
+
+ lldb::SBType
+ GetPointeeType();
+
+ lldb::SBType
+ GetReferenceType();
+
+ lldb::SBType
+ GetDereferencedType();
+
+ lldb::SBType
+ GetUnqualifiedType();
+
+ lldb::SBType
+ GetCanonicalType();
+ // Get the "lldb::BasicType" enumeration for a type. If a type is not a basic
+ // type eBasicTypeInvalid will be returned
+ lldb::BasicType
+ GetBasicType();
+
+ // The call below confusing and should really be renamed to "CreateBasicType"
+ lldb::SBType
+ GetBasicType(lldb::BasicType type);
+
+ uint32_t
+ GetNumberOfFields ();
+
+ uint32_t
+ GetNumberOfDirectBaseClasses ();
+
+ uint32_t
+ GetNumberOfVirtualBaseClasses ();
+
+ lldb::SBTypeMember
+ GetFieldAtIndex (uint32_t idx);
+
+ lldb::SBTypeMember
+ GetDirectBaseClassAtIndex (uint32_t idx);
+
+ lldb::SBTypeMember
+ GetVirtualBaseClassAtIndex (uint32_t idx);
+
+ uint32_t
+ GetNumberOfTemplateArguments ();
+
+ lldb::SBType
+ GetTemplateArgumentType (uint32_t idx);
+
+ lldb::TemplateArgumentKind
+ GetTemplateArgumentKind (uint32_t idx);
+
+ lldb::SBType
+ GetFunctionReturnType ();
+
+ lldb::SBTypeList
+ GetFunctionArgumentTypes ();
+
+ const char*
+ GetName();
+
+ lldb::TypeClass
+ GetTypeClass ();
+
+ bool
+ IsTypeComplete ();
+
+ bool
+ GetDescription (lldb::SBStream &description,
+ lldb::DescriptionLevel description_level);
+
+ lldb::SBType &
+ operator = (const lldb::SBType &rhs);
+
+ bool
+ operator == (lldb::SBType &rhs);
+
+ bool
+ operator != (lldb::SBType &rhs);
+
+protected:
+
+ lldb_private::TypeImpl &
+ ref ();
+
+ const lldb_private::TypeImpl &
+ ref () const;
+
+ lldb::TypeImplSP
+ GetSP ();
+
+ void
+ SetSP (const lldb::TypeImplSP &type_impl_sp);
+
+ lldb::TypeImplSP m_opaque_sp;
+
+ friend class SBFunction;
+ friend class SBModule;
+ friend class SBTarget;
+ friend class SBTypeNameSpecifier;
+ friend class SBTypeMember;
+ friend class SBTypeList;
+ friend class SBValue;
+
+ SBType (const lldb_private::ClangASTType &);
+ SBType (const lldb::TypeSP &);
+ SBType (const lldb::TypeImplSP &);
+
+};
+
+class SBTypeList
+{
+public:
+ SBTypeList();
+
+ SBTypeList(const lldb::SBTypeList& rhs);
+
+ ~SBTypeList();
+
+ lldb::SBTypeList&
+ operator = (const lldb::SBTypeList& rhs);
+
+ bool
+ IsValid();
+
+ void
+ Append (lldb::SBType type);
+
+ lldb::SBType
+ GetTypeAtIndex (uint32_t index);
+
+ uint32_t
+ GetSize();
+
+
+private:
+ std::unique_ptr<lldb_private::TypeListImpl> m_opaque_ap;
+ friend class SBModule;
+ friend class SBCompileUnit;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBType_h_
diff --git a/include/lldb/API/SBTypeCategory.h b/include/lldb/API/SBTypeCategory.h
new file mode 100644
index 000000000000..f123e931e17d
--- /dev/null
+++ b/include/lldb/API/SBTypeCategory.h
@@ -0,0 +1,168 @@
+//===-- SBTypeCategory.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBTypeCategory_h_
+#define LLDB_SBTypeCategory_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+ class SBTypeCategory
+ {
+ public:
+
+ SBTypeCategory();
+
+ SBTypeCategory (const lldb::SBTypeCategory &rhs);
+
+ ~SBTypeCategory ();
+
+ bool
+ IsValid() const;
+
+ bool
+ GetEnabled ();
+
+ void
+ SetEnabled (bool);
+
+ const char*
+ GetName();
+
+ bool
+ GetDescription (lldb::SBStream &description,
+ lldb::DescriptionLevel description_level);
+
+ uint32_t
+ GetNumFormats ();
+
+ uint32_t
+ GetNumSummaries ();
+
+ uint32_t
+ GetNumFilters ();
+
+#ifndef LLDB_DISABLE_PYTHON
+ uint32_t
+ GetNumSynthetics ();
+#endif
+
+ SBTypeNameSpecifier
+ GetTypeNameSpecifierForFilterAtIndex (uint32_t);
+
+ SBTypeNameSpecifier
+ GetTypeNameSpecifierForFormatAtIndex (uint32_t);
+
+ SBTypeNameSpecifier
+ GetTypeNameSpecifierForSummaryAtIndex (uint32_t);
+
+#ifndef LLDB_DISABLE_PYTHON
+ SBTypeNameSpecifier
+ GetTypeNameSpecifierForSyntheticAtIndex (uint32_t);
+#endif
+
+ SBTypeFilter
+ GetFilterForType (SBTypeNameSpecifier);
+
+ SBTypeFormat
+ GetFormatForType (SBTypeNameSpecifier);
+
+#ifndef LLDB_DISABLE_PYTHON
+ SBTypeSummary
+ GetSummaryForType (SBTypeNameSpecifier);
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+ SBTypeSynthetic
+ GetSyntheticForType (SBTypeNameSpecifier);
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+ SBTypeFilter
+ GetFilterAtIndex (uint32_t);
+#endif
+
+ SBTypeFormat
+ GetFormatAtIndex (uint32_t);
+
+#ifndef LLDB_DISABLE_PYTHON
+ SBTypeSummary
+ GetSummaryAtIndex (uint32_t);
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+ SBTypeSynthetic
+ GetSyntheticAtIndex (uint32_t);
+#endif
+
+ bool
+ AddTypeFormat (SBTypeNameSpecifier,
+ SBTypeFormat);
+
+ bool
+ DeleteTypeFormat (SBTypeNameSpecifier);
+
+#ifndef LLDB_DISABLE_PYTHON
+ bool
+ AddTypeSummary (SBTypeNameSpecifier,
+ SBTypeSummary);
+#endif
+
+ bool
+ DeleteTypeSummary (SBTypeNameSpecifier);
+
+ bool
+ AddTypeFilter (SBTypeNameSpecifier,
+ SBTypeFilter);
+
+ bool
+ DeleteTypeFilter (SBTypeNameSpecifier);
+
+#ifndef LLDB_DISABLE_PYTHON
+ bool
+ AddTypeSynthetic (SBTypeNameSpecifier,
+ SBTypeSynthetic);
+
+ bool
+ DeleteTypeSynthetic (SBTypeNameSpecifier);
+#endif
+
+ lldb::SBTypeCategory &
+ operator = (const lldb::SBTypeCategory &rhs);
+
+ bool
+ operator == (lldb::SBTypeCategory &rhs);
+
+ bool
+ operator != (lldb::SBTypeCategory &rhs);
+
+ protected:
+ friend class SBDebugger;
+
+ lldb::TypeCategoryImplSP
+ GetSP ();
+
+ void
+ SetSP (const lldb::TypeCategoryImplSP &typecategory_impl_sp);
+
+ TypeCategoryImplSP m_opaque_sp;
+
+ SBTypeCategory (const lldb::TypeCategoryImplSP &);
+
+ SBTypeCategory (const char*);
+
+ bool
+ IsDefaultCategory();
+
+ };
+
+} // namespace lldb
+
+#endif // LLDB_SBTypeCategory_h_
diff --git a/include/lldb/API/SBTypeFilter.h b/include/lldb/API/SBTypeFilter.h
new file mode 100644
index 000000000000..016954943e28
--- /dev/null
+++ b/include/lldb/API/SBTypeFilter.h
@@ -0,0 +1,92 @@
+//===-- SBTypeFilter.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBTypeFilter_h_
+#define LLDB_SBTypeFilter_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+ class SBTypeFilter
+ {
+ public:
+
+ SBTypeFilter();
+
+ SBTypeFilter (uint32_t options); // see lldb::eTypeOption values
+
+ SBTypeFilter (const lldb::SBTypeFilter &rhs);
+
+ ~SBTypeFilter ();
+
+ bool
+ IsValid() const;
+
+ uint32_t
+ GetNumberOfExpressionPaths ();
+
+ const char*
+ GetExpressionPathAtIndex (uint32_t i);
+
+ bool
+ ReplaceExpressionPathAtIndex (uint32_t i, const char* item);
+
+ void
+ AppendExpressionPath (const char* item);
+
+ void
+ Clear();
+
+ uint32_t
+ GetOptions();
+
+ void
+ SetOptions (uint32_t);
+
+ bool
+ GetDescription (lldb::SBStream &description,
+ lldb::DescriptionLevel description_level);
+
+ lldb::SBTypeFilter &
+ operator = (const lldb::SBTypeFilter &rhs);
+
+ bool
+ IsEqualTo (lldb::SBTypeFilter &rhs);
+
+ bool
+ operator == (lldb::SBTypeFilter &rhs);
+
+ bool
+ operator != (lldb::SBTypeFilter &rhs);
+
+ protected:
+ friend class SBDebugger;
+ friend class SBTypeCategory;
+ friend class SBValue;
+
+ lldb::TypeFilterImplSP
+ GetSP ();
+
+ void
+ SetSP (const lldb::TypeFilterImplSP &typefilter_impl_sp);
+
+ lldb::TypeFilterImplSP m_opaque_sp;
+
+ SBTypeFilter (const lldb::TypeFilterImplSP &);
+
+ bool
+ CopyOnWrite_Impl();
+
+ };
+
+
+} // namespace lldb
+
+#endif // LLDB_SBTypeFilter_h_
diff --git a/include/lldb/API/SBTypeFormat.h b/include/lldb/API/SBTypeFormat.h
new file mode 100644
index 000000000000..cd6345fbe6fa
--- /dev/null
+++ b/include/lldb/API/SBTypeFormat.h
@@ -0,0 +1,84 @@
+//===-- SBTypeFormat.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBTypeFormat_h_
+#define LLDB_SBTypeFormat_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBTypeFormat
+{
+public:
+
+ SBTypeFormat();
+
+ SBTypeFormat (lldb::Format format,
+ uint32_t options = 0); // see lldb::eTypeOption values
+
+ SBTypeFormat (const lldb::SBTypeFormat &rhs);
+
+ ~SBTypeFormat ();
+
+ bool
+ IsValid() const;
+
+ lldb::Format
+ GetFormat ();
+
+ uint32_t
+ GetOptions();
+
+ void
+ SetFormat (lldb::Format);
+
+ void
+ SetOptions (uint32_t);
+
+ bool
+ GetDescription (lldb::SBStream &description,
+ lldb::DescriptionLevel description_level);
+
+ lldb::SBTypeFormat &
+ operator = (const lldb::SBTypeFormat &rhs);
+
+ bool
+ IsEqualTo (lldb::SBTypeFormat &rhs);
+
+ bool
+ operator == (lldb::SBTypeFormat &rhs);
+
+ bool
+ operator != (lldb::SBTypeFormat &rhs);
+
+protected:
+ friend class SBDebugger;
+ friend class SBTypeCategory;
+ friend class SBValue;
+
+ lldb::TypeFormatImplSP
+ GetSP ();
+
+ void
+ SetSP (const lldb::TypeFormatImplSP &typeformat_impl_sp);
+
+ lldb::TypeFormatImplSP m_opaque_sp;
+
+ SBTypeFormat (const lldb::TypeFormatImplSP &);
+
+ bool
+ CopyOnWrite_Impl();
+
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBTypeFormat_h_
diff --git a/include/lldb/API/SBTypeNameSpecifier.h b/include/lldb/API/SBTypeNameSpecifier.h
new file mode 100644
index 000000000000..19d1988aa0c5
--- /dev/null
+++ b/include/lldb/API/SBTypeNameSpecifier.h
@@ -0,0 +1,77 @@
+//===-- SBTypeNameSpecifier.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBTypeNameSpecifier_h_
+#define LLDB_SBTypeNameSpecifier_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+ class SBTypeNameSpecifier
+ {
+ public:
+
+ SBTypeNameSpecifier();
+
+ SBTypeNameSpecifier (const char* name,
+ bool is_regex = false);
+
+ SBTypeNameSpecifier (SBType type);
+
+ SBTypeNameSpecifier (const lldb::SBTypeNameSpecifier &rhs);
+
+ ~SBTypeNameSpecifier ();
+
+ bool
+ IsValid() const;
+
+ const char*
+ GetName();
+
+ SBType
+ GetType ();
+
+ bool
+ IsRegex();
+
+ bool
+ GetDescription (lldb::SBStream &description,
+ lldb::DescriptionLevel description_level);
+
+ lldb::SBTypeNameSpecifier &
+ operator = (const lldb::SBTypeNameSpecifier &rhs);
+
+ bool
+ IsEqualTo (lldb::SBTypeNameSpecifier &rhs);
+
+ bool
+ operator == (lldb::SBTypeNameSpecifier &rhs);
+
+ bool
+ operator != (lldb::SBTypeNameSpecifier &rhs);
+
+ protected:
+ friend class SBDebugger;
+ friend class SBTypeCategory;
+
+ lldb::TypeNameSpecifierImplSP
+ GetSP ();
+
+ void
+ SetSP (const lldb::TypeNameSpecifierImplSP &type_namespec_sp);
+
+ lldb::TypeNameSpecifierImplSP m_opaque_sp;
+
+ SBTypeNameSpecifier (const lldb::TypeNameSpecifierImplSP &);
+ };
+
+} // namespace lldb
+
+#endif // LLDB_SBTypeNameSpecifier_h_
diff --git a/include/lldb/API/SBTypeSummary.h b/include/lldb/API/SBTypeSummary.h
new file mode 100644
index 000000000000..67a8607511cc
--- /dev/null
+++ b/include/lldb/API/SBTypeSummary.h
@@ -0,0 +1,115 @@
+//===-- SBTypeSummary.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBTypeSummary_h_
+#define LLDB_SBTypeSummary_h_
+
+#include "lldb/API/SBDefines.h"
+
+#ifndef LLDB_DISABLE_PYTHON
+
+namespace lldb {
+
+ class SBTypeSummary
+ {
+ public:
+
+ SBTypeSummary();
+
+ static SBTypeSummary
+ CreateWithSummaryString (const char* data,
+ uint32_t options = 0); // see lldb::eTypeOption values
+
+ static SBTypeSummary
+ CreateWithFunctionName (const char* data,
+ uint32_t options = 0); // see lldb::eTypeOption values
+
+ static SBTypeSummary
+ CreateWithScriptCode (const char* data,
+ uint32_t options = 0); // see lldb::eTypeOption values
+
+ SBTypeSummary (const lldb::SBTypeSummary &rhs);
+
+ ~SBTypeSummary ();
+
+ bool
+ IsValid() const;
+
+ bool
+ IsFunctionCode();
+
+ bool
+ IsFunctionName();
+
+ bool
+ IsSummaryString();
+
+ const char*
+ GetData ();
+
+ void
+ SetSummaryString (const char* data);
+
+ void
+ SetFunctionName (const char* data);
+
+ void
+ SetFunctionCode (const char* data);
+
+ uint32_t
+ GetOptions ();
+
+ void
+ SetOptions (uint32_t);
+
+ bool
+ GetDescription (lldb::SBStream &description,
+ lldb::DescriptionLevel description_level);
+
+ lldb::SBTypeSummary &
+ operator = (const lldb::SBTypeSummary &rhs);
+
+ bool
+ IsEqualTo (lldb::SBTypeSummary &rhs);
+
+ bool
+ operator == (lldb::SBTypeSummary &rhs);
+
+ bool
+ operator != (lldb::SBTypeSummary &rhs);
+
+ protected:
+ friend class SBDebugger;
+ friend class SBTypeCategory;
+ friend class SBValue;
+
+ lldb::TypeSummaryImplSP
+ GetSP ();
+
+ void
+ SetSP (const lldb::TypeSummaryImplSP &typefilter_impl_sp);
+
+ lldb::TypeSummaryImplSP m_opaque_sp;
+
+ SBTypeSummary (const lldb::TypeSummaryImplSP &);
+
+ bool
+ CopyOnWrite_Impl();
+
+ bool
+ ChangeSummaryType (bool want_script);
+
+ };
+
+
+} // namespace lldb
+
+#endif // LLDB_DISABLE_PYTHON
+
+#endif // LLDB_SBTypeSummary_h_
diff --git a/include/lldb/API/SBTypeSynthetic.h b/include/lldb/API/SBTypeSynthetic.h
new file mode 100644
index 000000000000..e77cbfef598c
--- /dev/null
+++ b/include/lldb/API/SBTypeSynthetic.h
@@ -0,0 +1,102 @@
+//===-- SBTypeSynthetic.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBTypeSynthetic_h_
+#define LLDB_SBTypeSynthetic_h_
+
+#include "lldb/API/SBDefines.h"
+
+#ifndef LLDB_DISABLE_PYTHON
+
+namespace lldb {
+
+ class SBTypeSynthetic
+ {
+ public:
+
+ SBTypeSynthetic();
+
+ static SBTypeSynthetic
+ CreateWithClassName (const char* data,
+ uint32_t options = 0); // see lldb::eTypeOption values
+
+ static SBTypeSynthetic
+ CreateWithScriptCode (const char* data,
+ uint32_t options = 0); // see lldb::eTypeOption values
+
+ SBTypeSynthetic (const lldb::SBTypeSynthetic &rhs);
+
+ ~SBTypeSynthetic ();
+
+ bool
+ IsValid() const;
+
+ bool
+ IsClassCode();
+
+ bool
+ IsClassName();
+
+ const char*
+ GetData ();
+
+ void
+ SetClassName (const char* data);
+
+ void
+ SetClassCode (const char* data);
+
+ uint32_t
+ GetOptions ();
+
+ void
+ SetOptions (uint32_t);
+
+ bool
+ GetDescription (lldb::SBStream &description,
+ lldb::DescriptionLevel description_level);
+
+ lldb::SBTypeSynthetic &
+ operator = (const lldb::SBTypeSynthetic &rhs);
+
+ bool
+ IsEqualTo (lldb::SBTypeSynthetic &rhs);
+
+ bool
+ operator == (lldb::SBTypeSynthetic &rhs);
+
+ bool
+ operator != (lldb::SBTypeSynthetic &rhs);
+
+ protected:
+ friend class SBDebugger;
+ friend class SBTypeCategory;
+ friend class SBValue;
+
+ lldb::ScriptedSyntheticChildrenSP
+ GetSP ();
+
+ void
+ SetSP (const lldb::ScriptedSyntheticChildrenSP &typefilter_impl_sp);
+
+ lldb::ScriptedSyntheticChildrenSP m_opaque_sp;
+
+ SBTypeSynthetic (const lldb::ScriptedSyntheticChildrenSP &);
+
+ bool
+ CopyOnWrite_Impl();
+
+ };
+
+
+} // namespace lldb
+
+#endif // LLDB_DISABLE_PYTHON
+
+#endif // LLDB_SBTypeSynthetic_h_
diff --git a/include/lldb/API/SBValue.h b/include/lldb/API/SBValue.h
new file mode 100644
index 000000000000..2b9a344b9300
--- /dev/null
+++ b/include/lldb/API/SBValue.h
@@ -0,0 +1,488 @@
+//===-- SBValue.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBValue_h_
+#define LLDB_SBValue_h_
+
+#include "lldb/API/SBData.h"
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBType.h"
+
+class ValueImpl;
+class ValueLocker;
+
+namespace lldb {
+
+class SBValue
+{
+friend class ValueLocker;
+
+public:
+ SBValue ();
+
+ SBValue (const lldb::SBValue &rhs);
+
+ lldb::SBValue &
+ operator =(const lldb::SBValue &rhs);
+
+ ~SBValue ();
+
+ bool
+ IsValid();
+
+ void
+ Clear();
+
+ SBError
+ GetError();
+
+ lldb::user_id_t
+ GetID ();
+
+ const char *
+ GetName();
+
+ const char *
+ GetTypeName ();
+
+ size_t
+ GetByteSize ();
+
+ bool
+ IsInScope ();
+
+ lldb::Format
+ GetFormat ();
+
+ void
+ SetFormat (lldb::Format format);
+
+ const char *
+ GetValue ();
+
+ int64_t
+ GetValueAsSigned (lldb::SBError& error, int64_t fail_value=0);
+
+ uint64_t
+ GetValueAsUnsigned (lldb::SBError& error, uint64_t fail_value=0);
+
+ int64_t
+ GetValueAsSigned(int64_t fail_value=0);
+
+ uint64_t
+ GetValueAsUnsigned(uint64_t fail_value=0);
+
+ ValueType
+ GetValueType ();
+
+ bool
+ GetValueDidChange ();
+
+ const char *
+ GetSummary ();
+
+ const char *
+ GetObjectDescription ();
+
+ lldb::SBValue
+ GetDynamicValue (lldb::DynamicValueType use_dynamic);
+
+ lldb::SBValue
+ GetStaticValue ();
+
+ lldb::SBValue
+ GetNonSyntheticValue ();
+
+ lldb::DynamicValueType
+ GetPreferDynamicValue ();
+
+ void
+ SetPreferDynamicValue (lldb::DynamicValueType use_dynamic);
+
+ bool
+ GetPreferSyntheticValue ();
+
+ void
+ SetPreferSyntheticValue (bool use_synthetic);
+
+ bool
+ IsDynamic ();
+
+ bool
+ IsSynthetic ();
+
+ const char *
+ GetLocation ();
+
+ // Deprecated - use the one that takes SBError&
+ bool
+ SetValueFromCString (const char *value_str);
+
+ bool
+ SetValueFromCString (const char *value_str, lldb::SBError& error);
+
+ lldb::SBTypeFormat
+ GetTypeFormat ();
+
+#ifndef LLDB_DISABLE_PYTHON
+ lldb::SBTypeSummary
+ GetTypeSummary ();
+#endif
+
+ lldb::SBTypeFilter
+ GetTypeFilter ();
+
+#ifndef LLDB_DISABLE_PYTHON
+ lldb::SBTypeSynthetic
+ GetTypeSynthetic ();
+#endif
+
+ lldb::SBValue
+ GetChildAtIndex (uint32_t idx);
+
+ lldb::SBValue
+ CreateChildAtOffset (const char *name, uint32_t offset, lldb::SBType type);
+
+ lldb::SBValue
+ Cast (lldb::SBType type);
+
+ lldb::SBValue
+ CreateValueFromExpression (const char *name, const char* expression);
+
+ lldb::SBValue
+ CreateValueFromExpression (const char *name, const char* expression, SBExpressionOptions &options);
+
+ lldb::SBValue
+ CreateValueFromAddress (const char* name,
+ lldb::addr_t address,
+ lldb::SBType type);
+
+ // this has no address! GetAddress() and GetLoadAddress() as well as AddressOf()
+ // on the return of this call all return invalid
+ lldb::SBValue
+ CreateValueFromData (const char* name,
+ lldb::SBData data,
+ lldb::SBType type);
+
+ //------------------------------------------------------------------
+ /// Get a child value by index from a value.
+ ///
+ /// Structs, unions, classes, arrays and and pointers have child
+ /// values that can be access by index.
+ ///
+ /// Structs and unions access child members using a zero based index
+ /// for each child member. For
+ ///
+ /// Classes reserve the first indexes for base classes that have
+ /// members (empty base classes are omitted), and all members of the
+ /// current class will then follow the base classes.
+ ///
+ /// Pointers differ depending on what they point to. If the pointer
+ /// points to a simple type, the child at index zero
+ /// is the only child value available, unless \a synthetic_allowed
+ /// is \b true, in which case the pointer will be used as an array
+ /// and can create 'synthetic' child values using positive or
+ /// negative indexes. If the pointer points to an aggregate type
+ /// (an array, class, union, struct), then the pointee is
+ /// transparently skipped and any children are going to be the indexes
+ /// of the child values within the aggregate type. For example if
+ /// we have a 'Point' type and we have a SBValue that contains a
+ /// pointer to a 'Point' type, then the child at index zero will be
+ /// the 'x' member, and the child at index 1 will be the 'y' member
+ /// (the child at index zero won't be a 'Point' instance).
+ ///
+ /// Arrays have a preset number of children that can be accessed by
+ /// index and will returns invalid child values for indexes that are
+ /// out of bounds unless the \a synthetic_allowed is \b true. In this
+ /// case the array can create 'synthetic' child values for indexes
+ /// that aren't in the array bounds using positive or negative
+ /// indexes.
+ ///
+ /// @param[in] idx
+ /// The index of the child value to get
+ ///
+ /// @param[in] use_dynamic
+ /// An enumeration that specifies wether to get dynamic values,
+ /// and also if the target can be run to figure out the dynamic
+ /// type of the child value.
+ ///
+ /// @param[in] synthetic_allowed
+ /// If \b true, then allow child values to be created by index
+ /// for pointers and arrays for indexes that normally wouldn't
+ /// be allowed.
+ ///
+ /// @return
+ /// A new SBValue object that represents the child member value.
+ //------------------------------------------------------------------
+ lldb::SBValue
+ GetChildAtIndex (uint32_t idx,
+ lldb::DynamicValueType use_dynamic,
+ bool can_create_synthetic);
+
+ // Matches children of this object only and will match base classes and
+ // member names if this is a clang typed object.
+ uint32_t
+ GetIndexOfChildWithName (const char *name);
+
+ // Matches child members of this object and child members of any base
+ // classes.
+ lldb::SBValue
+ GetChildMemberWithName (const char *name);
+
+ // Matches child members of this object and child members of any base
+ // classes.
+ lldb::SBValue
+ GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic);
+
+ // Expands nested expressions like .a->b[0].c[1]->d
+ lldb::SBValue
+ GetValueForExpressionPath(const char* expr_path);
+
+ lldb::SBValue
+ AddressOf();
+
+ lldb::addr_t
+ GetLoadAddress();
+
+ lldb::SBAddress
+ GetAddress();
+
+ //------------------------------------------------------------------
+ /// Get an SBData wrapping what this SBValue points to.
+ ///
+ /// This method will dereference the current SBValue, if its
+ /// data type is a T* or T[], and extract item_count elements
+ /// of type T from it, copying their contents in an SBData.
+ ///
+ /// @param[in] item_idx
+ /// The index of the first item to retrieve. For an array
+ /// this is equivalent to array[item_idx], for a pointer
+ /// to *(pointer + item_idx). In either case, the measurement
+ /// unit for item_idx is the sizeof(T) rather than the byte
+ ///
+ /// @param[in] item_count
+ /// How many items should be copied into the output. By default
+ /// only one item is copied, but more can be asked for.
+ ///
+ /// @return
+ /// An SBData with the contents of the copied items, on success.
+ /// An empty SBData otherwise.
+ //------------------------------------------------------------------
+ lldb::SBData
+ GetPointeeData (uint32_t item_idx = 0,
+ uint32_t item_count = 1);
+
+ //------------------------------------------------------------------
+ /// Get an SBData wrapping the contents of this SBValue.
+ ///
+ /// This method will read the contents of this object in memory
+ /// and copy them into an SBData for future use.
+ ///
+ /// @return
+ /// An SBData with the contents of this SBValue, on success.
+ /// An empty SBData otherwise.
+ //------------------------------------------------------------------
+ lldb::SBData
+ GetData ();
+
+ bool
+ SetData (lldb::SBData &data, lldb::SBError& error);
+
+ lldb::SBDeclaration
+ GetDeclaration ();
+
+ //------------------------------------------------------------------
+ /// Find out if a SBValue might have children.
+ ///
+ /// This call is much more efficient than GetNumChildren() as it
+ /// doesn't need to complete the underlying type. This is designed
+ /// to be used in a UI environment in order to detect if the
+ /// disclosure triangle should be displayed or not.
+ ///
+ /// This function returns true for class, union, structure,
+ /// pointers, references, arrays and more. Again, it does so without
+ /// doing any expensive type completion.
+ ///
+ /// @return
+ /// Returns \b true if the SBValue might have children, or \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ bool
+ MightHaveChildren ();
+
+ uint32_t
+ GetNumChildren ();
+
+ void *
+ GetOpaqueType();
+
+ lldb::SBTarget
+ GetTarget();
+
+ lldb::SBProcess
+ GetProcess();
+
+ lldb::SBThread
+ GetThread();
+
+ lldb::SBFrame
+ GetFrame();
+
+ lldb::SBValue
+ Dereference ();
+
+ bool
+ TypeIsPointerType ();
+
+ lldb::SBType
+ GetType();
+
+ bool
+ GetDescription (lldb::SBStream &description);
+
+ bool
+ GetExpressionPath (lldb::SBStream &description);
+
+ bool
+ GetExpressionPath (lldb::SBStream &description,
+ bool qualify_cxx_base_classes);
+
+ SBValue (const lldb::ValueObjectSP &value_sp);
+
+ //------------------------------------------------------------------
+ /// Watch this value if it resides in memory.
+ ///
+ /// Sets a watchpoint on the value.
+ ///
+ /// @param[in] resolve_location
+ /// Resolve the location of this value once and watch its address.
+ /// This value must currently be set to \b true as watching all
+ /// locations of a variable or a variable path is not yet supported,
+ /// though we plan to support it in the future.
+ ///
+ /// @param[in] read
+ /// Stop when this value is accessed.
+ ///
+ /// @param[in] write
+ /// Stop when this value is modified
+ ///
+ /// @param[out]
+ /// An error object. Contains the reason if there is some failure.
+ ///
+ /// @return
+ /// An SBWatchpoint object. This object might not be valid upon
+ /// return due to a value not being contained in memory, too
+ /// large, or watchpoint resources are not available or all in
+ /// use.
+ //------------------------------------------------------------------
+ lldb::SBWatchpoint
+ Watch (bool resolve_location, bool read, bool write, SBError &error);
+
+ // Backward compatibility fix in the interim.
+ lldb::SBWatchpoint
+ Watch (bool resolve_location, bool read, bool write);
+
+ //------------------------------------------------------------------
+ /// Watch this value that this value points to in memory
+ ///
+ /// Sets a watchpoint on the value.
+ ///
+ /// @param[in] resolve_location
+ /// Resolve the location of this value once and watch its address.
+ /// This value must currently be set to \b true as watching all
+ /// locations of a variable or a variable path is not yet supported,
+ /// though we plan to support it in the future.
+ ///
+ /// @param[in] read
+ /// Stop when this value is accessed.
+ ///
+ /// @param[in] write
+ /// Stop when this value is modified
+ ///
+ /// @param[out]
+ /// An error object. Contains the reason if there is some failure.
+ ///
+ /// @return
+ /// An SBWatchpoint object. This object might not be valid upon
+ /// return due to a value not being contained in memory, too
+ /// large, or watchpoint resources are not available or all in
+ /// use.
+ //------------------------------------------------------------------
+ lldb::SBWatchpoint
+ WatchPointee (bool resolve_location, bool read, bool write, SBError &error);
+
+ //------------------------------------------------------------------
+ /// Same as the protected version of GetSP that takes a locker, except that we make the
+ /// locker locally in the function. Since the Target API mutex is recursive, and the
+ /// StopLocker is a read lock, you can call this function even if you are already
+ /// holding the two above-mentioned locks.
+ ///
+ /// @return
+ /// A ValueObjectSP of the best kind (static, dynamic or synthetic) we
+ /// can cons up, in accordance with the SBValue's settings.
+ //------------------------------------------------------------------
+ lldb::ValueObjectSP
+ GetSP () const;
+
+protected:
+ friend class SBBlock;
+ friend class SBFrame;
+ friend class SBTarget;
+ friend class SBThread;
+ friend class SBValueList;
+
+ //------------------------------------------------------------------
+ /// Get the appropriate ValueObjectSP from this SBValue, consulting the
+ /// use_dynamic and use_synthetic options passed in to SetSP when the
+ /// SBValue's contents were set. Since this often requires examining memory,
+ /// and maybe even running code, it needs to acquire the Target API and Process StopLock.
+ /// Those are held in an opaque class ValueLocker which is currently local to SBValue.cpp.
+ /// So you don't have to get these yourself just default construct a ValueLocker, and pass it into this.
+ /// If we need to make a ValueLocker and use it in some other .cpp file, we'll have to move it to
+ /// ValueObject.h/cpp or somewhere else convenient. We haven't needed to so far.
+ ///
+ /// @param[in] value_locker
+ /// An object that will hold the Target API, and Process RunLocks, and
+ /// auto-destroy them when it goes out of scope. Currently this is only useful in
+ /// SBValue.cpp.
+ ///
+ /// @return
+ /// A ValueObjectSP of the best kind (static, dynamic or synthetic) we
+ /// can cons up, in accordance with the SBValue's settings.
+ //------------------------------------------------------------------
+ lldb::ValueObjectSP
+ GetSP (ValueLocker &value_locker) const;
+
+ // these calls do the right thing WRT adjusting their settings according to the target's preferences
+ void
+ SetSP (const lldb::ValueObjectSP &sp);
+
+ void
+ SetSP (const lldb::ValueObjectSP &sp, bool use_synthetic);
+
+ void
+ SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic);
+
+ void
+ SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic, bool use_synthetic);
+
+ void
+ SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic, bool use_synthetic, const char *name);
+
+private:
+ typedef std::shared_ptr<ValueImpl> ValueImplSP;
+ ValueImplSP m_opaque_sp;
+
+ void
+ SetSP (ValueImplSP impl_sp);
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBValue_h_
diff --git a/include/lldb/API/SBValueList.h b/include/lldb/API/SBValueList.h
new file mode 100644
index 000000000000..b9a6aedea3cb
--- /dev/null
+++ b/include/lldb/API/SBValueList.h
@@ -0,0 +1,93 @@
+//===-- SBValueList.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBValueList_h_
+#define LLDB_SBValueList_h_
+
+#include "lldb/API/SBDefines.h"
+
+class ValueListImpl;
+
+namespace lldb {
+
+class SBValueList
+{
+public:
+
+ SBValueList ();
+
+ SBValueList (const lldb::SBValueList &rhs);
+
+ ~SBValueList();
+
+ bool
+ IsValid() const;
+
+ void
+ Clear();
+
+ void
+ Append (const lldb::SBValue &val_obj);
+
+ void
+ Append (const lldb::SBValueList& value_list);
+
+ uint32_t
+ GetSize() const;
+
+ lldb::SBValue
+ GetValueAtIndex (uint32_t idx) const;
+
+ lldb::SBValue
+ FindValueObjectByUID (lldb::user_id_t uid);
+
+ const lldb::SBValueList &
+ operator = (const lldb::SBValueList &rhs);
+
+protected:
+
+ // only useful for visualizing the pointer or comparing two SBValueLists
+ // to see if they are backed by the same underlying Impl.
+ void *
+ opaque_ptr ();
+
+private:
+ friend class SBFrame;
+
+ SBValueList (const ValueListImpl *lldb_object_ptr);
+
+ void
+ Append (lldb::ValueObjectSP& val_obj_sp);
+
+ void
+ CreateIfNeeded ();
+
+ ValueListImpl *
+ operator -> ();
+
+ ValueListImpl &
+ operator* ();
+
+ const ValueListImpl *
+ operator -> () const;
+
+ const ValueListImpl &
+ operator* () const;
+
+
+ ValueListImpl &
+ ref ();
+
+ std::unique_ptr<ValueListImpl> m_opaque_ap;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBValueList_h_
diff --git a/include/lldb/API/SBWatchpoint.h b/include/lldb/API/SBWatchpoint.h
new file mode 100644
index 000000000000..9bf51fd1ad05
--- /dev/null
+++ b/include/lldb/API/SBWatchpoint.h
@@ -0,0 +1,104 @@
+//===-- SBWatchpoint.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBWatchpoint_h_
+#define LLDB_SBWatchpoint_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBWatchpoint
+{
+public:
+
+ SBWatchpoint ();
+
+ SBWatchpoint (const lldb::SBWatchpoint &rhs);
+
+ SBWatchpoint (const lldb::WatchpointSP &wp_sp);
+
+ ~SBWatchpoint ();
+
+ const lldb::SBWatchpoint &
+ operator = (const lldb::SBWatchpoint &rhs);
+
+ bool
+ IsValid() const;
+
+ SBError
+ GetError();
+
+ watch_id_t
+ GetID ();
+
+ /// With -1 representing an invalid hardware index.
+ int32_t
+ GetHardwareIndex ();
+
+ lldb::addr_t
+ GetWatchAddress ();
+
+ size_t
+ GetWatchSize();
+
+ void
+ SetEnabled(bool enabled);
+
+ bool
+ IsEnabled ();
+
+ uint32_t
+ GetHitCount ();
+
+ uint32_t
+ GetIgnoreCount ();
+
+ void
+ SetIgnoreCount (uint32_t n);
+
+ const char *
+ GetCondition ();
+
+ void
+ SetCondition (const char *condition);
+
+ bool
+ GetDescription (lldb::SBStream &description, DescriptionLevel level);
+
+ void
+ Clear ();
+
+ lldb::WatchpointSP
+ GetSP () const;
+
+ void
+ SetSP (const lldb::WatchpointSP &sp);
+
+ static bool
+ EventIsWatchpointEvent (const lldb::SBEvent &event);
+
+ static lldb::WatchpointEventType
+ GetWatchpointEventTypeFromEvent (const lldb::SBEvent& event);
+
+ static lldb::SBWatchpoint
+ GetWatchpointFromEvent (const lldb::SBEvent& event);
+
+private:
+ friend class SBTarget;
+ friend class SBValue;
+
+
+ lldb::WatchpointSP m_opaque_sp;
+
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBWatchpoint_h_
diff --git a/include/lldb/Breakpoint/Breakpoint.h b/include/lldb/Breakpoint/Breakpoint.h
new file mode 100644
index 000000000000..bd11a1c91e21
--- /dev/null
+++ b/include/lldb/Breakpoint/Breakpoint.h
@@ -0,0 +1,630 @@
+//===-- Breakpoint.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Breakpoint_h_
+#define liblldb_Breakpoint_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointLocationList.h"
+#include "lldb/Breakpoint/BreakpointOptions.h"
+#include "lldb/Breakpoint/BreakpointLocationCollection.h"
+#include "lldb/Breakpoint/Stoppoint.h"
+#include "lldb/Core/SearchFilter.h"
+#include "lldb/Core/Event.h"
+#include "lldb/Core/StringList.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Breakpoint Breakpoint.h "lldb/Breakpoint/Breakpoint.h"
+/// @brief Class that manages logical breakpoint setting.
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+/// General Outline:
+/// A breakpoint has four main parts, a filter, a resolver, the list of breakpoint
+/// locations that have been determined for the filter/resolver pair, and finally
+/// a set of options for the breakpoint.
+///
+/// \b Filter:
+/// This is an object derived from SearchFilter. It manages the search
+/// for breakpoint location matches through the symbols in the module list of the target
+/// that owns it. It also filters out locations based on whatever logic it wants.
+///
+/// \b Resolver:
+/// This is an object derived from BreakpointResolver. It provides a
+/// callback to the filter that will find breakpoint locations. How it does this is
+/// determined by what kind of resolver it is.
+///
+/// The Breakpoint class also provides constructors for the common breakpoint cases
+/// which make the appropriate filter and resolver for you.
+///
+/// \b Location List:
+/// This stores the breakpoint locations that have been determined
+/// to date. For a given breakpoint, there will be only one location with a given
+/// address. Adding a location at an already taken address will just return the location
+/// already at that address. Locations can be looked up by ID, or by address.
+///
+/// \b Options:
+/// This includes:
+/// \b Enabled/Disabled
+/// \b Ignore Count
+/// \b Callback
+/// \b Condition
+/// Note, these options can be set on the breakpoint, and they can also be set on the
+/// individual locations. The options set on the breakpoint take precedence over the
+/// options set on the individual location.
+/// So for instance disabling the breakpoint will cause NONE of the locations to get hit.
+/// But if the breakpoint is enabled, then the location's enabled state will be checked
+/// to determine whether to insert that breakpoint location.
+/// Similarly, if the breakpoint condition says "stop", we won't check the location's condition.
+/// But if the breakpoint condition says "continue", then we will check the location for whether
+/// to actually stop or not.
+/// One subtle point worth observing here is that you don't actually stop at a Breakpoint, you
+/// always stop at one of its locations. So the "should stop" tests are done by the location,
+/// not by the breakpoint.
+//----------------------------------------------------------------------
+class Breakpoint:
+ public std::enable_shared_from_this<Breakpoint>,
+ public Stoppoint
+{
+public:
+
+ static const ConstString &
+ GetEventIdentifier ();
+
+
+ //------------------------------------------------------------------
+ /// An enum specifying the match style for breakpoint settings. At
+ /// present only used for function name style breakpoints.
+ //------------------------------------------------------------------
+ typedef enum
+ {
+ Exact,
+ Regexp,
+ Glob
+ } MatchType;
+
+ class BreakpointEventData :
+ public EventData
+ {
+ public:
+
+ static const ConstString &
+ GetFlavorString ();
+
+ virtual const ConstString &
+ GetFlavor () const;
+
+ BreakpointEventData (lldb::BreakpointEventType sub_type,
+ const lldb::BreakpointSP &new_breakpoint_sp);
+
+ virtual
+ ~BreakpointEventData();
+
+ lldb::BreakpointEventType
+ GetBreakpointEventType () const;
+
+ lldb::BreakpointSP &
+ GetBreakpoint ();
+
+ BreakpointLocationCollection &
+ GetBreakpointLocationCollection()
+ {
+ return m_locations;
+ }
+
+
+ virtual void
+ Dump (Stream *s) const;
+
+ static lldb::BreakpointEventType
+ GetBreakpointEventTypeFromEvent (const lldb::EventSP &event_sp);
+
+ static lldb::BreakpointSP
+ GetBreakpointFromEvent (const lldb::EventSP &event_sp);
+
+ static lldb::BreakpointLocationSP
+ GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t loc_idx);
+
+ static size_t
+ GetNumBreakpointLocationsFromEvent (const lldb::EventSP &event_sp);
+
+ static const BreakpointEventData *
+ GetEventDataFromEvent (const Event *event_sp);
+
+ private:
+
+ lldb::BreakpointEventType m_breakpoint_event;
+ lldb::BreakpointSP m_new_breakpoint_sp;
+ BreakpointLocationCollection m_locations;
+
+ DISALLOW_COPY_AND_ASSIGN (BreakpointEventData);
+ };
+
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is not virtual since there should be no reason to subclass
+ /// breakpoints. The varieties of breakpoints are specified instead by
+ /// providing different resolvers & filters.
+ //------------------------------------------------------------------
+ ~Breakpoint();
+
+ //------------------------------------------------------------------
+ // Methods
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Tell whether this breakpoint is an "internal" breakpoint.
+ /// @return
+ /// Returns \b true if this is an internal breakpoint, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsInternal () const;
+
+ //------------------------------------------------------------------
+ /// Standard "Dump" method. At present it does nothing.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s);
+
+ //------------------------------------------------------------------
+ // The next set of methods provide ways to tell the breakpoint to update
+ // it's location list - usually done when modules appear or disappear.
+ //------------------------------------------------------------------
+
+
+ //------------------------------------------------------------------
+ /// Tell this breakpoint to clear all its breakpoint sites. Done
+ /// when the process holding the breakpoint sites is destroyed.
+ //------------------------------------------------------------------
+ void
+ ClearAllBreakpointSites ();
+
+ //------------------------------------------------------------------
+ /// Tell this breakpoint to scan it's target's module list and resolve any
+ /// new locations that match the breakpoint's specifications.
+ //------------------------------------------------------------------
+ void
+ ResolveBreakpoint ();
+
+ //------------------------------------------------------------------
+ /// Tell this breakpoint to scan a given module list and resolve any
+ /// new locations that match the breakpoint's specifications.
+ ///
+ /// @param[in] changed_modules
+ /// The list of modules to look in for new locations.
+ //------------------------------------------------------------------
+ void
+ ResolveBreakpointInModules (ModuleList &changed_modules);
+
+
+ //------------------------------------------------------------------
+ /// Like ResolveBreakpointInModules, but allows for "unload" events, in
+ /// which case we will remove any locations that are in modules that got
+ /// unloaded.
+ ///
+ /// @param[in] changedModules
+ /// The list of modules to look in for new locations.
+ /// @param[in] load_event
+ /// If \b true then the modules were loaded, if \b false, unloaded.
+ /// @param[in] delete_locations
+ /// If \b true then the modules were unloaded delete any locations in the changed modules.
+ //------------------------------------------------------------------
+ void
+ ModulesChanged (ModuleList &changed_modules,
+ bool load_event,
+ bool delete_locations = false);
+
+
+ //------------------------------------------------------------------
+ /// Tells the breakpoint the old module \a old_module_sp has been
+ /// replaced by new_module_sp (usually because the underlying file has been
+ /// rebuilt, and the old version is gone.)
+ ///
+ /// @param[in] old_module_sp
+ /// The old module that is going away.
+ /// @param[in] new_module_sp
+ /// The new module that is replacing it.
+ //------------------------------------------------------------------
+ void
+ ModuleReplaced (lldb::ModuleSP old_module_sp, lldb::ModuleSP new_module_sp);
+
+ //------------------------------------------------------------------
+ // The next set of methods provide access to the breakpoint locations
+ // for this breakpoint.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Add a location to the breakpoint's location list. This is only meant
+ /// to be called by the breakpoint's resolver. FIXME: how do I ensure that?
+ ///
+ /// @param[in] addr
+ /// The Address specifying the new location.
+ /// @param[out] new_location
+ /// Set to \b true if a new location was created, to \b false if there
+ /// already was a location at this Address.
+ /// @return
+ /// Returns a pointer to the new location.
+ //------------------------------------------------------------------
+ lldb::BreakpointLocationSP
+ AddLocation (const Address &addr,
+ bool *new_location = NULL);
+
+ //------------------------------------------------------------------
+ /// Find a breakpoint location by Address.
+ ///
+ /// @param[in] addr
+ /// The Address specifying the location.
+ /// @return
+ /// Returns a shared pointer to the location at \a addr. The pointer
+ /// in the shared pointer will be NULL if there is no location at that address.
+ //------------------------------------------------------------------
+ lldb::BreakpointLocationSP
+ FindLocationByAddress (const Address &addr);
+
+ //------------------------------------------------------------------
+ /// Find a breakpoint location ID by Address.
+ ///
+ /// @param[in] addr
+ /// The Address specifying the location.
+ /// @return
+ /// Returns the UID of the location at \a addr, or \b LLDB_INVALID_ID if
+ /// there is no breakpoint location at that address.
+ //------------------------------------------------------------------
+ lldb::break_id_t
+ FindLocationIDByAddress (const Address &addr);
+
+ //------------------------------------------------------------------
+ /// Find a breakpoint location for a given breakpoint location ID.
+ ///
+ /// @param[in] bp_loc_id
+ /// The ID specifying the location.
+ /// @return
+ /// Returns a shared pointer to the location with ID \a bp_loc_id. The pointer
+ /// in the shared pointer will be NULL if there is no location with that ID.
+ //------------------------------------------------------------------
+ lldb::BreakpointLocationSP
+ FindLocationByID (lldb::break_id_t bp_loc_id);
+
+ //------------------------------------------------------------------
+ /// Get breakpoint locations by index.
+ ///
+ /// @param[in] index
+ /// The location index.
+ ///
+ /// @return
+ /// Returns a shared pointer to the location with index \a
+ /// index. The shared pointer might contain NULL if \a index is
+ /// greater than then number of actual locations.
+ //------------------------------------------------------------------
+ lldb::BreakpointLocationSP
+ GetLocationAtIndex (size_t index);
+
+ //------------------------------------------------------------------
+ // The next section deals with various breakpoint options.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// If \a enable is \b true, enable the breakpoint, if \b false disable it.
+ //------------------------------------------------------------------
+ void
+ SetEnabled (bool enable);
+
+ //------------------------------------------------------------------
+ /// Check the Enable/Disable state.
+ /// @return
+ /// \b true if the breakpoint is enabled, \b false if disabled.
+ //------------------------------------------------------------------
+ bool
+ IsEnabled ();
+
+ //------------------------------------------------------------------
+ /// Set the breakpoint to ignore the next \a count breakpoint hits.
+ /// @param[in] count
+ /// The number of breakpoint hits to ignore.
+ //------------------------------------------------------------------
+ void
+ SetIgnoreCount (uint32_t count);
+
+ //------------------------------------------------------------------
+ /// Return the current ignore count/
+ /// @return
+ /// The number of breakpoint hits to be ignored.
+ //------------------------------------------------------------------
+ uint32_t
+ GetIgnoreCount () const;
+
+ //------------------------------------------------------------------
+ /// Return the current hit count for all locations.
+ /// @return
+ /// The current hit count for all locations.
+ //------------------------------------------------------------------
+ uint32_t
+ GetHitCount () const;
+
+
+ //------------------------------------------------------------------
+ /// If \a one_shot is \b true, breakpoint will be deleted on first hit.
+ //------------------------------------------------------------------
+ void
+ SetOneShot (bool one_shot);
+
+ //------------------------------------------------------------------
+ /// Check the OneShot state.
+ /// @return
+ /// \b true if the breakpoint is one shot, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsOneShot () const;
+
+ //------------------------------------------------------------------
+ /// Set the valid thread to be checked when the breakpoint is hit.
+ /// @param[in] thread_id
+ /// If this thread hits the breakpoint, we stop, otherwise not.
+ //------------------------------------------------------------------
+ void
+ SetThreadID (lldb::tid_t thread_id);
+
+ //------------------------------------------------------------------
+ /// Return the current stop thread value.
+ /// @return
+ /// The thread id for which the breakpoint hit will stop, LLDB_INVALID_THREAD_ID for all threads.
+ //------------------------------------------------------------------
+ lldb::tid_t
+ GetThreadID () const;
+
+ void
+ SetThreadIndex (uint32_t index);
+
+ uint32_t
+ GetThreadIndex() const;
+
+ void
+ SetThreadName (const char *thread_name);
+
+ const char *
+ GetThreadName () const;
+
+ void
+ SetQueueName (const char *queue_name);
+
+ const char *
+ GetQueueName () const;
+
+ //------------------------------------------------------------------
+ /// Set the callback action invoked when the breakpoint is hit.
+ ///
+ /// @param[in] callback
+ /// The method that will get called when the breakpoint is hit.
+ /// @param[in] baton
+ /// A void * pointer that will get passed back to the callback function.
+ /// @param[in] is_synchronous
+ /// If \b true the callback will be run on the private event thread
+ /// before the stop event gets reported. If false, the callback will get
+ /// handled on the public event thead after the stop has been posted.
+ ///
+ /// @return
+ /// \b true if the process should stop when you hit the breakpoint.
+ /// \b false if it should continue.
+ //------------------------------------------------------------------
+ void
+ SetCallback (BreakpointHitCallback callback,
+ void *baton,
+ bool is_synchronous = false);
+
+ void
+ SetCallback (BreakpointHitCallback callback,
+ const lldb::BatonSP &callback_baton_sp,
+ bool is_synchronous = false);
+
+ void
+ ClearCallback ();
+
+ //------------------------------------------------------------------
+ /// Set the breakpoint's condition.
+ ///
+ /// @param[in] condition
+ /// The condition expression to evaluate when the breakpoint is hit.
+ /// Pass in NULL to clear the condition.
+ //------------------------------------------------------------------
+ void SetCondition (const char *condition);
+
+ //------------------------------------------------------------------
+ /// Return a pointer to the text of the condition expression.
+ ///
+ /// @return
+ /// A pointer to the condition expression text, or NULL if no
+ // condition has been set.
+ //------------------------------------------------------------------
+ const char *GetConditionText () const;
+
+ //------------------------------------------------------------------
+ // The next section are various utility functions.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Return the number of breakpoint locations that have resolved to
+ /// actual breakpoint sites.
+ ///
+ /// @return
+ /// The number locations resolved breakpoint sites.
+ //------------------------------------------------------------------
+ size_t
+ GetNumResolvedLocations() const;
+
+ //------------------------------------------------------------------
+ /// Return the number of breakpoint locations.
+ ///
+ /// @return
+ /// The number breakpoint locations.
+ //------------------------------------------------------------------
+ size_t
+ GetNumLocations() const;
+
+ //------------------------------------------------------------------
+ /// Put a description of this breakpoint into the stream \a s.
+ ///
+ /// @param[in] s
+ /// Stream into which to dump the description.
+ ///
+ /// @param[in] level
+ /// The description level that indicates the detail level to
+ /// provide.
+ ///
+ /// @see lldb::DescriptionLevel
+ //------------------------------------------------------------------
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations = false);
+
+ //------------------------------------------------------------------
+ /// Set the "kind" description for a breakpoint. If the breakpoint is hit
+ /// the stop info will show this "kind" description instead of the breakpoint
+ /// number. Mostly useful for internal breakpoints, where the breakpoint number
+ /// doesn't have meaning to the user.
+ ///
+ /// @param[in] kind
+ /// New "kind" description.
+ //------------------------------------------------------------------
+ void
+ SetBreakpointKind (const char *kind)
+ {
+ m_kind_description.assign (kind);
+ }
+
+ //------------------------------------------------------------------
+ /// Return the "kind" description for a breakpoint.
+ ///
+ /// @return
+ /// The breakpoint kind, or NULL if none is set.
+ //------------------------------------------------------------------
+ const char *GetBreakpointKind () const
+ {
+ return m_kind_description.c_str();
+ }
+
+ //------------------------------------------------------------------
+ /// Accessor for the breakpoint Target.
+ /// @return
+ /// This breakpoint's Target.
+ //------------------------------------------------------------------
+ Target &
+ GetTarget ();
+
+ const Target &
+ GetTarget () const;
+
+ void
+ GetResolverDescription (Stream *s);
+
+ //------------------------------------------------------------------
+ /// Find breakpoint locations which match the (filename, line_number) description.
+ /// The breakpoint location collection is to be filled with the matching locations.
+ /// It should be initialized with 0 size by the API client.
+ ///
+ /// @return
+ /// True if there is a match
+ ///
+ /// The locations which match the filename and line_number in loc_coll. If its
+ /// size is 0 and true is returned, it means the breakpoint fully matches the
+ /// description.
+ //------------------------------------------------------------------
+ bool GetMatchingFileLine(const ConstString &filename, uint32_t line_number,
+ BreakpointLocationCollection &loc_coll);
+
+ void
+ GetFilterDescription (Stream *s);
+
+ //------------------------------------------------------------------
+ /// Returns the BreakpointOptions structure set at the breakpoint level.
+ ///
+ /// Meant to be used by the BreakpointLocation class.
+ ///
+ /// @return
+ /// A pointer to this breakpoint's BreakpointOptions.
+ //------------------------------------------------------------------
+ BreakpointOptions *
+ GetOptions ();
+
+
+ //------------------------------------------------------------------
+ /// Invoke the callback action when the breakpoint is hit.
+ ///
+ /// Meant to be used by the BreakpointLocation class.
+ ///
+ /// @param[in] context
+ /// Described the breakpoint event.
+ ///
+ /// @param[in] bp_loc_id
+ /// Which breakpoint location hit this breakpoint.
+ ///
+ /// @return
+ /// \b true if the target should stop at this breakpoint and \b false not.
+ //------------------------------------------------------------------
+ bool
+ InvokeCallback (StoppointCallbackContext *context,
+ lldb::break_id_t bp_loc_id);
+
+protected:
+ friend class Target;
+ //------------------------------------------------------------------
+ // Protected Methods
+ //------------------------------------------------------------------
+
+
+ //------------------------------------------------------------------
+ /// Constructors and Destructors
+ /// Only the Target can make a breakpoint, and it owns the breakpoint lifespans.
+ /// The constructor takes a filter and a resolver. Up in Target there are convenience
+ /// variants that make breakpoints for some common cases.
+ //------------------------------------------------------------------
+ // This is the generic constructor
+ Breakpoint(Target &target, lldb::SearchFilterSP &filter_sp, lldb::BreakpointResolverSP &resolver_sp);
+
+ friend class BreakpointLocation; // To call the following two when determining whether to stop.
+
+ void
+ DecrementIgnoreCount();
+
+ // BreakpointLocation::IgnoreCountShouldStop & Breakpoint::IgnoreCountShouldStop can only be called once per stop,
+ // and BreakpointLocation::IgnoreCountShouldStop should be tested first, and if it returns false we should
+ // continue, otherwise we should test Breakpoint::IgnoreCountShouldStop.
+
+ bool
+ IgnoreCountShouldStop ();
+
+private:
+ //------------------------------------------------------------------
+ // For Breakpoint only
+ //------------------------------------------------------------------
+ bool m_being_created;
+ Target &m_target; // The target that holds this breakpoint.
+ lldb::SearchFilterSP m_filter_sp; // The filter that constrains the breakpoint's domain.
+ lldb::BreakpointResolverSP m_resolver_sp; // The resolver that defines this breakpoint.
+ BreakpointOptions m_options; // Settable breakpoint options
+ BreakpointLocationList m_locations; // The list of locations currently found for this breakpoint.
+ std::string m_kind_description;
+
+ void
+ SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind);
+
+ void
+ SendBreakpointChangedEvent (BreakpointEventData *data);
+
+ DISALLOW_COPY_AND_ASSIGN(Breakpoint);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Breakpoint_h_
diff --git a/include/lldb/Breakpoint/BreakpointID.h b/include/lldb/Breakpoint/BreakpointID.h
new file mode 100644
index 000000000000..9e352100b9e1
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointID.h
@@ -0,0 +1,117 @@
+//===-- BreakpointID.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointID_h_
+#define liblldb_BreakpointID_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// class BreakpointID
+//----------------------------------------------------------------------
+
+class BreakpointID
+{
+public:
+
+ BreakpointID (lldb::break_id_t bp_id = LLDB_INVALID_BREAK_ID,
+ lldb::break_id_t loc_id = LLDB_INVALID_BREAK_ID);
+
+ virtual
+ ~BreakpointID ();
+
+ lldb::break_id_t
+ GetBreakpointID ()
+ {
+ return m_break_id;
+ }
+
+ lldb::break_id_t
+ GetLocationID ()
+ {
+ return m_location_id;
+ }
+
+ void
+ SetID (lldb::break_id_t bp_id, lldb::break_id_t loc_id)
+ {
+ m_break_id = bp_id;
+ m_location_id = loc_id;
+ }
+
+ void
+ SetBreakpointID (lldb::break_id_t bp_id)
+ {
+ m_break_id = bp_id;
+ }
+
+ void
+ SetBreakpointLocationID (lldb::break_id_t loc_id)
+ {
+ m_location_id = loc_id;
+ }
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level);
+
+ static bool
+ IsRangeIdentifier (const char *str);
+
+ static bool
+ IsValidIDExpression (const char *str);
+
+ static const char *g_range_specifiers[];
+
+ //------------------------------------------------------------------
+ /// Takes an input string containing the description of a breakpoint or breakpoint and location
+ /// and returns the breakpoint ID and the breakpoint location id.
+ ///
+ /// @param[in] input
+ /// A string containing JUST the breakpoint description.
+ /// @param[out] break_id
+ /// This is the break id.
+ /// @param[out] break_loc_id
+ /// This is breakpoint location id, or LLDB_INVALID_BREAK_ID is no location was specified.
+ /// @return
+ /// \b true if the call was able to extract a breakpoint location from the string. \b false otherwise.
+ //------------------------------------------------------------------
+ static bool
+ ParseCanonicalReference (const char *input, lldb::break_id_t *break_id, lldb::break_id_t *break_loc_id);
+
+
+ //------------------------------------------------------------------
+ /// Takes a breakpoint ID and the breakpoint location id and returns
+ /// a string containing the canonical description for the breakpoint
+ /// or breakpoint location.
+ ///
+ /// @param[out] break_id
+ /// This is the break id.
+ ///
+ /// @param[out] break_loc_id
+ /// This is breakpoint location id, or LLDB_INVALID_BREAK_ID is no
+ /// location is to be specified.
+ //------------------------------------------------------------------
+ static void
+ GetCanonicalReference (Stream *s, lldb::break_id_t break_id, lldb::break_id_t break_loc_id);
+
+protected:
+ lldb::break_id_t m_break_id;
+ lldb::break_id_t m_location_id;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointID_h_
diff --git a/include/lldb/Breakpoint/BreakpointIDList.h b/include/lldb/Breakpoint/BreakpointIDList.h
new file mode 100644
index 000000000000..c9fcef0a783c
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointIDList.h
@@ -0,0 +1,82 @@
+//===-- BreakpointIDList.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointIDList_h_
+#define liblldb_BreakpointIDList_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private.h"
+#include "lldb/Breakpoint/BreakpointID.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// class BreakpointIDList
+//----------------------------------------------------------------------
+
+
+class BreakpointIDList
+{
+public:
+ typedef std::vector<BreakpointID> BreakpointIDArray;
+
+ BreakpointIDList ();
+
+ virtual
+ ~BreakpointIDList ();
+
+ size_t
+ GetSize();
+
+ BreakpointID &
+ GetBreakpointIDAtIndex (size_t index);
+
+ bool
+ RemoveBreakpointIDAtIndex (size_t index);
+
+ void
+ Clear();
+
+ bool
+ AddBreakpointID (BreakpointID bp_id);
+
+ bool
+ AddBreakpointID (const char *bp_id);
+
+ bool
+ FindBreakpointID (BreakpointID &bp_id, size_t *position);
+
+ bool
+ FindBreakpointID (const char *bp_id, size_t *position);
+
+ void
+ InsertStringArray (const char **string_array, size_t array_size, CommandReturnObject &result);
+
+ static bool
+ StringContainsIDRangeExpression (const char *in_string, size_t *range_start_len, size_t *range_end_pos);
+
+ static void
+ FindAndReplaceIDRanges (Args &old_args, Target *target, CommandReturnObject &result, Args &new_args);
+
+private:
+ BreakpointIDArray m_breakpoint_ids;
+ BreakpointID m_invalid_id;
+
+ DISALLOW_COPY_AND_ASSIGN(BreakpointIDList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointIDList_h_
diff --git a/include/lldb/Breakpoint/BreakpointList.h b/include/lldb/Breakpoint/BreakpointList.h
new file mode 100644
index 000000000000..97eb2b46bc0c
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointList.h
@@ -0,0 +1,193 @@
+//===-- BreakpointList.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointList_h_
+#define liblldb_BreakpointList_h_
+
+// C Includes
+// C++ Includes
+#include <list>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointList BreakpointList.h "lldb/Breakpoint/BreakpointList.h"
+/// @brief This class manages a list of breakpoints.
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+/// General Outline:
+/// Allows adding and removing breakpoints and find by ID and index.
+//----------------------------------------------------------------------
+
+class BreakpointList
+{
+public:
+ BreakpointList (bool is_internal);
+
+ ~BreakpointList();
+
+ //------------------------------------------------------------------
+ /// Add the breakpoint \a bp_sp to the list.
+ ///
+ /// @param[in] bp_sp
+ /// Shared pointer to the breakpoint that will get added to the list.
+ ///
+ /// @result
+ /// Returns breakpoint id.
+ //------------------------------------------------------------------
+ lldb::break_id_t
+ Add (lldb::BreakpointSP& bp_sp, bool notify);
+
+ //------------------------------------------------------------------
+ /// Standard "Dump" method. At present it does nothing.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s) const;
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint with id \a breakID.
+ ///
+ /// @param[in] breakID
+ /// The breakpoint ID to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL pointer if the
+ /// breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ lldb::BreakpointSP
+ FindBreakpointByID (lldb::break_id_t breakID);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint with id \a breakID. Const version.
+ ///
+ /// @param[in] breakID
+ /// The breakpoint ID to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL pointer if the
+ /// breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ const lldb::BreakpointSP
+ FindBreakpointByID (lldb::break_id_t breakID) const;
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint with index \a i.
+ ///
+ /// @param[in] i
+ /// The breakpoint index to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL pointer if the
+ /// breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ lldb::BreakpointSP
+ GetBreakpointAtIndex (size_t i);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint with index \a i, const version
+ ///
+ /// @param[in] i
+ /// The breakpoint index to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL pointer if the
+ /// breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ const lldb::BreakpointSP
+ GetBreakpointAtIndex (size_t i) const;
+
+ //------------------------------------------------------------------
+ /// Returns the number of elements in this breakpoint list.
+ ///
+ /// @result
+ /// The number of elements.
+ //------------------------------------------------------------------
+ size_t
+ GetSize() const
+ {
+ Mutex::Locker locker(m_mutex);
+ return m_breakpoints.size();
+ }
+
+ //------------------------------------------------------------------
+ /// Removes the breakpoint given by \b breakID from this list.
+ ///
+ /// @param[in] breakID
+ /// The breakpoint index to remove.
+ ///
+ /// @result
+ /// \b true if the breakpoint \a breakID was in the list.
+ //------------------------------------------------------------------
+ bool
+ Remove (lldb::break_id_t breakID, bool notify);
+
+ void
+ SetEnabledAll (bool enabled);
+
+ //------------------------------------------------------------------
+ /// Removes all the breakpoints from this list.
+ //------------------------------------------------------------------
+ void
+ RemoveAll (bool notify);
+
+ //------------------------------------------------------------------
+ /// Tell all the breakpoints to update themselves due to a change in the
+ /// modules in \a module_list. \a added says whether the module was loaded
+ /// or unloaded.
+ ///
+ /// @param[in] module_list
+ /// The module list that has changed.
+ ///
+ /// @param[in] added
+ /// \b true if the modules are loaded, \b false if unloaded.
+ //------------------------------------------------------------------
+ void
+ UpdateBreakpoints (ModuleList &module_list, bool added);
+
+ void
+ UpdateBreakpointsWhenModuleIsReplaced (lldb::ModuleSP old_module_sp, lldb::ModuleSP new_module_sp);
+
+ void
+ ClearAllBreakpointSites ();
+
+ //------------------------------------------------------------------
+ /// Sets the passed in Locker to hold the Breakpoint List mutex.
+ ///
+ /// @param[in] locker
+ /// The locker object that is set.
+ //------------------------------------------------------------------
+ void
+ GetListMutex (lldb_private::Mutex::Locker &locker);
+
+protected:
+ typedef std::list<lldb::BreakpointSP> bp_collection;
+
+ bp_collection::iterator
+ GetBreakpointIDIterator(lldb::break_id_t breakID);
+
+ bp_collection::const_iterator
+ GetBreakpointIDConstIterator(lldb::break_id_t breakID) const;
+
+ mutable Mutex m_mutex;
+ bp_collection m_breakpoints; // The breakpoint list, currently a list.
+ lldb::break_id_t m_next_break_id;
+ bool m_is_internal;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (BreakpointList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointList_h_
diff --git a/include/lldb/Breakpoint/BreakpointLocation.h b/include/lldb/Breakpoint/BreakpointLocation.h
new file mode 100644
index 000000000000..9ab0a79c6844
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointLocation.h
@@ -0,0 +1,401 @@
+//===-- BreakpointLocation.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointLocation_h_
+#define liblldb_BreakpointLocation_h_
+
+// C Includes
+
+// C++ Includes
+#include <list>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Breakpoint/StoppointLocation.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Expression/ClangUserExpression.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointLocation BreakpointLocation.h "lldb/Breakpoint/BreakpointLocation.h"
+/// @brief Class that manages one unique (by address) instance of a logical breakpoint.
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+/// General Outline:
+/// A breakpoint location is defined by the breakpoint that produces it,
+/// and the address that resulted in this particular instantiation.
+/// Each breakpoint location also may have a breakpoint site if its
+/// address has been loaded into the program.
+/// Finally it has a settable options object.
+///
+/// FIXME: Should we also store some fingerprint for the location, so
+/// we can map one location to the "equivalent location" on rerun? This
+/// would be useful if you've set options on the locations.
+//----------------------------------------------------------------------
+
+class BreakpointLocation :
+ public std::enable_shared_from_this<BreakpointLocation>,
+ public StoppointLocation
+{
+public:
+
+ ~BreakpointLocation ();
+
+ //------------------------------------------------------------------
+ /// Gets the load address for this breakpoint location
+ /// @return
+ /// Returns breakpoint location load address, \b
+ /// LLDB_INVALID_ADDRESS if not yet set.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetLoadAddress () const;
+
+ //------------------------------------------------------------------
+ /// Gets the Address for this breakpoint location
+ /// @return
+ /// Returns breakpoint location Address.
+ //------------------------------------------------------------------
+ Address &
+ GetAddress ();
+ //------------------------------------------------------------------
+ /// Gets the Breakpoint that created this breakpoint location
+ /// @return
+ /// Returns the owning breakpoint.
+ //------------------------------------------------------------------
+ Breakpoint &
+ GetBreakpoint ();
+
+ //------------------------------------------------------------------
+ /// Determines whether we should stop due to a hit at this
+ /// breakpoint location.
+ ///
+ /// Side Effects: This may evaluate the breakpoint condition, and
+ /// run the callback. So this command may do a considerable amount
+ /// of work.
+ ///
+ /// @return
+ /// \b true if this breakpoint location thinks we should stop,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ShouldStop (StoppointCallbackContext *context);
+
+ //------------------------------------------------------------------
+ // The next section deals with various breakpoint options.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// If \a enable is \b true, enable the breakpoint, if \b false
+ /// disable it.
+ //------------------------------------------------------------------
+ void
+ SetEnabled(bool enabled);
+
+ //------------------------------------------------------------------
+ /// Check the Enable/Disable state.
+ ///
+ /// @return
+ /// \b true if the breakpoint is enabled, \b false if disabled.
+ //------------------------------------------------------------------
+ bool
+ IsEnabled () const;
+
+ //------------------------------------------------------------------
+ /// Return the current Ignore Count.
+ ///
+ /// @return
+ /// The number of breakpoint hits to be ignored.
+ //------------------------------------------------------------------
+ uint32_t
+ GetIgnoreCount ();
+
+ //------------------------------------------------------------------
+ /// Set the breakpoint to ignore the next \a count breakpoint hits.
+ ///
+ /// @param[in] count
+ /// The number of breakpoint hits to ignore.
+ //------------------------------------------------------------------
+ void
+ SetIgnoreCount (uint32_t n);
+
+ //------------------------------------------------------------------
+ /// Set the callback action invoked when the breakpoint is hit.
+ ///
+ /// The callback will return a bool indicating whether the target
+ /// should stop at this breakpoint or not.
+ ///
+ /// @param[in] callback
+ /// The method that will get called when the breakpoint is hit.
+ ///
+ /// @param[in] callback_baton_sp
+ /// A shared pointer to a Baton that provides the void * needed
+ /// for the callback.
+ ///
+ /// @see lldb_private::Baton
+ //------------------------------------------------------------------
+ void
+ SetCallback (BreakpointHitCallback callback,
+ const lldb::BatonSP &callback_baton_sp,
+ bool is_synchronous);
+
+ void
+ SetCallback (BreakpointHitCallback callback,
+ void *baton,
+ bool is_synchronous);
+
+ void
+ ClearCallback ();
+
+ //------------------------------------------------------------------
+ /// Set the breakpoint location's condition.
+ ///
+ /// @param[in] condition
+ /// The condition expression to evaluate when the breakpoint is hit.
+ //------------------------------------------------------------------
+ void
+ SetCondition (const char *condition);
+
+ //------------------------------------------------------------------
+ /// Return a pointer to the text of the condition expression.
+ ///
+ /// @return
+ /// A pointer to the condition expression text, or NULL if no
+ // condition has been set.
+ //------------------------------------------------------------------
+ const char *
+ GetConditionText (size_t *hash = NULL) const;
+
+ bool
+ ConditionSaysStop (ExecutionContext &exe_ctx, Error &error);
+
+
+ //------------------------------------------------------------------
+ /// Set the valid thread to be checked when the breakpoint is hit.
+ ///
+ /// @param[in] thread_id
+ /// If this thread hits the breakpoint, we stop, otherwise not.
+ //------------------------------------------------------------------
+ void
+ SetThreadID (lldb::tid_t thread_id);
+
+ lldb::tid_t
+ GetThreadID ();
+
+ void
+ SetThreadIndex (uint32_t index);
+
+ uint32_t
+ GetThreadIndex() const;
+
+ void
+ SetThreadName (const char *thread_name);
+
+ const char *
+ GetThreadName () const;
+
+ void
+ SetQueueName (const char *queue_name);
+
+ const char *
+ GetQueueName () const;
+
+ //------------------------------------------------------------------
+ // The next section deals with this location's breakpoint sites.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Try to resolve the breakpoint site for this location.
+ ///
+ /// @return
+ /// \b true if we were successful at setting a breakpoint site,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ResolveBreakpointSite ();
+
+ //------------------------------------------------------------------
+ /// Clear this breakpoint location's breakpoint site - for instance
+ /// when disabling the breakpoint.
+ ///
+ /// @return
+ /// \b true if there was a breakpoint site to be cleared, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ ClearBreakpointSite ();
+
+ //------------------------------------------------------------------
+ /// Return whether this breakpoint location has a breakpoint site.
+ /// @return
+ /// \b true if there was a breakpoint site for this breakpoint
+ /// location, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsResolved () const;
+
+ lldb::BreakpointSiteSP
+ GetBreakpointSite() const;
+
+ //------------------------------------------------------------------
+ // The next section are generic report functions.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Print a description of this breakpoint location to the stream
+ /// \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to print the description.
+ ///
+ /// @param[in] level
+ /// The description level that indicates the detail level to
+ /// provide.
+ ///
+ /// @see lldb::DescriptionLevel
+ //------------------------------------------------------------------
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level);
+
+ //------------------------------------------------------------------
+ /// Standard "Dump" method. At present it does nothing.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s) const;
+
+ //------------------------------------------------------------------
+ /// Use this to set location specific breakpoint options.
+ ///
+ /// It will create a copy of the containing breakpoint's options if
+ /// that hasn't been done already
+ ///
+ /// @return
+ /// A pointer to the breakpoint options.
+ //------------------------------------------------------------------
+ BreakpointOptions *
+ GetLocationOptions ();
+
+ //------------------------------------------------------------------
+ /// Use this to access breakpoint options from this breakpoint location.
+ /// This will point to the owning breakpoint's options unless options have
+ /// been set specifically on this location.
+ ///
+ /// @return
+ /// A pointer to the containing breakpoint's options if this
+ /// location doesn't have its own copy.
+ //------------------------------------------------------------------
+ const BreakpointOptions *
+ GetOptionsNoCreate () const;
+
+ bool
+ ValidForThisThread (Thread *thread);
+
+
+ //------------------------------------------------------------------
+ /// Invoke the callback action when the breakpoint is hit.
+ ///
+ /// Meant to be used by the BreakpointLocation class.
+ ///
+ /// @param[in] context
+ /// Described the breakpoint event.
+ ///
+ /// @param[in] bp_loc_id
+ /// Which breakpoint location hit this breakpoint.
+ ///
+ /// @return
+ /// \b true if the target should stop at this breakpoint and \b
+ /// false not.
+ //------------------------------------------------------------------
+ bool
+ InvokeCallback (StoppointCallbackContext *context);
+
+protected:
+ friend class BreakpointLocationList;
+ friend class CommandObjectBreakpointCommandAdd;
+ friend class Process;
+
+ //------------------------------------------------------------------
+ /// Set the breakpoint site for this location to \a bp_site_sp.
+ ///
+ /// @param[in] bp_site_sp
+ /// The breakpoint site we are setting for this location.
+ ///
+ /// @return
+ /// \b true if we were successful at setting the breakpoint site,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ SetBreakpointSite (lldb::BreakpointSiteSP& bp_site_sp);
+
+ void
+ DecrementIgnoreCount();
+
+ bool
+ IgnoreCountShouldStop();
+
+private:
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //
+ // Only the Breakpoint can make breakpoint locations, and it owns
+ // them.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Constructor.
+ ///
+ /// @param[in] owner
+ /// A back pointer to the breakpoint that owns this location.
+ ///
+ /// @param[in] addr
+ /// The Address defining this location.
+ ///
+ /// @param[in] tid
+ /// The thread for which this breakpoint location is valid, or
+ /// LLDB_INVALID_THREAD_ID if it is valid for all threads.
+ ///
+ /// @param[in] hardware
+ /// \b true if a hardware breakpoint is requested.
+ //------------------------------------------------------------------
+
+ BreakpointLocation (lldb::break_id_t bid,
+ Breakpoint &owner,
+ const Address &addr,
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID,
+ bool hardware = false);
+
+ //------------------------------------------------------------------
+ // Data members:
+ //------------------------------------------------------------------
+ bool m_being_created;
+ Address m_address; ///< The address defining this location.
+ Breakpoint &m_owner; ///< The breakpoint that produced this object.
+ std::unique_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, NULL if we're using our breakpoint's options.
+ lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be shared by more than one location.)
+ ClangUserExpression::ClangUserExpressionSP m_user_expression_sp; ///< The compiled expression to use in testing our condition.
+ Mutex m_condition_mutex; ///< Guards parsing and evaluation of the condition, which could be evaluated by multiple processes.
+ size_t m_condition_hash; ///< For testing whether the condition source code changed.
+
+ void
+ SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind);
+
+ DISALLOW_COPY_AND_ASSIGN (BreakpointLocation);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointLocation_h_
diff --git a/include/lldb/Breakpoint/BreakpointLocationCollection.h b/include/lldb/Breakpoint/BreakpointLocationCollection.h
new file mode 100644
index 000000000000..7f6a659323be
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointLocationCollection.h
@@ -0,0 +1,209 @@
+//===-- BreakpointLocationCollection.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointLocationCollection_h_
+#define liblldb_BreakpointLocationCollection_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class BreakpointLocationCollection
+{
+public:
+ BreakpointLocationCollection();
+
+ ~BreakpointLocationCollection();
+
+ //------------------------------------------------------------------
+ /// Add the breakpoint \a bp_loc_sp to the list.
+ ///
+ /// @param[in] bp_sp
+ /// Shared pointer to the breakpoint location that will get added
+ /// to the list.
+ ///
+ /// @result
+ /// Returns breakpoint location id.
+ //------------------------------------------------------------------
+ void
+ Add (const lldb::BreakpointLocationSP& bp_loc_sp);
+
+ //------------------------------------------------------------------
+ /// Removes the breakpoint location given by \b breakID from this
+ /// list.
+ ///
+ /// @param[in] break_id
+ /// The breakpoint index to remove.
+ ///
+ /// @param[in] break_loc_id
+ /// The breakpoint location index in break_id to remove.
+ ///
+ /// @result
+ /// \b true if the breakpoint was in the list.
+ //------------------------------------------------------------------
+ bool
+ Remove (lldb::break_id_t break_id, lldb::break_id_t break_loc_id);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint location with id \a
+ /// breakID.
+ ///
+ /// @param[in] break_id
+ /// The breakpoint ID to seek for.
+ ///
+ /// @param[in] break_loc_id
+ /// The breakpoint location ID in \a break_id to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL
+ /// pointer if the breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ lldb::BreakpointLocationSP
+ FindByIDPair (lldb::break_id_t break_id, lldb::break_id_t break_loc_id);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint location with id \a
+ /// breakID, const version.
+ ///
+ /// @param[in] breakID
+ /// The breakpoint location ID to seek for.
+ ///
+ /// @param[in] break_loc_id
+ /// The breakpoint location ID in \a break_id to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL
+ /// pointer if the breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ const lldb::BreakpointLocationSP
+ FindByIDPair (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const;
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint location with index
+ /// \a i.
+ ///
+ /// @param[in] i
+ /// The breakpoint location index to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL
+ /// pointer if the breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ lldb::BreakpointLocationSP
+ GetByIndex (size_t i);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint location with index
+ /// \a i, const version.
+ ///
+ /// @param[in] i
+ /// The breakpoint location index to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL
+ /// pointer if the breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ const lldb::BreakpointLocationSP
+ GetByIndex (size_t i) const;
+
+ //------------------------------------------------------------------
+ /// Returns the number of elements in this breakpoint location list.
+ ///
+ /// @result
+ /// The number of elements.
+ //------------------------------------------------------------------
+ size_t
+ GetSize() const { return m_break_loc_collection.size(); }
+
+ //------------------------------------------------------------------
+ /// Enquires of all the breakpoint locations in this list whether
+ /// we should stop at a hit at \a breakID.
+ ///
+ /// @param[in] context
+ /// This contains the information about this stop.
+ ///
+ /// @param[in] breakID
+ /// This break ID that we hit.
+ ///
+ /// @return
+ /// \b true if we should stop, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ShouldStop (StoppointCallbackContext *context);
+
+ //------------------------------------------------------------------
+ /// Print a description of the breakpoint locations in this list
+ /// to the stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to print the description.
+ ///
+ /// @param[in] level
+ /// The description level that indicates the detail level to
+ /// provide.
+ ///
+ /// @see lldb::DescriptionLevel
+ //------------------------------------------------------------------
+ void GetDescription (Stream *s, lldb::DescriptionLevel level);
+
+ //------------------------------------------------------------------
+ /// Check whether this collection of breakpoint locations have any
+ /// thread specifiers, and if yes, is \a thread_id contained in any
+ /// of these specifiers.
+ ///
+ /// @param[in] thread
+ /// The thread against which to test.
+ ///
+ /// return
+ /// \b true if the collection contains at least one location that
+ /// would be valid for this thread, false otherwise.
+ //------------------------------------------------------------------
+ bool ValidForThisThread (Thread *thread);
+
+ //------------------------------------------------------------------
+ /// Tell whether ALL the breakpoints in the location collection are internal.
+ ///
+ /// @result
+ /// \b true if all breakpoint locations are owned by internal breakpoints,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool IsInternal() const;
+
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from BreakpointLocationCollection can see
+ // and modify these
+ //------------------------------------------------------------------
+
+private:
+ //------------------------------------------------------------------
+ // For BreakpointLocationCollection only
+ //------------------------------------------------------------------
+
+ typedef std::vector<lldb::BreakpointLocationSP> collection;
+
+ collection::iterator
+ GetIDPairIterator(lldb::break_id_t break_id, lldb::break_id_t break_loc_id);
+
+ collection::const_iterator
+ GetIDPairConstIterator(lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const;
+
+ collection m_break_loc_collection;
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointLocationCollection_h_
diff --git a/include/lldb/Breakpoint/BreakpointLocationList.h b/include/lldb/Breakpoint/BreakpointLocationList.h
new file mode 100644
index 000000000000..1cba23d9118e
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointLocationList.h
@@ -0,0 +1,269 @@
+//===-- BreakpointLocationList.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointLocationList_h_
+#define liblldb_BreakpointLocationList_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+#include <map>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointLocationList BreakpointLocationList.h "lldb/Breakpoint/BreakpointLocationList.h"
+/// @brief This class is used by Breakpoint to manage a list of breakpoint locations,
+// each breakpoint location in the list
+/// has a unique ID, and is unique by Address as well.
+//----------------------------------------------------------------------
+
+class BreakpointLocationList
+{
+// Only Breakpoints can make the location list, or add elements to it.
+// This is not just some random collection of locations. Rather, the act of adding the location
+// to this list sets its ID, and implicitly all the locations have the same breakpoint ID as
+// well. If you need a generic container for breakpoint locations, use BreakpointLocationCollection.
+friend class Breakpoint;
+
+public:
+ virtual
+ ~BreakpointLocationList();
+
+ //------------------------------------------------------------------
+ /// Standard "Dump" method. At present it does nothing.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s) const;
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint location at address
+ /// \a addr - const version.
+ ///
+ /// @param[in] addr
+ /// The address to look for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL
+ /// pointer if the breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ const lldb::BreakpointLocationSP
+ FindByAddress (const Address &addr) const;
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint location with id
+ /// \a breakID, const version.
+ ///
+ /// @param[in] breakID
+ /// The breakpoint location ID to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL
+ /// pointer if the breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ lldb::BreakpointLocationSP
+ FindByID (lldb::break_id_t breakID) const;
+
+ //------------------------------------------------------------------
+ /// Returns the breakpoint location id to the breakpoint location
+ /// at address \a addr.
+ ///
+ /// @param[in] addr
+ /// The address to match.
+ ///
+ /// @result
+ /// The ID of the breakpoint location, or LLDB_INVALID_BREAK_ID.
+ //------------------------------------------------------------------
+ lldb::break_id_t
+ FindIDByAddress (const Address &addr);
+
+ //------------------------------------------------------------------
+ /// Returns a breakpoint location list of the breakpoint locations
+ /// in the module \a module. This list is allocated, and owned by
+ /// the caller.
+ ///
+ /// @param[in] module
+ /// The module to seek in.
+ ///
+ /// @param[in]
+ /// A breakpoint collection that gets any breakpoint locations
+ /// that match \a module appended to.
+ ///
+ /// @result
+ /// The number of matches
+ //------------------------------------------------------------------
+ size_t
+ FindInModule (Module *module,
+ BreakpointLocationCollection& bp_loc_list);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint location with
+ /// index \a i.
+ ///
+ /// @param[in] i
+ /// The breakpoint location index to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL
+ /// pointer if the breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ lldb::BreakpointLocationSP
+ GetByIndex (size_t i);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint location with index
+ /// \a i, const version.
+ ///
+ /// @param[in] i
+ /// The breakpoint location index to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint. May contain a NULL
+ /// pointer if the breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ const lldb::BreakpointLocationSP
+ GetByIndex (size_t i) const;
+
+ //------------------------------------------------------------------
+ /// Removes all the locations in this list from their breakpoint site
+ /// owners list.
+ //------------------------------------------------------------------
+ void
+ ClearAllBreakpointSites ();
+
+ //------------------------------------------------------------------
+ /// Tells all the breakopint locations in this list to attempt to
+ /// resolve any possible breakpoint sites.
+ //------------------------------------------------------------------
+ void
+ ResolveAllBreakpointSites ();
+
+ //------------------------------------------------------------------
+ /// Returns the number of breakpoint locations in this list with
+ /// resolved breakpoints.
+ ///
+ /// @result
+ /// Number of qualifying breakpoint locations.
+ //------------------------------------------------------------------
+ size_t
+ GetNumResolvedLocations() const;
+
+ //------------------------------------------------------------------
+ /// Returns the number hit count of all locations in this list.
+ ///
+ /// @result
+ /// Hit count of all locations in this list.
+ //------------------------------------------------------------------
+ uint32_t
+ GetHitCount () const;
+
+ //------------------------------------------------------------------
+ /// Enquires of the breakpoint location in this list with ID \a
+ /// breakID whether we should stop.
+ ///
+ /// @param[in] context
+ /// This contains the information about this stop.
+ ///
+ /// @param[in] breakID
+ /// This break ID that we hit.
+ ///
+ /// @return
+ /// \b true if we should stop, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ShouldStop (StoppointCallbackContext *context,
+ lldb::break_id_t breakID);
+
+ //------------------------------------------------------------------
+ /// Returns the number of elements in this breakpoint location list.
+ ///
+ /// @result
+ /// The number of elements.
+ //------------------------------------------------------------------
+ size_t
+ GetSize() const
+ {
+ return m_locations.size();
+ }
+
+ //------------------------------------------------------------------
+ /// Print a description of the breakpoint locations in this list to
+ /// the stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to print the description.
+ ///
+ /// @param[in] level
+ /// The description level that indicates the detail level to
+ /// provide.
+ ///
+ /// @see lldb::DescriptionLevel
+ //------------------------------------------------------------------
+ void
+ GetDescription (Stream *s,
+ lldb::DescriptionLevel level);
+
+protected:
+
+ //------------------------------------------------------------------
+ /// This is the standard constructor.
+ ///
+ /// It creates an empty breakpoint location list. It is protected
+ /// here because only Breakpoints are allowed to create the
+ /// breakpoint location list.
+ //------------------------------------------------------------------
+ BreakpointLocationList(Breakpoint &owner);
+
+ //------------------------------------------------------------------
+ /// Add the breakpoint \a bp_loc_sp to the list.
+ ///
+ /// @param[in] bp_sp
+ /// Shared pointer to the breakpoint location that will get
+ /// added to the list.
+ ///
+ /// @result
+ /// Returns breakpoint location id.
+ //------------------------------------------------------------------
+ lldb::BreakpointLocationSP
+ Create (const Address &addr);
+
+ void
+ StartRecordingNewLocations(BreakpointLocationCollection &new_locations);
+
+ void
+ StopRecordingNewLocations();
+
+ lldb::BreakpointLocationSP
+ AddLocation (const Address &addr,
+ bool *new_location = NULL);
+
+ bool
+ RemoveLocation (const lldb::BreakpointLocationSP &bp_loc_sp);
+
+ typedef std::vector<lldb::BreakpointLocationSP> collection;
+ typedef std::map<lldb_private::Address,
+ lldb::BreakpointLocationSP,
+ Address::ModulePointerAndOffsetLessThanFunctionObject> addr_map;
+
+ Breakpoint &m_owner;
+ collection m_locations;
+ addr_map m_address_to_location;
+ mutable Mutex m_mutex;
+ lldb::break_id_t m_next_id;
+ BreakpointLocationCollection *m_new_location_recorder;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointLocationList_h_
diff --git a/include/lldb/Breakpoint/BreakpointOptions.h b/include/lldb/Breakpoint/BreakpointOptions.h
new file mode 100644
index 000000000000..728f5932fa06
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointOptions.h
@@ -0,0 +1,358 @@
+//===-- BreakpointOptions.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointOptions_h_
+#define liblldb_BreakpointOptions_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Baton.h"
+#include "lldb/Core/StringList.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointOptions BreakpointOptions.h "lldb/Breakpoint/BreakpointOptions.h"
+/// @brief Class that manages the options on a breakpoint or breakpoint location.
+//----------------------------------------------------------------------
+
+class BreakpointOptions
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ /// Default constructor. The breakpoint is enabled, and has no condition,
+ /// callback, ignore count, etc...
+ //------------------------------------------------------------------
+ BreakpointOptions();
+ BreakpointOptions(const BreakpointOptions& rhs);
+
+ static BreakpointOptions *
+ CopyOptionsNoCallback (BreakpointOptions &rhs);
+ //------------------------------------------------------------------
+ /// This constructor allows you to specify all the breakpoint options.
+ ///
+ /// @param[in] condition
+ /// The expression which if it evaluates to \b true if we are to stop
+ ///
+ /// @param[in] callback
+ /// This is the plugin for some code that gets run, returns \b true if we are to stop.
+ ///
+ /// @param[in] baton
+ /// Client data that will get passed to the callback.
+ ///
+ /// @param[in] enabled
+ /// Is this breakpoint enabled.
+ ///
+ /// @param[in] ignore
+ /// How many breakpoint hits we should ignore before stopping.
+ ///
+ /// @param[in] thread_id
+ /// Only stop if \a thread_id hits the breakpoint.
+ //------------------------------------------------------------------
+ BreakpointOptions(void *condition,
+ BreakpointHitCallback callback,
+ void *baton,
+ bool enabled = true,
+ int32_t ignore = 0,
+ lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID,
+ bool one_shot = false);
+
+ virtual ~BreakpointOptions();
+
+ //------------------------------------------------------------------
+ // Operators
+ //------------------------------------------------------------------
+ const BreakpointOptions&
+ operator=(const BreakpointOptions& rhs);
+
+ //------------------------------------------------------------------
+ // Callbacks
+ //
+ // Breakpoint callbacks come in two forms, synchronous and asynchronous. Synchronous callbacks will get
+ // run before any of the thread plans are consulted, and if they return false the target will continue
+ // "under the radar" of the thread plans. There are a couple of restrictions to synchronous callbacks:
+ // 1) They should NOT resume the target themselves. Just return false if you want the target to restart.
+ // 2) Breakpoints with synchronous callbacks can't have conditions (or rather, they can have them, but they
+ // won't do anything. Ditto with ignore counts, etc... You are supposed to control that all through the
+ // callback.
+ // Asynchronous callbacks get run as part of the "ShouldStop" logic in the thread plan. The logic there is:
+ // a) If the breakpoint is thread specific and not for this thread, continue w/o running the callback.
+ // b) If the ignore count says we shouldn't stop, then ditto.
+ // c) If the condition says we shouldn't stop, then ditto.
+ // d) Otherwise, the callback will get run, and if it returns true we will stop, and if false we won't.
+ // The asynchronous callback can run the target itself, but at present that should be the last action the
+ // callback does. We will relax this condition at some point, but it will take a bit of plumbing to get
+ // that to work.
+ //
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Adds a callback to the breakpoint option set.
+ ///
+ /// @param[in] callback
+ /// The function to be called when the breakpoint gets hit.
+ ///
+ /// @param[in] baton_sp
+ /// A baton which will get passed back to the callback when it is invoked.
+ ///
+ /// @param[in] synchronous
+ /// Whether this is a synchronous or asynchronous callback. See discussion above.
+ //------------------------------------------------------------------
+ void SetCallback (BreakpointHitCallback callback, const lldb::BatonSP &baton_sp, bool synchronous = false);
+
+
+ //------------------------------------------------------------------
+ /// Remove the callback from this option set.
+ //------------------------------------------------------------------
+ void ClearCallback ();
+
+ // The rest of these functions are meant to be used only within the breakpoint handling mechanism.
+
+ //------------------------------------------------------------------
+ /// Use this function to invoke the callback for a specific stop.
+ ///
+ /// @param[in] context
+ /// The context in which the callback is to be invoked. This includes the stop event, the
+ /// execution context of the stop (since you might hit the same breakpoint on multiple threads) and
+ /// whether we are currently executing synchronous or asynchronous callbacks.
+ ///
+ /// @param[in] break_id
+ /// The breakpoint ID that owns this option set.
+ ///
+ /// @param[in] break_loc_id
+ /// The breakpoint location ID that owns this option set.
+ ///
+ /// @return
+ /// The callback return value.
+ //------------------------------------------------------------------
+ bool InvokeCallback (StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ //------------------------------------------------------------------
+ /// Used in InvokeCallback to tell whether it is the right time to run this kind of callback.
+ ///
+ /// @return
+ /// The synchronicity of our callback.
+ //------------------------------------------------------------------
+ bool IsCallbackSynchronous () {
+ return m_callback_is_synchronous;
+ }
+
+ //------------------------------------------------------------------
+ /// Fetch the baton from the callback.
+ ///
+ /// @return
+ /// The baton.
+ //------------------------------------------------------------------
+ Baton *GetBaton ();
+
+ //------------------------------------------------------------------
+ /// Fetch a const version of the baton from the callback.
+ ///
+ /// @return
+ /// The baton.
+ //------------------------------------------------------------------
+ const Baton *GetBaton () const;
+
+ //------------------------------------------------------------------
+ // Condition
+ //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ /// Set the breakpoint option's condition.
+ ///
+ /// @param[in] condition
+ /// The condition expression to evaluate when the breakpoint is hit.
+ //------------------------------------------------------------------
+ void SetCondition (const char *condition);
+
+ //------------------------------------------------------------------
+ /// Return a pointer to the text of the condition expression.
+ ///
+ /// @return
+ /// A pointer to the condition expression text, or NULL if no
+ // condition has been set.
+ //------------------------------------------------------------------
+ const char *GetConditionText (size_t *hash = NULL) const;
+
+ //------------------------------------------------------------------
+ // Enabled/Ignore Count
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Check the Enable/Disable state.
+ /// @return
+ /// \b true if the breakpoint is enabled, \b false if disabled.
+ //------------------------------------------------------------------
+ bool
+ IsEnabled () const
+ {
+ return m_enabled;
+ }
+
+ //------------------------------------------------------------------
+ /// If \a enable is \b true, enable the breakpoint, if \b false disable it.
+ //------------------------------------------------------------------
+ void
+ SetEnabled (bool enabled)
+ {
+ m_enabled = enabled;
+ }
+
+ //------------------------------------------------------------------
+ /// Check the One-shot state.
+ /// @return
+ /// \b true if the breakpoint is one-shot, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsOneShot () const
+ {
+ return m_one_shot;
+ }
+
+ //------------------------------------------------------------------
+ /// If \a enable is \b true, enable the breakpoint, if \b false disable it.
+ //------------------------------------------------------------------
+ void
+ SetOneShot (bool one_shot)
+ {
+ m_one_shot = one_shot;
+ }
+
+ //------------------------------------------------------------------
+ /// Set the breakpoint to ignore the next \a count breakpoint hits.
+ /// @param[in] count
+ /// The number of breakpoint hits to ignore.
+ //------------------------------------------------------------------
+
+ void
+ SetIgnoreCount (uint32_t n)
+ {
+ m_ignore_count = n;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the current Ignore Count.
+ /// @return
+ /// The number of breakpoint hits to be ignored.
+ //------------------------------------------------------------------
+ uint32_t
+ GetIgnoreCount () const
+ {
+ return m_ignore_count;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the current thread spec for this option. This will return NULL if the no thread
+ /// specifications have been set for this Option yet.
+ /// @return
+ /// The thread specification pointer for this option, or NULL if none has
+ /// been set yet.
+ //------------------------------------------------------------------
+ const ThreadSpec *
+ GetThreadSpecNoCreate () const;
+
+ //------------------------------------------------------------------
+ /// Returns a pointer to the ThreadSpec for this option, creating it.
+ /// if it hasn't been created already. This API is used for setting the
+ /// ThreadSpec items for this option.
+ //------------------------------------------------------------------
+ ThreadSpec *
+ GetThreadSpec ();
+
+ void
+ SetThreadID(lldb::tid_t thread_id);
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+ //------------------------------------------------------------------
+ /// Returns true if the breakpoint option has a callback set.
+ //------------------------------------------------------------------
+ bool
+ HasCallback();
+
+ //------------------------------------------------------------------
+ /// This is the default empty callback.
+ /// @return
+ /// The thread id for which the breakpoint hit will stop,
+ /// LLDB_INVALID_THREAD_ID for all threads.
+ //------------------------------------------------------------------
+ static bool
+ NullCallback (void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+
+ struct CommandData
+ {
+ CommandData () :
+ user_source(),
+ script_source(),
+ stop_on_error(true)
+ {
+ }
+
+ ~CommandData ()
+ {
+ }
+
+ StringList user_source;
+ std::string script_source;
+ bool stop_on_error;
+ };
+
+ class CommandBaton : public Baton
+ {
+ public:
+ CommandBaton (CommandData *data) :
+ Baton (data)
+ {
+ }
+
+ virtual
+ ~CommandBaton ()
+ {
+ delete ((CommandData *)m_data);
+ m_data = NULL;
+ }
+
+ virtual void
+ GetDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+ };
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from BreakpointOptions can see and modify these
+ //------------------------------------------------------------------
+
+private:
+ //------------------------------------------------------------------
+ // For BreakpointOptions only
+ //------------------------------------------------------------------
+ BreakpointHitCallback m_callback; // This is the callback function pointer
+ lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback
+ bool m_callback_is_synchronous;
+ bool m_enabled;
+ bool m_one_shot;
+ uint32_t m_ignore_count; // Number of times to ignore this breakpoint
+ std::unique_ptr<ThreadSpec> m_thread_spec_ap; // Thread for which this breakpoint will take
+ std::string m_condition_text; // The condition to test.
+ size_t m_condition_text_hash; // Its hash, so that locations know when the condition is updated.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointOptions_h_
diff --git a/include/lldb/Breakpoint/BreakpointResolver.h b/include/lldb/Breakpoint/BreakpointResolver.h
new file mode 100644
index 000000000000..3db3795453e8
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointResolver.h
@@ -0,0 +1,147 @@
+//===-- BreakpointResolver.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointResolver_h_
+#define liblldb_BreakpointResolver_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/SearchFilter.h"
+#include "lldb/Core/ConstString.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointResolver BreakpointResolver.h "lldb/Breakpoint/BreakpointResolver.h"
+/// @brief This class works with SearchFilter to resolve logical breakpoints to their
+/// of concrete breakpoint locations.
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+/// General Outline:
+/// The BreakpointResolver is a Searcher. In that protocol,
+/// the SearchFilter asks the question "At what depth of the symbol context
+/// descent do you want your callback to get called?" of the filter. The resolver
+/// answers this question (in the GetDepth method) and provides the resolution callback.
+/// Each Breakpoint has a BreakpointResolver, and it calls either ResolveBreakpoint
+/// or ResolveBreakpointInModules to tell it to look for new breakpoint locations.
+//----------------------------------------------------------------------
+
+class BreakpointResolver :
+ public Searcher
+{
+public:
+ //------------------------------------------------------------------
+ /// The breakpoint resolver need to have a breakpoint for "ResolveBreakpoint
+ /// to make sense. It can be constructed without a breakpoint, but you have to
+ /// call SetBreakpoint before ResolveBreakpoint.
+ ///
+ /// @param[in] bkpt
+ /// The breakpoint that owns this resolver.
+ /// @param[in] resolverType
+ /// The concrete breakpoint resolver type for this breakpoint.
+ ///
+ /// @result
+ /// Returns breakpoint location id.
+ //------------------------------------------------------------------
+ BreakpointResolver (Breakpoint *bkpt, unsigned char resolverType);
+
+ //------------------------------------------------------------------
+ /// The Destructor is virtual, all significant breakpoint resolvers derive
+ /// from this class.
+ //------------------------------------------------------------------
+ virtual
+ ~BreakpointResolver ();
+
+ //------------------------------------------------------------------
+ /// This sets the breakpoint for this resolver.
+ ///
+ /// @param[in] bkpt
+ /// The breakpoint that owns this resolver.
+ //------------------------------------------------------------------
+ void
+ SetBreakpoint (Breakpoint *bkpt);
+
+ //------------------------------------------------------------------
+ /// In response to this method the resolver scans all the modules in the breakpoint's
+ /// target, and adds any new locations it finds.
+ ///
+ /// @param[in] filter
+ /// The filter that will manage the search for this resolver.
+ //------------------------------------------------------------------
+ virtual void
+ ResolveBreakpoint (SearchFilter &filter);
+
+ //------------------------------------------------------------------
+ /// In response to this method the resolver scans the modules in the module list
+ /// \a modules, and adds any new locations it finds.
+ ///
+ /// @param[in] filter
+ /// The filter that will manage the search for this resolver.
+ //------------------------------------------------------------------
+ virtual void
+ ResolveBreakpointInModules (SearchFilter &filter,
+ ModuleList &modules);
+
+ //------------------------------------------------------------------
+ /// Prints a canonical description for the breakpoint to the stream \a s.
+ ///
+ /// @param[in] s
+ /// Stream to which the output is copied.
+ //------------------------------------------------------------------
+ virtual void
+ GetDescription (Stream *s) = 0;
+
+ //------------------------------------------------------------------
+ /// Standard "Dump" method. At present it does nothing.
+ //------------------------------------------------------------------
+ virtual void
+ Dump (Stream *s) const = 0;
+
+ //------------------------------------------------------------------
+ /// An enumeration for keeping track of the concrete subclass that
+ /// is actually instantiated. Values of this enumeration are kept in the
+ /// BreakpointResolver's SubclassID field. They are used for concrete type
+ /// identification.
+ enum ResolverTy {
+ FileLineResolver, // This is an instance of BreakpointResolverFileLine
+ AddressResolver, // This is an instance of BreakpointResolverAddress
+ NameResolver, // This is an instance of BreakpointResolverName
+ FileRegexResolver,
+ ExceptionResolver
+ };
+
+ //------------------------------------------------------------------
+ /// getResolverID - Return an ID for the concrete type of this object. This
+ /// is used to implement the LLVM classof checks. This should not be used
+ /// for any other purpose, as the values may change as LLDB evolves.
+ unsigned getResolverID() const {
+ return SubclassID;
+ }
+
+protected:
+ Breakpoint *m_breakpoint; // This is the breakpoint we add locations to.
+
+private:
+ // Subclass identifier (for llvm isa/dyn_cast)
+ const unsigned char SubclassID;
+ DISALLOW_COPY_AND_ASSIGN(BreakpointResolver);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointResolver_h_
diff --git a/include/lldb/Breakpoint/BreakpointResolverAddress.h b/include/lldb/Breakpoint/BreakpointResolverAddress.h
new file mode 100644
index 000000000000..4ca4a405957e
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointResolverAddress.h
@@ -0,0 +1,74 @@
+//===-- BreakpointResolverAddress.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointResolverAddress_h_
+#define liblldb_BreakpointResolverAddress_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointResolver.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointResolverAddress BreakpointResolverAddress.h "lldb/Breakpoint/BreakpointResolverAddress.h"
+/// @brief This class sets breakpoints on a given Address. This breakpoint only takes
+/// once, and then it won't attempt to reset itself.
+//----------------------------------------------------------------------
+
+class BreakpointResolverAddress:
+ public BreakpointResolver
+{
+public:
+ BreakpointResolverAddress (Breakpoint *bkpt,
+ const Address &addr);
+
+ virtual
+ ~BreakpointResolverAddress ();
+
+ virtual void
+ ResolveBreakpoint (SearchFilter &filter);
+
+ virtual void
+ ResolveBreakpointInModules (SearchFilter &filter,
+ ModuleList &modules);
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing);
+
+ virtual Searcher::Depth
+ GetDepth ();
+
+ virtual void
+ GetDescription (Stream *s);
+
+ virtual void
+ Dump (Stream *s) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BreakpointResolverAddress *) { return true; }
+ static inline bool classof(const BreakpointResolver *V) {
+ return V->getResolverID() == BreakpointResolver::AddressResolver;
+ }
+
+protected:
+ Address m_addr;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(BreakpointResolverAddress);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointResolverAddress_h_
diff --git a/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/include/lldb/Breakpoint/BreakpointResolverFileLine.h
new file mode 100644
index 000000000000..cc1633ce1705
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointResolverFileLine.h
@@ -0,0 +1,74 @@
+//===-- BreakpointResolverFileLine.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointResolverFileLine_h_
+#define liblldb_BreakpointResolverFileLine_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointResolver.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointResolverFileLine BreakpointResolverFileLine.h "lldb/Breakpoint/BreakpointResolverFileLine.h"
+/// @brief This class sets breakpoints by file and line. Optionally, it will look for inlined
+/// instances of the file and line specification.
+//----------------------------------------------------------------------
+
+class BreakpointResolverFileLine :
+ public BreakpointResolver
+{
+public:
+ BreakpointResolverFileLine (Breakpoint *bkpt,
+ const FileSpec &resolver,
+ uint32_t line_no,
+ bool check_inlines,
+ bool skip_prologue);
+
+ virtual
+ ~BreakpointResolverFileLine ();
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing);
+
+ virtual Searcher::Depth
+ GetDepth ();
+
+ virtual void
+ GetDescription (Stream *s);
+
+ virtual void
+ Dump (Stream *s) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BreakpointResolverFileLine *) { return true; }
+ static inline bool classof(const BreakpointResolver *V) {
+ return V->getResolverID() == BreakpointResolver::FileLineResolver;
+ }
+
+protected:
+ friend class Breakpoint;
+ FileSpec m_file_spec; // This is the file spec we are looking for.
+ uint32_t m_line_number; // This is the line number that we are looking for.
+ bool m_inlines; // This determines whether the resolver looks for inlined functions or not.
+ bool m_skip_prologue;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileLine);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointResolverFileLine_h_
diff --git a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
new file mode 100644
index 000000000000..f1c2b1409e92
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
@@ -0,0 +1,68 @@
+//===-- BreakpointResolverFileRegex.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointResolverFileRegex_h_
+#define liblldb_BreakpointResolverFileRegex_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointResolver.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointResolverFileRegex BreakpointResolverFileRegex.h "lldb/Breakpoint/BreakpointResolverFileRegex.h"
+/// @brief This class sets breakpoints by file and line. Optionally, it will look for inlined
+/// instances of the file and line specification.
+//----------------------------------------------------------------------
+
+class BreakpointResolverFileRegex :
+ public BreakpointResolver
+{
+public:
+ BreakpointResolverFileRegex (Breakpoint *bkpt,
+ RegularExpression &regex);
+
+ virtual
+ ~BreakpointResolverFileRegex ();
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing);
+
+ virtual Searcher::Depth
+ GetDepth ();
+
+ virtual void
+ GetDescription (Stream *s);
+
+ virtual void
+ Dump (Stream *s) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BreakpointResolverFileRegex *) { return true; }
+ static inline bool classof(const BreakpointResolver *V) {
+ return V->getResolverID() == BreakpointResolver::FileRegexResolver;
+ }
+
+protected:
+ friend class Breakpoint;
+ RegularExpression m_regex; // This is the line expression that we are looking for.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileRegex);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointResolverFileRegex_h_
diff --git a/include/lldb/Breakpoint/BreakpointResolverName.h b/include/lldb/Breakpoint/BreakpointResolverName.h
new file mode 100644
index 000000000000..f481aa9c5338
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointResolverName.h
@@ -0,0 +1,122 @@
+//===-- BreakpointResolverName.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointResolverName_h_
+#define liblldb_BreakpointResolverName_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+#include <string>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointResolver.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointResolverName BreakpointResolverName.h "lldb/Breakpoint/BreakpointResolverName.h"
+/// @brief This class sets breakpoints on a given function name, either by exact match
+/// or by regular expression.
+//----------------------------------------------------------------------
+
+class BreakpointResolverName:
+ public BreakpointResolver
+{
+public:
+
+ BreakpointResolverName (Breakpoint *bkpt,
+ const char *name,
+ uint32_t name_type_mask,
+ Breakpoint::MatchType type,
+ bool skip_prologue);
+
+ // This one takes an array of names. It is always MatchType = Exact.
+ BreakpointResolverName (Breakpoint *bkpt,
+ const char *names[],
+ size_t num_names,
+ uint32_t name_type_mask,
+ bool skip_prologue);
+
+ // This one takes a C++ array of names. It is always MatchType = Exact.
+ BreakpointResolverName (Breakpoint *bkpt,
+ std::vector<std::string> names,
+ uint32_t name_type_mask,
+ bool skip_prologue);
+
+ // Creates a function breakpoint by regular expression. Takes over control of the lifespan of func_regex.
+ BreakpointResolverName (Breakpoint *bkpt,
+ RegularExpression &func_regex,
+ bool skip_prologue);
+
+ BreakpointResolverName (Breakpoint *bkpt,
+ const char *class_name,
+ const char *method,
+ Breakpoint::MatchType type,
+ bool skip_prologue);
+
+ virtual
+ ~BreakpointResolverName ();
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing);
+
+ virtual Searcher::Depth
+ GetDepth ();
+
+ virtual void
+ GetDescription (Stream *s);
+
+ virtual void
+ Dump (Stream *s) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BreakpointResolverName *) { return true; }
+ static inline bool classof(const BreakpointResolver *V) {
+ return V->getResolverID() == BreakpointResolver::NameResolver;
+ }
+
+protected:
+ struct LookupInfo
+ {
+ ConstString name;
+ ConstString lookup_name;
+ uint32_t name_type_mask; // See FunctionNameType
+ bool match_name_after_lookup;
+
+ LookupInfo () :
+ name(),
+ lookup_name(),
+ name_type_mask (0),
+ match_name_after_lookup (false)
+ {
+ }
+
+ void
+ Prune (SymbolContextList &sc_list,
+ size_t start_idx) const;
+ };
+ std::vector<LookupInfo> m_lookups;
+ ConstString m_class_name;
+ RegularExpression m_regex;
+ Breakpoint::MatchType m_match_type;
+ bool m_skip_prologue;
+
+ void
+ AddNameLookup (const ConstString &name, uint32_t name_type_mask);
+private:
+ DISALLOW_COPY_AND_ASSIGN(BreakpointResolverName);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointResolverName_h_
diff --git a/include/lldb/Breakpoint/BreakpointSite.h b/include/lldb/Breakpoint/BreakpointSite.h
new file mode 100644
index 000000000000..271a23c2e451
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointSite.h
@@ -0,0 +1,295 @@
+//===-- BreakpointSite.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointSite_h_
+#define liblldb_BreakpointSite_h_
+
+// C Includes
+
+// C++ Includes
+#include <list>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Breakpoint/StoppointLocation.h"
+#include "lldb/Breakpoint/BreakpointLocationCollection.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointSite BreakpointSite.h "lldb/Breakpoint/BreakpointSite.h"
+/// @brief Class that manages the actual breakpoint that will be inserted
+/// into the running program.
+///
+/// The BreakpointSite class handles the physical breakpoint that is
+/// actually inserted in the target program. As such, it is also the
+/// one that gets hit, when the program stops. It keeps a list of all
+/// BreakpointLocations that share this phsyical site. When the
+/// breakpoint is hit, all the locations are informed by the breakpoint
+/// site. Breakpoint sites are owned by the process.
+//----------------------------------------------------------------------
+
+class BreakpointSite :
+ public std::enable_shared_from_this<BreakpointSite>,
+ public StoppointLocation
+{
+public:
+
+ enum Type
+ {
+ eSoftware, // Breakpoint opcode has been written to memory and m_saved_opcode
+ // and m_trap_opcode contain the saved and written opcode.
+ eHardware, // Breakpoint site is set as a hardware breakpoint
+ eExternal // Breakpoint site is managed by an external debug nub or
+ // debug interface where memory reads trasparently will not
+ // display any breakpoint opcodes.
+ };
+
+ virtual ~BreakpointSite ();
+
+ //----------------------------------------------------------------------
+ // This section manages the breakpoint traps
+ //----------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Returns the Opcode Bytes for this breakpoint
+ //------------------------------------------------------------------
+ uint8_t *
+ GetTrapOpcodeBytes ();
+
+ //------------------------------------------------------------------
+ /// Returns the Opcode Bytes for this breakpoint - const version
+ //------------------------------------------------------------------
+ const uint8_t *
+ GetTrapOpcodeBytes () const;
+
+ //------------------------------------------------------------------
+ /// Get the size of the trap opcode for this address
+ //------------------------------------------------------------------
+ size_t
+ GetTrapOpcodeMaxByteSize () const;
+
+ //------------------------------------------------------------------
+ /// Sets the trap opcode
+ //------------------------------------------------------------------
+ bool
+ SetTrapOpcode (const uint8_t *trap_opcode,
+ uint32_t trap_opcode_size);
+
+ //------------------------------------------------------------------
+ /// Gets the original instruction bytes that were overwritten by the trap
+ //------------------------------------------------------------------
+ uint8_t *
+ GetSavedOpcodeBytes ();
+
+ //------------------------------------------------------------------
+ /// Gets the original instruction bytes that were overwritten by the trap const version
+ //------------------------------------------------------------------
+ const uint8_t *
+ GetSavedOpcodeBytes () const;
+
+ //------------------------------------------------------------------
+ /// Says whether \a addr and size \a size intersects with the address \a intersect_addr
+ //------------------------------------------------------------------
+ bool
+ IntersectsRange (lldb::addr_t addr,
+ size_t size,
+ lldb::addr_t *intersect_addr,
+ size_t *intersect_size,
+ size_t *opcode_offset) const;
+
+ //------------------------------------------------------------------
+ /// Tells whether the current breakpoint site is enabled or not
+ ///
+ /// This is a low-level enable bit for the breakpoint sites. If a
+ /// breakpoint site has no enabled owners, it should just get
+ /// removed. This enable/disable is for the low-level target code
+ /// to enable and disable breakpoint sites when single stepping,
+ /// etc.
+ //------------------------------------------------------------------
+ bool
+ IsEnabled () const;
+
+ //------------------------------------------------------------------
+ /// Sets whether the current breakpoint site is enabled or not
+ ///
+ /// @param[in] enabled
+ /// \b true if the breakoint is enabled, \b false otherwise.
+ //------------------------------------------------------------------
+ void
+ SetEnabled (bool enabled);
+
+ //------------------------------------------------------------------
+ /// Enquires of the breakpoint locations that produced this breakpoint site whether
+ /// we should stop at this location.
+ ///
+ /// @param[in] context
+ /// This contains the information about this stop.
+ ///
+ /// @return
+ /// \b true if we should stop, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ ShouldStop (StoppointCallbackContext *context);
+
+ //------------------------------------------------------------------
+ /// Standard Dump method
+ ///
+ /// @param[in] context
+ /// The stream to dump this output.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s) const;
+
+ //------------------------------------------------------------------
+ /// The "Owners" are the breakpoint locations that share this
+ /// breakpoint site. The method adds the \a owner to this breakpoint
+ /// site's owner list.
+ ///
+ /// @param[in] context
+ /// \a owner is the Breakpoint Location to add.
+ //------------------------------------------------------------------
+ void
+ AddOwner (const lldb::BreakpointLocationSP &owner);
+
+ //------------------------------------------------------------------
+ /// This method returns the number of breakpoint locations currently
+ /// located at this breakpoint site.
+ ///
+ /// @return
+ /// The number of owners.
+ //------------------------------------------------------------------
+ size_t
+ GetNumberOfOwners ();
+
+ //------------------------------------------------------------------
+ /// This method returns the the breakpoint location at index \a index
+ /// located at this breakpoint site. The owners are listed ordinally
+ /// from 0 to GetNumberOfOwners() - 1 so you can use this method to iterate
+ /// over the owners
+ ///
+ /// @param[in] index
+ /// The index in the list of owners for which you wish the owner location.
+ /// @return
+ /// A shared pointer to the breakpoint location at that index.
+ //------------------------------------------------------------------
+ lldb::BreakpointLocationSP
+ GetOwnerAtIndex (size_t idx);
+
+ //------------------------------------------------------------------
+ /// Check whether the owners of this breakpoint site have any
+ /// thread specifiers, and if yes, is \a thread contained in any
+ /// of these specifiers.
+ ///
+ /// @param[in] thread
+ /// The thread against which to test.
+ ///
+ /// return
+ /// \b true if the collection contains at least one location that
+ /// would be valid for this thread, false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ValidForThisThread (Thread *thread);
+
+
+ //------------------------------------------------------------------
+ /// Print a description of this breakpoint site to the stream \a s.
+ /// GetDescription tells you about the breakpoint site's owners.
+ /// Use BreakpointSite::Dump(Stream *) to get information about the
+ /// breakpoint site itself.
+ ///
+ /// @param[in] s
+ /// The stream to which to print the description.
+ ///
+ /// @param[in] level
+ /// The description level that indicates the detail level to
+ /// provide.
+ ///
+ /// @see lldb::DescriptionLevel
+ //------------------------------------------------------------------
+ void
+ GetDescription (Stream *s,
+ lldb::DescriptionLevel level);
+
+ //------------------------------------------------------------------
+ /// Tell whether a breakpoint has a location at this site.
+ ///
+ /// @param[in] bp_id
+ /// The breakpoint id to query.
+ ///
+ /// @result
+ /// \b true if bp_id has a location that is at this site,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsBreakpointAtThisSite (lldb::break_id_t bp_id);
+
+ //------------------------------------------------------------------
+ /// Tell whether ALL the breakpoints in the location collection are internal.
+ ///
+ /// @result
+ /// \b true if all breakpoint locations are owned by internal breakpoints,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsInternal () const;
+
+ BreakpointSite::Type
+ GetType () const
+ {
+ return m_type;
+ }
+
+ void
+ SetType (BreakpointSite::Type type)
+ {
+ m_type = type;
+ }
+
+private:
+ friend class Process;
+
+ //------------------------------------------------------------------
+ /// The method removes the owner at \a break_loc_id from this breakpoint list.
+ ///
+ /// @param[in] context
+ /// \a break_loc_id is the Breakpoint Location to remove.
+ //------------------------------------------------------------------
+ size_t
+ RemoveOwner (lldb::break_id_t break_id,
+ lldb::break_id_t break_loc_id);
+
+ BreakpointSite::Type m_type;///< The type of this breakpoint site.
+ uint8_t m_saved_opcode[8]; ///< The saved opcode bytes if this breakpoint site uses trap opcodes.
+ uint8_t m_trap_opcode[8]; ///< The opcode that was used to create the breakpoint if it is a software breakpoint site.
+ bool m_enabled; ///< Boolean indicating if this breakpoint site enabled or not.
+
+ // Consider adding an optimization where if there is only one
+ // owner, we don't store a list. The usual case will be only one owner...
+ BreakpointLocationCollection m_owners; ///< This has the BreakpointLocations that share this breakpoint site.
+
+ static lldb::break_id_t
+ GetNextID();
+
+ // Only the Process can create breakpoint sites in
+ // Process::CreateBreakpointSite (lldb::BreakpointLocationSP &, bool).
+ BreakpointSite (BreakpointSiteList *list,
+ const lldb::BreakpointLocationSP& owner,
+ lldb::addr_t m_addr,
+ bool use_hardware);
+
+ DISALLOW_COPY_AND_ASSIGN(BreakpointSite);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointSite_h_
diff --git a/include/lldb/Breakpoint/BreakpointSiteList.h b/include/lldb/Breakpoint/BreakpointSiteList.h
new file mode 100644
index 000000000000..0d4dafc4baab
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointSiteList.h
@@ -0,0 +1,216 @@
+//===-- BreakpointSiteList.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointSiteList_h_
+#define liblldb_BreakpointSiteList_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointSite.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointSiteList BreakpointSiteList.h "lldb/Breakpoint/BreakpointSiteList.h"
+/// @brief Class that manages lists of BreakpointSite shared pointers.
+//----------------------------------------------------------------------
+class BreakpointSiteList
+{
+// At present Process directly accesses the map of BreakpointSites so it can
+// do quick lookups into the map (using GetMap).
+// FIXME: Find a better interface for this.
+friend class Process;
+
+public:
+ //------------------------------------------------------------------
+ /// Default constructor makes an empty list.
+ //------------------------------------------------------------------
+ BreakpointSiteList();
+
+ //------------------------------------------------------------------
+ /// Destructor, currently does nothing.
+ //------------------------------------------------------------------
+ ~BreakpointSiteList();
+
+ //------------------------------------------------------------------
+ /// Add a BreakpointSite to the list.
+ ///
+ /// @param[in] bp_site_sp
+ /// A shared pointer to a breakpoint site being added to the list.
+ ///
+ /// @return
+ /// The ID of the BreakpointSite in the list.
+ //------------------------------------------------------------------
+ lldb::break_id_t
+ Add (const lldb::BreakpointSiteSP& bp_site_sp);
+
+ //------------------------------------------------------------------
+ /// Standard Dump routine, doesn't do anything at present.
+ /// @param[in] s
+ /// Stream into which to dump the description.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s) const;
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint site at address
+ /// \a addr.
+ ///
+ /// @param[in] addr
+ /// The address to look for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint site. May contain a NULL
+ /// pointer if no breakpoint site exists with a matching address.
+ //------------------------------------------------------------------
+ lldb::BreakpointSiteSP
+ FindByAddress (lldb::addr_t addr);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint site with id \a breakID.
+ ///
+ /// @param[in] breakID
+ /// The breakpoint site ID to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint site. May contain a NULL pointer if the
+ /// breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ lldb::BreakpointSiteSP
+ FindByID (lldb::break_id_t breakID);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the breakpoint site with id \a breakID - const version.
+ ///
+ /// @param[in] breakID
+ /// The breakpoint site ID to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the breakpoint site. May contain a NULL pointer if the
+ /// breakpoint doesn't exist.
+ //------------------------------------------------------------------
+ const lldb::BreakpointSiteSP
+ FindByID (lldb::break_id_t breakID) const;
+
+ //------------------------------------------------------------------
+ /// Returns the breakpoint site id to the breakpoint site at address \a addr.
+ ///
+ /// @param[in] addr
+ /// The address to match.
+ ///
+ /// @result
+ /// The ID of the breakpoint site, or LLDB_INVALID_BREAK_ID.
+ //------------------------------------------------------------------
+ lldb::break_id_t
+ FindIDByAddress (lldb::addr_t addr);
+
+ //------------------------------------------------------------------
+ /// Returns whether the breakpoint site \a bp_site_id has \a bp_id
+ // as one of its owners.
+ ///
+ /// @param[in] bp_site_id
+ /// The breakpoint site id to query.
+ ///
+ /// @param[in] bp_id
+ /// The breakpoint id to look for in \a bp_site_id.
+ ///
+ /// @result
+ /// True if \a bp_site_id exists in the site list AND \a bp_id is one of the
+ /// owners of that site.
+ //------------------------------------------------------------------
+ bool
+ BreakpointSiteContainsBreakpoint (lldb::break_id_t bp_site_id, lldb::break_id_t bp_id);
+
+ void
+ ForEach (std::function <void(BreakpointSite *)> const &callback);
+
+ //------------------------------------------------------------------
+ /// Removes the breakpoint site given by \b breakID from this list.
+ ///
+ /// @param[in] breakID
+ /// The breakpoint site index to remove.
+ ///
+ /// @result
+ /// \b true if the breakpoint site \a breakID was in the list.
+ //------------------------------------------------------------------
+ bool
+ Remove (lldb::break_id_t breakID);
+
+ //------------------------------------------------------------------
+ /// Removes the breakpoint site at address \a addr from this list.
+ ///
+ /// @param[in] addr
+ /// The address from which to remove a breakpoint site.
+ ///
+ /// @result
+ /// \b true if \a addr had a breakpoint site to remove from the list.
+ //------------------------------------------------------------------
+ bool
+ RemoveByAddress (lldb::addr_t addr);
+
+ bool
+ FindInRange (lldb::addr_t lower_bound, lldb::addr_t upper_bound, BreakpointSiteList &bp_site_list) const;
+
+ typedef void (*BreakpointSiteSPMapFunc) (lldb::BreakpointSiteSP &bp, void *baton);
+
+ //------------------------------------------------------------------
+ /// Enquires of the breakpoint site on in this list with ID \a breakID whether
+ /// we should stop for the breakpoint or not.
+ ///
+ /// @param[in] context
+ /// This contains the information about this stop.
+ ///
+ /// @param[in] breakID
+ /// This break ID that we hit.
+ ///
+ /// @return
+ /// \b true if we should stop, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ShouldStop (StoppointCallbackContext *context, lldb::break_id_t breakID);
+
+ //------------------------------------------------------------------
+ /// Returns the number of elements in the list.
+ ///
+ /// @result
+ /// The number of elements.
+ //------------------------------------------------------------------
+ size_t
+ GetSize() const
+ {
+ Mutex::Locker locker(m_mutex);
+ return m_bp_site_list.size();
+ }
+
+ bool
+ IsEmpty() const
+ {
+ Mutex::Locker locker(m_mutex);
+ return m_bp_site_list.empty();
+ }
+protected:
+ typedef std::map<lldb::addr_t, lldb::BreakpointSiteSP> collection;
+
+ collection::iterator
+ GetIDIterator(lldb::break_id_t breakID);
+
+ collection::const_iterator
+ GetIDConstIterator(lldb::break_id_t breakID) const;
+
+ mutable Mutex m_mutex;
+ collection m_bp_site_list; // The breakpoint site list.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointSiteList_h_
diff --git a/include/lldb/Breakpoint/Stoppoint.h b/include/lldb/Breakpoint/Stoppoint.h
new file mode 100644
index 000000000000..c294830f15ec
--- /dev/null
+++ b/include/lldb/Breakpoint/Stoppoint.h
@@ -0,0 +1,63 @@
+//===-- Stoppoint.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Stoppoint_h_
+#define liblldb_Stoppoint_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/UserID.h"
+
+namespace lldb_private {
+
+class Stoppoint
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ Stoppoint();
+
+ virtual
+ ~Stoppoint();
+
+ //------------------------------------------------------------------
+ // Methods
+ //------------------------------------------------------------------
+ virtual void
+ Dump (Stream *) = 0;
+
+ virtual bool
+ IsEnabled () = 0;
+
+ virtual void
+ SetEnabled (bool enable) = 0;
+
+ lldb::break_id_t
+ GetID () const;
+
+ void
+ SetID (lldb::break_id_t bid);
+
+protected:
+ lldb::break_id_t m_bid;
+
+private:
+ //------------------------------------------------------------------
+ // For Stoppoint only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (Stoppoint);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Stoppoint_h_
diff --git a/include/lldb/Breakpoint/StoppointCallbackContext.h b/include/lldb/Breakpoint/StoppointCallbackContext.h
new file mode 100644
index 000000000000..78327e291340
--- /dev/null
+++ b/include/lldb/Breakpoint/StoppointCallbackContext.h
@@ -0,0 +1,58 @@
+//===-- StoppointCallbackContext.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StoppointCallbackContext_h_
+#define liblldb_StoppointCallbackContext_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Target/ExecutionContext.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class StoppointCallbackContext StoppointCallbackContext.h "lldb/Breakpoint/StoppointCallbackContext.h"
+/// @brief Class holds the information that a breakpoint callback needs to evaluate this stop.
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+/// General Outline:
+/// When we hit a breakpoint we need to package up whatever information is needed
+/// to evaluate breakpoint commands and conditions. This class is the container of
+/// that information.
+//----------------------------------------------------------------------
+
+class StoppointCallbackContext
+{
+public:
+ StoppointCallbackContext();
+
+ StoppointCallbackContext(Event *event, const ExecutionContext &exe_ctx, bool synchronously = false);
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Sets the event, process and thread to NULL, and the frame index to an
+ /// invalid value.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ Event *event; // This is the event, the callback can modify this to indicate
+ // the meaning of the breakpoint hit
+ ExecutionContextRef exe_ctx_ref; // This tells us where we have stopped, what thread.
+ bool is_synchronous; // Is the callback being executed synchronously with the breakpoint,
+ // or asynchronously as the event is retrieved?
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StoppointCallbackContext_h_
diff --git a/include/lldb/Breakpoint/StoppointLocation.h b/include/lldb/Breakpoint/StoppointLocation.h
new file mode 100644
index 000000000000..ccedc511951d
--- /dev/null
+++ b/include/lldb/Breakpoint/StoppointLocation.h
@@ -0,0 +1,147 @@
+//===-- StoppointLocation.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StoppointLocation_h_
+#define liblldb_StoppointLocation_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/UserID.h"
+// #include "lldb/Breakpoint/BreakpointOptions.h"
+
+namespace lldb_private {
+
+class StoppointLocation
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ StoppointLocation (lldb::break_id_t bid,
+ lldb::addr_t m_addr,
+ bool hardware);
+
+ StoppointLocation (lldb::break_id_t bid,
+ lldb::addr_t m_addr,
+ uint32_t byte_size,
+ bool hardware);
+
+ virtual
+ ~StoppointLocation ();
+
+ //------------------------------------------------------------------
+ // Operators
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ // Methods
+ //------------------------------------------------------------------
+ virtual lldb::addr_t
+ GetLoadAddress() const
+ {
+ return m_addr;
+ }
+
+ virtual void
+ SetLoadAddress (lldb::addr_t addr)
+ {
+ m_addr = addr;
+ }
+
+ uint32_t
+ GetByteSize () const
+ {
+ return m_byte_size;
+ }
+
+ uint32_t
+ GetHitCount () const
+ {
+ return m_hit_count;
+ }
+
+ uint32_t
+ GetHardwareIndex () const
+ {
+ return m_hw_index;
+ }
+
+
+ bool
+ HardwarePreferred () const
+ {
+ return m_hw_preferred;
+ }
+
+ virtual bool
+ IsHardware () const
+ {
+ return m_hw_index != LLDB_INVALID_INDEX32;
+ }
+
+
+ virtual bool
+ ShouldStop (StoppointCallbackContext *context)
+ {
+ return true;
+ }
+
+ virtual void
+ Dump (Stream *stream) const
+ {
+ }
+
+ void
+ SetHardwareIndex (uint32_t index)
+ {
+ m_hw_index = index;
+ }
+
+
+ lldb::break_id_t
+ GetID () const
+ {
+ return m_loc_id;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from StoppointLocation can see and modify these
+ //------------------------------------------------------------------
+ lldb::break_id_t m_loc_id; // Stoppoint location ID
+ lldb::addr_t m_addr; // The load address of this stop point. The base Stoppoint doesn't
+ // store a full Address since that's not needed for the breakpoint sites.
+ bool m_hw_preferred; // 1 if this point has been requested to be set using hardware (which may fail due to lack of resources)
+ uint32_t m_hw_index; // The hardware resource index for this breakpoint/watchpoint
+ uint32_t m_byte_size; // The size in bytes of stop location. e.g. the length of the trap opcode for
+ // software breakpoints, or the optional length in bytes for
+ // hardware breakpoints, or the length of the watchpoint.
+ uint32_t m_hit_count; // Number of times this breakpoint/watchpoint has been hit
+
+ // If you override this, be sure to call the base class to increment the internal counter.
+ void
+ IncrementHitCount ()
+ {
+ ++m_hit_count;
+ }
+
+private:
+ //------------------------------------------------------------------
+ // For StoppointLocation only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(StoppointLocation);
+ StoppointLocation(); // Disallow default constructor
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StoppointLocation_h_
diff --git a/include/lldb/Breakpoint/Watchpoint.h b/include/lldb/Breakpoint/Watchpoint.h
new file mode 100644
index 000000000000..5dbed03d5406
--- /dev/null
+++ b/include/lldb/Breakpoint/Watchpoint.h
@@ -0,0 +1,252 @@
+//===-- Watchpoint.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Watchpoint_h_
+#define liblldb_Watchpoint_h_
+
+// C Includes
+
+// C++ Includes
+#include <list>
+#include <string>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Breakpoint/WatchpointOptions.h"
+#include "lldb/Breakpoint/StoppointLocation.h"
+
+namespace lldb_private {
+
+class Watchpoint :
+ public std::enable_shared_from_this<Watchpoint>,
+ public StoppointLocation
+{
+public:
+
+ class WatchpointEventData :
+ public EventData
+ {
+ public:
+
+ static const ConstString &
+ GetFlavorString ();
+
+ virtual const ConstString &
+ GetFlavor () const;
+
+ WatchpointEventData (lldb::WatchpointEventType sub_type,
+ const lldb::WatchpointSP &new_watchpoint_sp);
+
+ virtual
+ ~WatchpointEventData();
+
+ lldb::WatchpointEventType
+ GetWatchpointEventType () const;
+
+ lldb::WatchpointSP &
+ GetWatchpoint ();
+
+ virtual void
+ Dump (Stream *s) const;
+
+ static lldb::WatchpointEventType
+ GetWatchpointEventTypeFromEvent (const lldb::EventSP &event_sp);
+
+ static lldb::WatchpointSP
+ GetWatchpointFromEvent (const lldb::EventSP &event_sp);
+
+ static const WatchpointEventData *
+ GetEventDataFromEvent (const Event *event_sp);
+
+ private:
+
+ lldb::WatchpointEventType m_watchpoint_event;
+ lldb::WatchpointSP m_new_watchpoint_sp;
+
+ DISALLOW_COPY_AND_ASSIGN (WatchpointEventData);
+ };
+
+ Watchpoint (Target& target, lldb::addr_t addr, uint32_t size, const ClangASTType *type, bool hardware = true);
+ ~Watchpoint ();
+
+ void
+ IncrementFalseAlarmsAndReviseHitCount();
+
+ bool
+ IsEnabled () const;
+
+ void
+ SetEnabled (bool enabled, bool notify = true);
+
+ virtual bool
+ IsHardware () const;
+
+ virtual bool
+ ShouldStop (StoppointCallbackContext *context);
+
+ bool WatchpointRead () const;
+ bool WatchpointWrite () const;
+ uint32_t GetIgnoreCount () const;
+ void SetIgnoreCount (uint32_t n);
+ void SetWatchpointType (uint32_t type, bool notify = true);
+ void SetDeclInfo (const std::string &str);
+ std::string GetWatchSpec();
+ void SetWatchSpec (const std::string &str);
+
+ // Snapshot management interface.
+ bool IsWatchVariable() const;
+ void SetWatchVariable(bool val);
+ bool CaptureWatchedValue (const ExecutionContext &exe_ctx);
+
+ void GetDescription (Stream *s, lldb::DescriptionLevel level);
+ void Dump (Stream *s) const;
+ void DumpSnapshots (Stream *s, const char * prefix = NULL) const;
+ void DumpWithLevel (Stream *s, lldb::DescriptionLevel description_level) const;
+ Target &GetTarget() { return m_target; }
+ const Error &GetError() { return m_error; }
+
+ //------------------------------------------------------------------
+ /// Returns the WatchpointOptions structure set for this watchpoint.
+ ///
+ /// @return
+ /// A pointer to this watchpoint's WatchpointOptions.
+ //------------------------------------------------------------------
+ WatchpointOptions *
+ GetOptions () { return &m_options; }
+
+ //------------------------------------------------------------------
+ /// Set the callback action invoked when the watchpoint is hit.
+ ///
+ /// @param[in] callback
+ /// The method that will get called when the watchpoint is hit.
+ /// @param[in] callback_baton
+ /// A void * pointer that will get passed back to the callback function.
+ /// @param[in] is_synchronous
+ /// If \b true the callback will be run on the private event thread
+ /// before the stop event gets reported. If false, the callback will get
+ /// handled on the public event thead after the stop has been posted.
+ ///
+ /// @return
+ /// \b true if the process should stop when you hit the watchpoint.
+ /// \b false if it should continue.
+ //------------------------------------------------------------------
+ void
+ SetCallback (WatchpointHitCallback callback,
+ void *callback_baton,
+ bool is_synchronous = false);
+
+ void
+ SetCallback (WatchpointHitCallback callback,
+ const lldb::BatonSP &callback_baton_sp,
+ bool is_synchronous = false);
+
+ void ClearCallback();
+
+ //------------------------------------------------------------------
+ /// Invoke the callback action when the watchpoint is hit.
+ ///
+ /// @param[in] context
+ /// Described the watchpoint event.
+ ///
+ /// @return
+ /// \b true if the target should stop at this watchpoint and \b false not.
+ //------------------------------------------------------------------
+ bool
+ InvokeCallback (StoppointCallbackContext *context);
+
+ //------------------------------------------------------------------
+ // Condition
+ //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ /// Set the watchpoint's condition.
+ ///
+ /// @param[in] condition
+ /// The condition expression to evaluate when the watchpoint is hit.
+ /// Pass in NULL to clear the condition.
+ //------------------------------------------------------------------
+ void SetCondition (const char *condition);
+
+ //------------------------------------------------------------------
+ /// Return a pointer to the text of the condition expression.
+ ///
+ /// @return
+ /// A pointer to the condition expression text, or NULL if no
+ // condition has been set.
+ //------------------------------------------------------------------
+ const char *GetConditionText () const;
+
+ void
+ TurnOnEphemeralMode();
+
+ void
+ TurnOffEphemeralMode();
+
+ bool
+ IsDisabledDuringEphemeralMode();
+
+ const ClangASTType &
+ GetClangASTType()
+ {
+ return m_type;
+ }
+
+
+private:
+ friend class Target;
+ friend class WatchpointList;
+
+ void ResetHitCount() { m_hit_count = 0; }
+
+ Target &m_target;
+ bool m_enabled; // Is this watchpoint enabled
+ bool m_is_hardware; // Is this a hardware watchpoint
+ bool m_is_watch_variable; // True if set via 'watchpoint set variable'.
+ bool m_is_ephemeral; // True if the watchpoint is in the ephemeral mode, meaning that it is
+ // undergoing a pair of temporary disable/enable actions to avoid recursively
+ // triggering further watchpoint events.
+ uint32_t m_disabled_count; // Keep track of the count that the watchpoint is disabled while in ephemeral mode.
+ // At the end of the ephemeral mode when the watchpoint is to be enabled agian,
+ // we check the count, if it is more than 1, it means the user-supplied actions
+ // actually want the watchpoint to be disabled!
+ uint32_t m_watch_read:1, // 1 if we stop when the watched data is read from
+ m_watch_write:1, // 1 if we stop when the watched data is written to
+ m_watch_was_read:1, // Set to 1 when watchpoint is hit for a read access
+ m_watch_was_written:1; // Set to 1 when watchpoint is hit for a write access
+ uint32_t m_ignore_count; // Number of times to ignore this watchpoint
+ uint32_t m_false_alarms; // Number of false alarms.
+ std::string m_decl_str; // Declaration information, if any.
+ std::string m_watch_spec_str; // Spec for the watchpoint.
+ lldb::ValueObjectSP m_old_value_sp;
+ lldb::ValueObjectSP m_new_value_sp;
+ ClangASTType m_type;
+ Error m_error; // An error object describing errors associated with this watchpoint.
+ WatchpointOptions m_options; // Settable watchpoint options, which is a delegate to handle
+ // the callback machinery.
+ bool m_being_created;
+
+ std::unique_ptr<ClangUserExpression> m_condition_ap; // The condition to test.
+
+ void SetID(lldb::watch_id_t id) { m_loc_id = id; }
+
+ void
+ SendWatchpointChangedEvent (lldb::WatchpointEventType eventKind);
+
+ void
+ SendWatchpointChangedEvent (WatchpointEventData *data);
+
+ DISALLOW_COPY_AND_ASSIGN (Watchpoint);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Watchpoint_h_
diff --git a/include/lldb/Breakpoint/WatchpointList.h b/include/lldb/Breakpoint/WatchpointList.h
new file mode 100644
index 000000000000..d16cb25e3b7d
--- /dev/null
+++ b/include/lldb/Breakpoint/WatchpointList.h
@@ -0,0 +1,276 @@
+//===-- WatchpointList.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_WatchpointList_h_
+#define liblldb_WatchpointList_h_
+
+// C Includes
+// C++ Includes
+#include <list>
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class WatchpointList WatchpointList.h "lldb/Breakpoint/WatchpointList.h"
+/// @brief This class is used by Watchpoint to manage a list of watchpoints,
+// each watchpoint in the list has a unique ID, and is unique by Address as
+// well.
+//----------------------------------------------------------------------
+
+class WatchpointList
+{
+// Only Target can make the watchpoint list, or add elements to it.
+// This is not just some random collection of watchpoints. Rather, the act of
+// adding the watchpoint to this list sets its ID.
+friend class Watchpoint;
+friend class Target;
+
+public:
+ //------------------------------------------------------------------
+ /// Default constructor makes an empty list.
+ //------------------------------------------------------------------
+ WatchpointList();
+
+ //------------------------------------------------------------------
+ /// Destructor, currently does nothing.
+ //------------------------------------------------------------------
+ ~WatchpointList();
+
+ //------------------------------------------------------------------
+ /// Add a Watchpoint to the list.
+ ///
+ /// @param[in] wp_sp
+ /// A shared pointer to a watchpoint being added to the list.
+ ///
+ /// @return
+ /// The ID of the Watchpoint in the list.
+ //------------------------------------------------------------------
+ lldb::watch_id_t
+ Add (const lldb::WatchpointSP& wp_sp, bool notify);
+
+ //------------------------------------------------------------------
+ /// Standard "Dump" method.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s) const;
+
+ //------------------------------------------------------------------
+ /// Dump with lldb::DescriptionLevel.
+ //------------------------------------------------------------------
+ void
+ DumpWithLevel (Stream *s, lldb::DescriptionLevel description_level) const;
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the watchpoint at address
+ /// \a addr -
+ /// const version.
+ ///
+ /// @param[in] addr
+ /// The address to look for.
+ ///
+ /// @result
+ /// A shared pointer to the watchpoint. May contain a NULL
+ /// pointer if the watchpoint doesn't exist.
+ //------------------------------------------------------------------
+ const lldb::WatchpointSP
+ FindByAddress (lldb::addr_t addr) const;
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the watchpoint with watchpoint spec
+ /// \a spec -
+ /// const version.
+ ///
+ /// @param[in] spec
+ /// The watchpoint spec to look for.
+ ///
+ /// @result
+ /// A shared pointer to the watchpoint. May contain a NULL
+ /// pointer if the watchpoint doesn't exist.
+ //------------------------------------------------------------------
+ const lldb::WatchpointSP
+ FindBySpec (std::string spec) const;
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the watchpoint with id
+ /// \a watchID, const
+ /// version.
+ ///
+ /// @param[in] watchID
+ /// The watchpoint location ID to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the watchpoint. May contain a NULL
+ /// pointer if the watchpoint doesn't exist.
+ //------------------------------------------------------------------
+ lldb::WatchpointSP
+ FindByID (lldb::watch_id_t watchID) const;
+
+ //------------------------------------------------------------------
+ /// Returns the watchpoint id to the watchpoint
+ /// at address \a addr.
+ ///
+ /// @param[in] addr
+ /// The address to match.
+ ///
+ /// @result
+ /// The ID of the watchpoint, or LLDB_INVALID_WATCH_ID.
+ //------------------------------------------------------------------
+ lldb::watch_id_t
+ FindIDByAddress (lldb::addr_t addr);
+
+ //------------------------------------------------------------------
+ /// Returns the watchpoint id to the watchpoint
+ /// with watchpoint spec \a spec.
+ ///
+ /// @param[in] spec
+ /// The watchpoint spec to match.
+ ///
+ /// @result
+ /// The ID of the watchpoint, or LLDB_INVALID_WATCH_ID.
+ //------------------------------------------------------------------
+ lldb::watch_id_t
+ FindIDBySpec (std::string spec);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the watchpoint with index \a i.
+ ///
+ /// @param[in] i
+ /// The watchpoint index to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the watchpoint. May contain a NULL pointer if
+ /// the watchpoint doesn't exist.
+ //------------------------------------------------------------------
+ lldb::WatchpointSP
+ GetByIndex (uint32_t i);
+
+ //------------------------------------------------------------------
+ /// Returns a shared pointer to the watchpoint with index \a i, const
+ /// version.
+ ///
+ /// @param[in] i
+ /// The watchpoint index to seek for.
+ ///
+ /// @result
+ /// A shared pointer to the watchpoint. May contain a NULL pointer if
+ /// the watchpoint location doesn't exist.
+ //------------------------------------------------------------------
+ const lldb::WatchpointSP
+ GetByIndex (uint32_t i) const;
+
+ //------------------------------------------------------------------
+ /// Removes the watchpoint given by \b watchID from this list.
+ ///
+ /// @param[in] watchID
+ /// The watchpoint ID to remove.
+ ///
+ /// @result
+ /// \b true if the watchpoint \a watchID was in the list.
+ //------------------------------------------------------------------
+ bool
+ Remove (lldb::watch_id_t watchID, bool notify);
+
+ //------------------------------------------------------------------
+ /// Returns the number hit count of all watchpoints in this list.
+ ///
+ /// @result
+ /// Hit count of all watchpoints in this list.
+ //------------------------------------------------------------------
+ uint32_t
+ GetHitCount () const;
+
+ //------------------------------------------------------------------
+ /// Enquires of the watchpoint in this list with ID \a watchID whether we
+ /// should stop.
+ ///
+ /// @param[in] context
+ /// This contains the information about this stop.
+ ///
+ /// @param[in] watchID
+ /// This watch ID that we hit.
+ ///
+ /// @return
+ /// \b true if we should stop, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ShouldStop (StoppointCallbackContext *context,
+ lldb::watch_id_t watchID);
+
+ //------------------------------------------------------------------
+ /// Returns the number of elements in this watchpoint list.
+ ///
+ /// @result
+ /// The number of elements.
+ //------------------------------------------------------------------
+ size_t
+ GetSize() const
+ {
+ Mutex::Locker locker(m_mutex);
+ return m_watchpoints.size();
+ }
+
+ //------------------------------------------------------------------
+ /// Print a description of the watchpoints in this list to the stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to print the description.
+ ///
+ /// @param[in] level
+ /// The description level that indicates the detail level to
+ /// provide.
+ ///
+ /// @see lldb::DescriptionLevel
+ //------------------------------------------------------------------
+ void
+ GetDescription (Stream *s,
+ lldb::DescriptionLevel level);
+
+ void
+ SetEnabledAll (bool enabled);
+
+ void
+ RemoveAll (bool notify);
+
+ //------------------------------------------------------------------
+ /// Sets the passed in Locker to hold the Watchpoint List mutex.
+ ///
+ /// @param[in] locker
+ /// The locker object that is set.
+ //------------------------------------------------------------------
+ void
+ GetListMutex (lldb_private::Mutex::Locker &locker);
+
+protected:
+ typedef std::list<lldb::WatchpointSP> wp_collection;
+ typedef std::vector<lldb::watch_id_t> id_vector;
+
+ id_vector
+ GetWatchpointIDs() const;
+
+ wp_collection::iterator
+ GetIDIterator(lldb::watch_id_t watchID);
+
+ wp_collection::const_iterator
+ GetIDConstIterator(lldb::watch_id_t watchID) const;
+
+ wp_collection m_watchpoints;
+ mutable Mutex m_mutex;
+
+ lldb::watch_id_t m_next_wp_id;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_WatchpointList_h_
diff --git a/include/lldb/Breakpoint/WatchpointOptions.h b/include/lldb/Breakpoint/WatchpointOptions.h
new file mode 100644
index 000000000000..64c65f92b44f
--- /dev/null
+++ b/include/lldb/Breakpoint/WatchpointOptions.h
@@ -0,0 +1,255 @@
+//===-- WatchpointOptions.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_WatchpointOptions_h_
+#define liblldb_WatchpointOptions_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Baton.h"
+#include "lldb/Core/StringList.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class WatchpointOptions WatchpointOptions.h "lldb/Breakpoint/WatchpointOptions.h"
+/// @brief Class that manages the options on a watchpoint.
+//----------------------------------------------------------------------
+
+class WatchpointOptions
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ /// Default constructor. The watchpoint is enabled, and has no condition,
+ /// callback, ignore count, etc...
+ //------------------------------------------------------------------
+ WatchpointOptions();
+ WatchpointOptions(const WatchpointOptions& rhs);
+
+ static WatchpointOptions *
+ CopyOptionsNoCallback (WatchpointOptions &rhs);
+ //------------------------------------------------------------------
+ /// This constructor allows you to specify all the watchpoint options.
+ ///
+ /// @param[in] callback
+ /// This is the plugin for some code that gets run, returns \b true if we are to stop.
+ ///
+ /// @param[in] baton
+ /// Client data that will get passed to the callback.
+ ///
+ /// @param[in] thread_id
+ /// Only stop if \a thread_id hits the watchpoint.
+ //------------------------------------------------------------------
+ WatchpointOptions(WatchpointHitCallback callback,
+ void *baton,
+ lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID);
+
+ virtual ~WatchpointOptions();
+
+ //------------------------------------------------------------------
+ // Operators
+ //------------------------------------------------------------------
+ const WatchpointOptions&
+ operator=(const WatchpointOptions& rhs);
+
+ //------------------------------------------------------------------
+ // Callbacks
+ //
+ // Watchpoint callbacks come in two forms, synchronous and asynchronous. Synchronous callbacks will get
+ // run before any of the thread plans are consulted, and if they return false the target will continue
+ // "under the radar" of the thread plans. There are a couple of restrictions to synchronous callbacks:
+ // 1) They should NOT resume the target themselves. Just return false if you want the target to restart.
+ // 2) Watchpoints with synchronous callbacks can't have conditions (or rather, they can have them, but they
+ // won't do anything. Ditto with ignore counts, etc... You are supposed to control that all through the
+ // callback.
+ // Asynchronous callbacks get run as part of the "ShouldStop" logic in the thread plan. The logic there is:
+ // a) If the watchpoint is thread specific and not for this thread, continue w/o running the callback.
+ // b) If the ignore count says we shouldn't stop, then ditto.
+ // c) If the condition says we shouldn't stop, then ditto.
+ // d) Otherwise, the callback will get run, and if it returns true we will stop, and if false we won't.
+ // The asynchronous callback can run the target itself, but at present that should be the last action the
+ // callback does. We will relax this condition at some point, but it will take a bit of plumbing to get
+ // that to work.
+ //
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Adds a callback to the watchpoint option set.
+ ///
+ /// @param[in] callback
+ /// The function to be called when the watchpoint gets hit.
+ ///
+ /// @param[in] baton_sp
+ /// A baton which will get passed back to the callback when it is invoked.
+ ///
+ /// @param[in] synchronous
+ /// Whether this is a synchronous or asynchronous callback. See discussion above.
+ //------------------------------------------------------------------
+ void SetCallback (WatchpointHitCallback callback, const lldb::BatonSP &baton_sp, bool synchronous = false);
+
+
+ //------------------------------------------------------------------
+ /// Remove the callback from this option set.
+ //------------------------------------------------------------------
+ void ClearCallback ();
+
+ // The rest of these functions are meant to be used only within the watchpoint handling mechanism.
+
+ //------------------------------------------------------------------
+ /// Use this function to invoke the callback for a specific stop.
+ ///
+ /// @param[in] context
+ /// The context in which the callback is to be invoked. This includes the stop event, the
+ /// execution context of the stop (since you might hit the same watchpoint on multiple threads) and
+ /// whether we are currently executing synchronous or asynchronous callbacks.
+ ///
+ /// @param[in] watch_id
+ /// The watchpoint ID that owns this option set.
+ ///
+ /// @return
+ /// The callback return value.
+ //------------------------------------------------------------------
+ bool InvokeCallback (StoppointCallbackContext *context, lldb::user_id_t watch_id);
+
+ //------------------------------------------------------------------
+ /// Used in InvokeCallback to tell whether it is the right time to run this kind of callback.
+ ///
+ /// @return
+ /// The synchronicity of our callback.
+ //------------------------------------------------------------------
+ bool IsCallbackSynchronous () {
+ return m_callback_is_synchronous;
+ }
+
+ //------------------------------------------------------------------
+ /// Fetch the baton from the callback.
+ ///
+ /// @return
+ /// The baton.
+ //------------------------------------------------------------------
+ Baton *GetBaton ();
+
+ //------------------------------------------------------------------
+ /// Fetch a const version of the baton from the callback.
+ ///
+ /// @return
+ /// The baton.
+ //------------------------------------------------------------------
+ const Baton *GetBaton () const;
+
+ //------------------------------------------------------------------
+ /// Return the current thread spec for this option. This will return NULL if the no thread
+ /// specifications have been set for this Option yet.
+ /// @return
+ /// The thread specification pointer for this option, or NULL if none has
+ /// been set yet.
+ //------------------------------------------------------------------
+ const ThreadSpec *
+ GetThreadSpecNoCreate () const;
+
+ //------------------------------------------------------------------
+ /// Returns a pointer to the ThreadSpec for this option, creating it.
+ /// if it hasn't been created already. This API is used for setting the
+ /// ThreadSpec items for this option.
+ //------------------------------------------------------------------
+ ThreadSpec *
+ GetThreadSpec ();
+
+ void
+ SetThreadID(lldb::tid_t thread_id);
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+ //------------------------------------------------------------------
+ /// Get description for callback only.
+ //------------------------------------------------------------------
+ void
+ GetCallbackDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+ //------------------------------------------------------------------
+ /// Returns true if the watchpoint option has a callback set.
+ //------------------------------------------------------------------
+ bool
+ HasCallback();
+
+ //------------------------------------------------------------------
+ /// This is the default empty callback.
+ /// @return
+ /// The thread id for which the watchpoint hit will stop,
+ /// LLDB_INVALID_THREAD_ID for all threads.
+ //------------------------------------------------------------------
+ static bool
+ NullCallback (void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t watch_id);
+
+
+ struct CommandData
+ {
+ CommandData () :
+ user_source(),
+ script_source(),
+ stop_on_error(true)
+ {
+ }
+
+ ~CommandData ()
+ {
+ }
+
+ StringList user_source;
+ std::string script_source;
+ bool stop_on_error;
+ };
+
+ class CommandBaton : public Baton
+ {
+ public:
+ CommandBaton (CommandData *data) :
+ Baton (data)
+ {
+ }
+
+ virtual
+ ~CommandBaton ()
+ {
+ delete ((CommandData *)m_data);
+ m_data = NULL;
+ }
+
+ virtual void
+ GetDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+ };
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from WatchpointOptions can see and modify these
+ //------------------------------------------------------------------
+
+private:
+ //------------------------------------------------------------------
+ // For WatchpointOptions only
+ //------------------------------------------------------------------
+ WatchpointHitCallback m_callback; // This is the callback function pointer
+ lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback
+ bool m_callback_is_synchronous;
+ std::unique_ptr<ThreadSpec> m_thread_spec_ap; // Thread for which this watchpoint will take
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_WatchpointOptions_h_
diff --git a/include/lldb/Core/Address.h b/include/lldb/Core/Address.h
new file mode 100644
index 000000000000..60cd4a86bd4a
--- /dev/null
+++ b/include/lldb/Core/Address.h
@@ -0,0 +1,570 @@
+//===-- Address.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Address_h_
+#define liblldb_Address_h_
+
+// C Includes
+// C++ Includes
+#include <atomic>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Symbol/SymbolContextScope.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Address Address.h "lldb/Core/Address.h"
+/// @brief A section + offset based address class.
+///
+/// The Address class allows addresses to be relative to a section
+/// that can move during runtime due to images (executables, shared
+/// libraries, bundles, frameworks) being loaded at different
+/// addresses than the addresses found in the object file that
+/// represents them on disk. There are currently two types of addresses
+/// for a section:
+/// @li file addresses
+/// @li load addresses
+///
+/// File addresses represent the virtual addresses that are in the "on
+/// disk" object files. These virtual addresses are converted to be
+/// relative to unique sections scoped to the object file so that
+/// when/if the addresses slide when the images are loaded/unloaded
+/// in memory, we can easily track these changes without having to
+/// update every object (compile unit ranges, line tables, function
+/// address ranges, lexical block and inlined subroutine address
+/// ranges, global and static variables) each time an image is loaded or
+/// unloaded.
+///
+/// Load addresses represent the virtual addresses where each section
+/// ends up getting loaded at runtime. Before executing a program, it
+/// is common for all of the load addresses to be unresolved. When a
+/// DynamicLoader plug-in receives notification that shared libraries
+/// have been loaded/unloaded, the load addresses of the main executable
+/// and any images (shared libraries) will be resolved/unresolved. When
+/// this happens, breakpoints that are in one of these sections can be
+/// set/cleared.
+//----------------------------------------------------------------------
+class Address
+{
+public:
+ //------------------------------------------------------------------
+ /// Dump styles allow the Address::Dump(Stream *,DumpStyle) const
+ /// function to display Address contents in a variety of ways.
+ //------------------------------------------------------------------
+ typedef enum {
+ DumpStyleInvalid, ///< Invalid dump style
+ DumpStyleSectionNameOffset, ///< Display as the section name + offset.
+ ///< \code
+ /// // address for printf in libSystem.B.dylib as a section name + offset
+ /// libSystem.B.dylib.__TEXT.__text + 0x0005cfdf
+ /// \endcode
+ DumpStyleSectionPointerOffset, ///< Display as the section pointer + offset (debug output).
+ ///< \code
+ /// // address for printf in libSystem.B.dylib as a section pointer + offset
+ /// (lldb::Section *)0x35cc50 + 0x000000000005cfdf \endcode
+ DumpStyleFileAddress, ///< Display as the file address (if any).
+ ///< \code
+ /// // address for printf in libSystem.B.dylib as a file address
+ /// 0x000000000005dcff \endcode
+ DumpStyleModuleWithFileAddress, ///< Display as the file address with the module name prepended (if any).
+ ///< \code
+ /// // address for printf in libSystem.B.dylib as a file address
+ /// libSystem.B.dylib[0x000000000005dcff] \endcode
+ DumpStyleLoadAddress, ///< Display as the load address (if resolved).
+ ///< \code
+ /// // address for printf in libSystem.B.dylib as a load address
+ /// 0x00007fff8306bcff \endcode
+ DumpStyleResolvedDescription, ///< Display the details about what an address resolves to. This can
+ ///< be anything from a symbol context summary (module, function/symbol,
+ ///< and file and line), to information about what the pointer points to
+ ///< if the address is in a section (section of pointers, c strings, etc).
+ DumpStyleResolvedDescriptionNoModule,
+ DumpStyleDetailedSymbolContext, ///< Detailed symbol context information for an address for all symbol
+ ///< context members.
+ DumpStyleResolvedPointerDescription ///< Dereference a pointer at the current address and then lookup the
+ ///< dereferenced address using DumpStyleResolvedDescription
+ } DumpStyle;
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize with a invalid section (NULL) and an invalid
+ /// offset (LLDB_INVALID_ADDRESS).
+ //------------------------------------------------------------------
+ Address () :
+ m_section_wp (),
+ m_offset (LLDB_INVALID_ADDRESS)
+ {
+ }
+
+
+ //------------------------------------------------------------------
+ /// Copy constructor
+ ///
+ /// Makes a copy of the another Address object \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A const Address object reference to copy.
+ //------------------------------------------------------------------
+ Address (const Address& rhs) :
+ m_section_wp (rhs.m_section_wp),
+ m_offset(rhs.m_offset.load())
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Construct with a section pointer and offset.
+ ///
+ /// Initialize the address with the supplied \a section and \a
+ /// offset.
+ ///
+ /// @param[in] section
+ /// A section pointer to a valid lldb::Section, or NULL if the
+ /// address doesn't have a section or will get resolved later.
+ ///
+ /// @param[in] offset
+ /// The offset in bytes into \a section.
+ //------------------------------------------------------------------
+ Address (const lldb::SectionSP &section_sp, lldb::addr_t offset) :
+ m_section_wp (), // Don't init with section_sp in case section_sp is invalid (the weak_ptr will throw)
+ m_offset (offset)
+ {
+ if (section_sp)
+ m_section_wp = section_sp;
+ }
+
+ //------------------------------------------------------------------
+ /// Construct with a virtual address and section list.
+ ///
+ /// Initialize and resolve the address with the supplied virtual
+ /// address \a file_addr.
+ ///
+ /// @param[in] file_addr
+ /// A virtual file address.
+ ///
+ /// @param[in] section_list
+ /// A list of sections, one of which may contain the \a file_addr.
+ //------------------------------------------------------------------
+ Address (lldb::addr_t file_addr, const SectionList * section_list);
+
+ Address (lldb::addr_t abs_addr);
+
+ //------------------------------------------------------------------
+ /// Assignment operator.
+ ///
+ /// Copies the address value from another Address object \a rhs
+ /// into \a this object.
+ ///
+ /// @param[in] rhs
+ /// A const Address object reference to copy.
+ ///
+ /// @return
+ /// A const Address object reference to \a this.
+ //------------------------------------------------------------------
+#ifndef SWIG
+ const Address&
+ operator= (const Address& rhs);
+#endif
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Sets the section to an invalid value (NULL) and an invalid
+ /// offset (LLDB_INVALID_ADDRESS).
+ //------------------------------------------------------------------
+ void
+ Clear ()
+ {
+ m_section_wp.reset();
+ m_offset = LLDB_INVALID_ADDRESS;
+ }
+
+ //------------------------------------------------------------------
+ /// Compare two Address objects.
+ ///
+ /// @param[in] lhs
+ /// The Left Hand Side const Address object reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const Address object reference.
+ ///
+ /// @return
+ /// @li -1 if lhs < rhs
+ /// @li 0 if lhs == rhs
+ /// @li 1 if lhs > rhs
+ //------------------------------------------------------------------
+ static int
+ CompareFileAddress (const Address& lhs, const Address& rhs);
+
+ static int
+ CompareLoadAddress (const Address& lhs, const Address& rhs, Target *target);
+
+ static int
+ CompareModulePointerAndOffset (const Address& lhs, const Address& rhs);
+
+ // For use with std::map, std::multi_map
+ class ModulePointerAndOffsetLessThanFunctionObject
+ {
+ public:
+ ModulePointerAndOffsetLessThanFunctionObject () {}
+
+ bool
+ operator() (const Address& a, const Address& b) const
+ {
+ return Address::CompareModulePointerAndOffset(a, b) < 0;
+ }
+ };
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s. There are many ways to display a section
+ /// offset based address, and \a style lets the user choose.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] style
+ /// The display style for the address.
+ ///
+ /// @param[in] fallback_style
+ /// The display style for the address.
+ ///
+ /// @return
+ /// Returns \b true if the address was able to be displayed.
+ /// File and load addresses may be unresolved and it may not be
+ /// possible to display a valid value, \b false will be returned
+ /// in such cases.
+ ///
+ /// @see Address::DumpStyle
+ //------------------------------------------------------------------
+ bool
+ Dump (Stream *s,
+ ExecutionContextScope *exe_scope,
+ DumpStyle style,
+ DumpStyle fallback_style = DumpStyleInvalid,
+ uint32_t addr_byte_size = UINT32_MAX) const;
+
+ lldb::AddressClass
+ GetAddressClass () const;
+
+ //------------------------------------------------------------------
+ /// Get the file address.
+ ///
+ /// If an address comes from a file on disk that has section
+ /// relative addresses, then it has a virtual address that is
+ /// relative to unique section in the object file.
+ ///
+ /// @return
+ /// The valid file virtual address, or LLDB_INVALID_ADDRESS if
+ /// the address doesn't have a file virtual address (image is
+ /// from memory only with no representation on disk).
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetFileAddress () const;
+
+ //------------------------------------------------------------------
+ /// Get the load address.
+ ///
+ /// If an address comes from a file on disk that has section
+ /// relative addresses, then it has a virtual address that is
+ /// relative to unique section in the object file. Sections get
+ /// resolved at runtime by DynamicLoader plug-ins as images
+ /// (executables and shared libraries) get loaded/unloaded. If a
+ /// section is loaded, then the load address can be resolved.
+ ///
+ /// @return
+ /// The valid load virtual address, or LLDB_INVALID_ADDRESS if
+ /// the address is currently not loaded.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetLoadAddress (Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Get the load address as a callable code load address.
+ ///
+ /// This function will first resolve its address to a load address.
+ /// Then, if the address turns out to be in code address, return the
+ /// load address that would be required to call or return to. The
+ /// address might have extra bits set (bit zero will be set to Thumb
+ /// functions for an ARM target) that are required when changing the
+ /// program counter to setting a return address.
+ ///
+ /// @return
+ /// The valid load virtual address, or LLDB_INVALID_ADDRESS if
+ /// the address is currently not loaded.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetCallableLoadAddress (Target *target, bool is_indirect = false) const;
+
+ //------------------------------------------------------------------
+ /// Get the load address as an opcode load address.
+ ///
+ /// This function will first resolve its address to a load address.
+ /// Then, if the address turns out to be in code address, return the
+ /// load address for a an opcode. This address object might have
+ /// extra bits set (bit zero will be set to Thumb functions for an
+ /// ARM target) that are required for changing the program counter
+ /// and this function will remove any bits that are intended for
+ /// these special purposes. The result of this function can be used
+ /// to safely write a software breakpoint trap to memory.
+ ///
+ /// @return
+ /// The valid load virtual address with extra callable bits
+ /// removed, or LLDB_INVALID_ADDRESS if the address is currently
+ /// not loaded.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetOpcodeLoadAddress (Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Get the section relative offset value.
+ ///
+ /// @return
+ /// The current offset, or LLDB_INVALID_ADDRESS if this address
+ /// doesn't contain a valid offset.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetOffset () const { return m_offset; }
+
+ //------------------------------------------------------------------
+ /// Check if an address is section offset.
+ ///
+ /// When converting a virtual file or load address into a section
+ /// offset based address, we often need to know if, given a section
+ /// list, if the address was able to be converted to section offset.
+ /// This function returns true if the current value contained in
+ /// this object is section offset based.
+ ///
+ /// @return
+ /// Returns \b true if the address has a valid section and
+ /// offset, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsSectionOffset() const
+ {
+ return IsValid() && (GetSection().get() != NULL);
+ }
+
+ //------------------------------------------------------------------
+ /// Check if the object state is valid.
+ ///
+ /// A valid Address object contains either a section pointer and
+ /// and offset (for section offset based addresses), or just a valid
+ /// offset (for absolute addresses that have no section).
+ ///
+ /// @return
+ /// Returns \b true if the the offset is valid, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsValid() const
+ {
+ return m_offset != LLDB_INVALID_ADDRESS;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ //------------------------------------------------------------------
+ size_t
+ MemorySize () const;
+
+ //------------------------------------------------------------------
+ /// Resolve a file virtual address using a section list.
+ ///
+ /// Given a list of sections, attempt to resolve \a addr as a
+ /// an offset into one of the file sections.
+ ///
+ /// @return
+ /// Returns \b true if \a addr was able to be resolved, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ ResolveAddressUsingFileSections (lldb::addr_t addr, const SectionList *sections);
+
+ //------------------------------------------------------------------
+ /// Set the address to represent \a load_addr.
+ ///
+ /// The address will attempt to find a loaded section within
+ /// \a target that contains \a load_addr. If successful, this
+ /// address object will have a valid section and offset. Else this
+ /// address object will have no section (NULL) and the offset will
+ /// be \a load_addr.
+ ///
+ /// @param[in] load_addr
+ /// A load address from a current process.
+ ///
+ /// @param[in] target
+ /// The target to use when trying resolve the address into
+ /// a section + offset. The Target's SectionLoadList object
+ /// is used to resolve the address.
+ ///
+ /// @return
+ /// Returns \b true if the load address was resolved to be
+ /// section/offset, \b false otherwise. It is often ok for an
+ /// address no not resolve to a section in a module, this often
+ /// happens for JIT'ed code, or any load addresses on the stack
+ /// or heap.
+ //------------------------------------------------------------------
+ bool
+ SetLoadAddress (lldb::addr_t load_addr, Target *target);
+
+ bool
+ SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target);
+
+ bool
+ SetCallableLoadAddress (lldb::addr_t load_addr, Target *target);
+
+ //------------------------------------------------------------------
+ /// Get accessor for the module for this address.
+ ///
+ /// @return
+ /// Returns the Module pointer that this address is an offset
+ /// in, or NULL if this address doesn't belong in a module, or
+ /// isn't resolved yet.
+ //------------------------------------------------------------------
+ lldb::ModuleSP
+ GetModule () const;
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the section.
+ ///
+ /// @return
+ /// Returns the const lldb::Section pointer that this address is an
+ /// offset in, or NULL if this address is absolute.
+ //------------------------------------------------------------------
+ lldb::SectionSP
+ GetSection () const { return m_section_wp.lock(); }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the offset.
+ ///
+ /// @param[in] offset
+ /// A new offset value for this object.
+ ///
+ /// @return
+ /// Returns \b true if the offset changed, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ SetOffset (lldb::addr_t offset)
+ {
+ bool changed = m_offset != offset;
+ m_offset = offset;
+ return changed;
+ }
+
+ void
+ SetRawAddress (lldb::addr_t addr)
+ {
+ m_section_wp.reset();
+ m_offset = addr;
+ }
+
+ bool
+ Slide (int64_t offset)
+ {
+ if (m_offset != LLDB_INVALID_ADDRESS)
+ {
+ m_offset += offset;
+ return true;
+ }
+ return false;
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the section.
+ ///
+ /// @param[in] section
+ /// A new lldb::Section pointer to use as the section base. Can
+ /// be NULL for absolute addresses that are not relative to
+ /// any section.
+ //------------------------------------------------------------------
+ void
+ SetSection (const lldb::SectionSP &section_sp)
+ {
+ m_section_wp = section_sp;
+ }
+
+ void
+ ClearSection ()
+ {
+ m_section_wp.reset();
+ }
+ //------------------------------------------------------------------
+ /// Reconstruct a symbol context from an address.
+ ///
+ /// This class doesn't inherit from SymbolContextScope because many
+ /// address objects have short lifespans. Address objects that are
+ /// section offset can reconstruct their symbol context by looking
+ /// up the address in the module found in the section.
+ ///
+ /// @see SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ //------------------------------------------------------------------
+ uint32_t
+ CalculateSymbolContext (SymbolContext *sc,
+ uint32_t resolve_scope = lldb::eSymbolContextEverything) const;
+
+ lldb::ModuleSP
+ CalculateSymbolContextModule () const;
+
+ CompileUnit *
+ CalculateSymbolContextCompileUnit () const;
+
+ Function *
+ CalculateSymbolContextFunction () const;
+
+ Block *
+ CalculateSymbolContextBlock () const;
+
+ Symbol *
+ CalculateSymbolContextSymbol () const;
+
+ bool
+ CalculateSymbolContextLineEntry (LineEntry &line_entry) const;
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ lldb::SectionWP m_section_wp; ///< The section for the address, can be NULL.
+ std::atomic<lldb::addr_t> m_offset; ///< Offset into section if \a m_section_wp is valid...
+};
+
+
+//----------------------------------------------------------------------
+// NOTE: Be careful using this operator. It can correctly compare two
+// addresses from the same Module correctly. It can't compare two
+// addresses from different modules in any meaningful way, but it will
+// compare the module pointers.
+//
+// To sum things up:
+// - works great for addresses within the same module
+// - it works for addresses across multiple modules, but don't expect the
+// address results to make much sense
+//
+// This basically lets Address objects be used in ordered collection
+// classes.
+//----------------------------------------------------------------------
+bool operator< (const Address& lhs, const Address& rhs);
+bool operator> (const Address& lhs, const Address& rhs);
+
+
+
+bool operator== (const Address& lhs, const Address& rhs);
+bool operator!= (const Address& lhs, const Address& rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_Address_h_
diff --git a/include/lldb/Core/AddressRange.h b/include/lldb/Core/AddressRange.h
new file mode 100644
index 000000000000..bd3ab2ab5da5
--- /dev/null
+++ b/include/lldb/Core/AddressRange.h
@@ -0,0 +1,284 @@
+//===-- AddressRange.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_AddressRange_h_
+#define liblldb_AddressRange_h_
+
+#include "lldb/Core/Address.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class AddressRange AddressRange.h "lldb/Core/AddressRange.h"
+/// @brief A section + offset based address range class.
+//----------------------------------------------------------------------
+class AddressRange
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize with a invalid section (NULL), an invalid
+ /// offset (LLDB_INVALID_ADDRESS), and zero byte size.
+ //------------------------------------------------------------------
+ AddressRange ();
+
+ //------------------------------------------------------------------
+ /// Construct with a section pointer, offset, and byte_size.
+ ///
+ /// Initialize the address with the supplied \a section, \a
+ /// offset and \a byte_size.
+ ///
+ /// @param[in] section
+ /// A section pointer to a valid lldb::Section, or NULL if the
+ /// address doesn't have a section or will get resolved later.
+ ///
+ /// @param[in] offset
+ /// The offset in bytes into \a section.
+ ///
+ /// @param[in] byte_size
+ /// The size in bytes of the address range.
+ //------------------------------------------------------------------
+ AddressRange (const lldb::SectionSP &section, lldb::addr_t offset, lldb::addr_t byte_size);
+
+ //------------------------------------------------------------------
+ /// Construct with a virtual address, section list and byte size.
+ ///
+ /// Initialize and resolve the address with the supplied virtual
+ /// address \a file_addr, and byte size \a byte_size.
+ ///
+ /// @param[in] file_addr
+ /// A virtual address.
+ ///
+ /// @param[in] byte_size
+ /// The size in bytes of the address range.
+ ///
+ /// @param[in] section_list
+ /// A list of sections, one of which may contain the \a vaddr.
+ //------------------------------------------------------------------
+ AddressRange (lldb::addr_t file_addr, lldb::addr_t byte_size, const SectionList *section_list = NULL);
+
+ //------------------------------------------------------------------
+ /// Construct with a Address object address and byte size.
+ ///
+ /// Initialize by copying the section offset address in \a so_addr,
+ /// and setting the byte size to \a byte_size.
+ ///
+ /// @param[in] so_addr
+ /// A section offset address object.
+ ///
+ /// @param[in] byte_size
+ /// The size in bytes of the address range.
+ //------------------------------------------------------------------
+ AddressRange (const Address& so_addr, lldb::addr_t byte_size);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual in case this class is subclassed.
+ //------------------------------------------------------------------
+ ~AddressRange ();
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Sets the section to an invalid value (NULL), an invalid offset
+ /// (LLDB_INVALID_ADDRESS) and a zero byte size.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Check if a section offset address is contained in this range.
+ ///
+ /// @param[in] so_addr
+ /// A section offset address object reference.
+ ///
+ /// @return
+ /// Returns \b true if \a so_addr is contained in this range,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+// bool
+// Contains (const Address &so_addr) const;
+
+ //------------------------------------------------------------------
+ /// Check if a section offset address is contained in this range.
+ ///
+ /// @param[in] so_addr_ptr
+ /// A section offset address object pointer.
+ ///
+ /// @return
+ /// Returns \b true if \a so_addr is contained in this range,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+// bool
+// Contains (const Address *so_addr_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Check if a section offset \a so_addr when represented as a file
+ /// address is contained within this object's file address range.
+ ///
+ /// @param[in] so_addr
+ /// A section offset address object reference.
+ ///
+ /// @return
+ /// Returns \b true if both \a this and \a so_addr have
+ /// resolvable file address values and \a so_addr is contained
+ /// in the address range, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ContainsFileAddress (const Address &so_addr) const;
+
+ //------------------------------------------------------------------
+ /// Check if the resolved file address \a file_addr is contained
+ /// within this object's file address range.
+ ///
+ /// @param[in] so_addr
+ /// A section offset address object reference.
+ ///
+ /// @return
+ /// Returns \b true if both \a this has a resolvable file
+ /// address value and \a so_addr is contained in the address
+ /// range, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ContainsFileAddress (lldb::addr_t file_addr) const;
+
+ //------------------------------------------------------------------
+ /// Check if a section offset \a so_addr when represented as a load
+ /// address is contained within this object's load address range.
+ ///
+ /// @param[in] so_addr
+ /// A section offset address object reference.
+ ///
+ /// @return
+ /// Returns \b true if both \a this and \a so_addr have
+ /// resolvable load address values and \a so_addr is contained
+ /// in the address range, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ContainsLoadAddress (const Address &so_addr, Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Check if the resolved load address \a load_addr is contained
+ /// within this object's load address range.
+ ///
+ /// @param[in] so_addr
+ /// A section offset address object reference.
+ ///
+ /// @return
+ /// Returns \b true if both \a this has a resolvable load
+ /// address value and \a so_addr is contained in the address
+ /// range, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ContainsLoadAddress (lldb::addr_t load_addr, Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s. There are many ways to display a section
+ /// offset based address range, and \a style lets the user choose
+ /// how the base address gets displayed.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] style
+ /// The display style for the address.
+ ///
+ /// @return
+ /// Returns \b true if the address was able to be displayed.
+ /// File and load addresses may be unresolved and it may not be
+ /// possible to display a valid value, \b false will be returned
+ /// in such cases.
+ ///
+ /// @see Address::DumpStyle
+ //------------------------------------------------------------------
+ bool
+ Dump (Stream *s, Target *target, Address::DumpStyle style, Address::DumpStyle fallback_style = Address::DumpStyleInvalid) const;
+
+ //------------------------------------------------------------------
+ /// Dump a debug description of this object to a Stream.
+ ///
+ /// Dump a debug description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// The debug description contains verbose internal state such
+ /// and pointer values, reference counts, etc.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ DumpDebug (Stream *s) const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the base address of the range.
+ ///
+ /// @return
+ /// A reference to the base address object.
+ //------------------------------------------------------------------
+ Address &
+ GetBaseAddress() { return m_base_addr; }
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the base address of the range.
+ ///
+ /// @return
+ /// A const reference to the base address object.
+ //------------------------------------------------------------------
+ const Address &
+ GetBaseAddress() const { return m_base_addr; }
+
+ //------------------------------------------------------------------
+ /// Get accessor for the byte size of this range.
+ ///
+ /// @return
+ /// The size in bytes of this address range.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetByteSize () const { return m_byte_size; }
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ //------------------------------------------------------------------
+ size_t
+ MemorySize () const {
+ // Noting special for the memory size of a single AddressRange object,
+ // it is just the size of itself.
+ return sizeof(AddressRange);
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the byte size of this range.
+ ///
+ /// @param[in] byte_size
+ /// The new size in bytes of this address range.
+ //------------------------------------------------------------------
+ void
+ SetByteSize (lldb::addr_t byte_size) { m_byte_size = byte_size; }
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ Address m_base_addr; ///< The section offset base address of this range.
+ lldb::addr_t m_byte_size; ///< The size in bytes of this address range.
+};
+
+//bool operator== (const AddressRange& lhs, const AddressRange& rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_AddressRange_h_
diff --git a/include/lldb/Core/AddressResolver.h b/include/lldb/Core/AddressResolver.h
new file mode 100644
index 000000000000..e5fe276e3fb1
--- /dev/null
+++ b/include/lldb/Core/AddressResolver.h
@@ -0,0 +1,89 @@
+//===-- AddressResolver.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_AddressResolver_h_
+#define liblldb_AddressResolver_h_
+
+#include <vector>
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Core/SearchFilter.h"
+#include "lldb/Core/ConstString.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class AddressResolver AddressResolver.h "lldb/Core/AddressResolver.h"
+/// @brief This class works with SearchFilter to resolve function names and
+/// source file locations to their concrete addresses.
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+/// General Outline:
+/// The AddressResolver is a Searcher. In that protocol,
+/// the SearchFilter asks the question "At what depth of the symbol context
+/// descent do you want your callback to get called?" of the filter. The resolver
+/// answers this question (in the GetDepth method) and provides the resolution callback.
+//----------------------------------------------------------------------
+
+class AddressResolver :
+ public Searcher
+{
+public:
+
+ typedef enum
+ {
+ Exact,
+ Regexp,
+ Glob
+ } MatchType;
+
+
+ AddressResolver ();
+
+ virtual
+ ~AddressResolver ();
+
+ virtual void
+ ResolveAddress (SearchFilter &filter);
+
+ virtual void
+ ResolveAddressInModules (SearchFilter &filter,
+ ModuleList &modules);
+
+ virtual void
+ GetDescription (Stream *s) = 0;
+
+ std::vector<AddressRange> &
+ GetAddressRanges ();
+
+ size_t
+ GetNumberOfAddresses ();
+
+ AddressRange &
+ GetAddressRangeAtIndex (size_t idx);
+
+protected:
+
+ std::vector<AddressRange> m_address_ranges;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(AddressResolver);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_AddressResolver_h_
diff --git a/include/lldb/Core/AddressResolverFileLine.h b/include/lldb/Core/AddressResolverFileLine.h
new file mode 100644
index 000000000000..ddeb0e0301d2
--- /dev/null
+++ b/include/lldb/Core/AddressResolverFileLine.h
@@ -0,0 +1,59 @@
+//===-- AddressResolverFileLine.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_AddressResolverFileLine_h_
+#define liblldb_AddressResolverFileLine_h_
+
+// Project includes
+#include "lldb/Core/AddressResolver.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class AddressResolverFileLine AddressResolverFileLine.h "lldb/Core/AddressResolverFileLine.h"
+/// @brief This class finds address for source file and line. Optionally, it will look for inlined
+/// instances of the file and line specification.
+//----------------------------------------------------------------------
+
+class AddressResolverFileLine :
+ public AddressResolver
+{
+public:
+
+ AddressResolverFileLine (const FileSpec &resolver,
+ uint32_t line_no,
+ bool check_inlines);
+
+ virtual
+ ~AddressResolverFileLine ();
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing);
+
+ virtual Searcher::Depth
+ GetDepth ();
+
+ virtual void
+ GetDescription (Stream *s);
+
+protected:
+ FileSpec m_file_spec; // This is the file spec we are looking for.
+ uint32_t m_line_number; // This is the line number that we are looking for.
+ bool m_inlines; // This determines whether the resolver looks for inlined functions or not.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(AddressResolverFileLine);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_AddressResolverFileLine_h_
diff --git a/include/lldb/Core/AddressResolverName.h b/include/lldb/Core/AddressResolverName.h
new file mode 100644
index 000000000000..afde675a89bb
--- /dev/null
+++ b/include/lldb/Core/AddressResolverName.h
@@ -0,0 +1,68 @@
+//===-- AddressResolverName.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_AddressResolverName_h_
+#define liblldb_AddressResolverName_h_
+
+// Project includes
+
+#include "lldb/Core/AddressResolver.h"
+#include "lldb/Core/RegularExpression.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class AddressResolverName AddressResolverName.h "lldb/Core/AddressResolverName.h"
+/// @brief This class finds addresses for a given function name, either by exact match
+/// or by regular expression.
+//----------------------------------------------------------------------
+
+class AddressResolverName:
+ public AddressResolver
+{
+public:
+
+ AddressResolverName (const char *func_name,
+ AddressResolver::MatchType type = Exact);
+
+ // Creates a function breakpoint by regular expression. Takes over control of the lifespan of func_regex.
+ AddressResolverName (RegularExpression &func_regex);
+
+ AddressResolverName (const char *class_name,
+ const char *method,
+ AddressResolver::MatchType type);
+
+ virtual
+ ~AddressResolverName ();
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing);
+
+ virtual Searcher::Depth
+ GetDepth ();
+
+ virtual void
+ GetDescription (Stream *s);
+
+protected:
+ ConstString m_func_name;
+ ConstString m_class_name; // FIXME: Not used yet. The idea would be to stop on methods of this class.
+ RegularExpression m_regex;
+ AddressResolver::MatchType m_match_type;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(AddressResolverName);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_AddressResolverName_h_
diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h
new file mode 100644
index 000000000000..3bfa96be0cee
--- /dev/null
+++ b/include/lldb/Core/ArchSpec.h
@@ -0,0 +1,422 @@
+//===-- ArchSpec.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ArchSpec_h_
+#define liblldb_ArchSpec_h_
+
+#if defined(__cplusplus)
+
+#include "lldb/lldb-private.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+
+namespace lldb_private {
+
+struct CoreDefinition;
+
+//----------------------------------------------------------------------
+/// @class ArchSpec ArchSpec.h "lldb/Core/ArchSpec.h"
+/// @brief An architecture specification class.
+///
+/// A class designed to be created from a cpu type and subtype, a
+/// string representation, or an llvm::Triple. Keeping all of the
+/// conversions of strings to architecture enumeration values confined
+/// to this class allows new architecture support to be added easily.
+//----------------------------------------------------------------------
+class ArchSpec
+{
+public:
+ enum Core
+ {
+ eCore_arm_generic,
+ eCore_arm_armv4,
+ eCore_arm_armv4t,
+ eCore_arm_armv5,
+ eCore_arm_armv5e,
+ eCore_arm_armv5t,
+ eCore_arm_armv6,
+ eCore_arm_armv7,
+ eCore_arm_armv7f,
+ eCore_arm_armv7s,
+ eCore_arm_armv7k,
+ eCore_arm_armv7m,
+ eCore_arm_armv7em,
+ eCore_arm_xscale,
+ eCore_thumb,
+ eCore_thumbv4t,
+ eCore_thumbv5,
+ eCore_thumbv5e,
+ eCore_thumbv6,
+ eCore_thumbv7,
+ eCore_thumbv7f,
+ eCore_thumbv7s,
+ eCore_thumbv7k,
+ eCore_thumbv7m,
+ eCore_thumbv7em,
+
+ eCore_ppc_generic,
+ eCore_ppc_ppc601,
+ eCore_ppc_ppc602,
+ eCore_ppc_ppc603,
+ eCore_ppc_ppc603e,
+ eCore_ppc_ppc603ev,
+ eCore_ppc_ppc604,
+ eCore_ppc_ppc604e,
+ eCore_ppc_ppc620,
+ eCore_ppc_ppc750,
+ eCore_ppc_ppc7400,
+ eCore_ppc_ppc7450,
+ eCore_ppc_ppc970,
+
+ eCore_ppc64_generic,
+ eCore_ppc64_ppc970_64,
+
+ eCore_sparc_generic,
+
+ eCore_sparc9_generic,
+
+ eCore_x86_32_i386,
+ eCore_x86_32_i486,
+ eCore_x86_32_i486sx,
+
+ eCore_x86_64_x86_64,
+ eCore_uknownMach32,
+ eCore_uknownMach64,
+ kNumCores,
+
+ kCore_invalid,
+ // The following constants are used for wildcard matching only
+ kCore_any,
+ kCore_arm_any,
+ kCore_ppc_any,
+ kCore_ppc64_any,
+ kCore_x86_32_any,
+
+ kCore_arm_first = eCore_arm_generic,
+ kCore_arm_last = eCore_arm_xscale,
+
+ kCore_thumb_first = eCore_thumb,
+ kCore_thumb_last = eCore_thumbv7em,
+
+ kCore_ppc_first = eCore_ppc_generic,
+ kCore_ppc_last = eCore_ppc_ppc970,
+
+ kCore_ppc64_first = eCore_ppc64_generic,
+ kCore_ppc64_last = eCore_ppc64_ppc970_64,
+
+ kCore_x86_32_first = eCore_x86_32_i386,
+ kCore_x86_32_last = eCore_x86_32_i486sx
+ };
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Default constructor that initializes the object with invalid
+ /// cpu type and subtype values.
+ //------------------------------------------------------------------
+ ArchSpec ();
+
+ //------------------------------------------------------------------
+ /// Constructor over triple.
+ ///
+ /// Constructs an ArchSpec with properties consistent with the given
+ /// Triple.
+ //------------------------------------------------------------------
+ explicit
+ ArchSpec (const llvm::Triple &triple);
+ explicit
+ ArchSpec (const char *triple_cstr);
+ explicit
+ ArchSpec (const char *triple_cstr, Platform *platform);
+ //------------------------------------------------------------------
+ /// Constructor over architecture name.
+ ///
+ /// Constructs an ArchSpec with properties consistent with the given
+ /// object type and architecture name.
+ //------------------------------------------------------------------
+ explicit
+ ArchSpec (ArchitectureType arch_type,
+ uint32_t cpu_type,
+ uint32_t cpu_subtype);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~ArchSpec ();
+
+ //------------------------------------------------------------------
+ /// Assignment operator.
+ ///
+ /// @param[in] rhs another ArchSpec object to copy.
+ ///
+ /// @return A const reference to this object.
+ //------------------------------------------------------------------
+ const ArchSpec&
+ operator= (const ArchSpec& rhs);
+
+ static size_t
+ AutoComplete (const char *name,
+ StringList &matches);
+
+ //------------------------------------------------------------------
+ /// Returns a static string representing the current architecture.
+ ///
+ /// @return A static string correcponding to the current
+ /// architecture.
+ //------------------------------------------------------------------
+ const char *
+ GetArchitectureName () const;
+
+ //------------------------------------------------------------------
+ /// Clears the object state.
+ ///
+ /// Clears the object state back to a default invalid state.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Returns the size in bytes of an address of the current
+ /// architecture.
+ ///
+ /// @return The byte size of an address of the current architecture.
+ //------------------------------------------------------------------
+ uint32_t
+ GetAddressByteSize () const;
+
+ //------------------------------------------------------------------
+ /// Returns a machine family for the current architecture.
+ ///
+ /// @return An LLVM arch type.
+ //------------------------------------------------------------------
+ llvm::Triple::ArchType
+ GetMachine () const;
+
+ //------------------------------------------------------------------
+ /// Tests if this ArchSpec is valid.
+ ///
+ /// @return True if the current architecture is valid, false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsValid () const
+ {
+ return m_core >= eCore_arm_generic && m_core < kNumCores;
+ }
+
+ bool
+ TripleVendorWasSpecified() const
+ {
+ return !m_triple.getVendorName().empty();
+ }
+
+ bool
+ TripleOSWasSpecified() const
+ {
+ return !m_triple.getOSName().empty();
+ }
+
+ //------------------------------------------------------------------
+ /// Sets this ArchSpec according to the given architecture name.
+ ///
+ /// The architecture name can be one of the generic system default
+ /// values:
+ ///
+ /// @li \c LLDB_ARCH_DEFAULT - The arch the current system defaults
+ /// to when a program is launched without any extra
+ /// attributes or settings.
+ /// @li \c LLDB_ARCH_DEFAULT_32BIT - The default host architecture
+ /// for 32 bit (if any).
+ /// @li \c LLDB_ARCH_DEFAULT_64BIT - The default host architecture
+ /// for 64 bit (if any).
+ ///
+ /// Alternatively, if the object type of this ArchSpec has been
+ /// configured, a concrete architecture can be specified to set
+ /// the CPU type ("x86_64" for example).
+ ///
+ /// Finally, an encoded object and archetecture format is accepted.
+ /// The format contains an object type (like "macho" or "elf"),
+ /// followed by a platform dependent encoding of CPU type and
+ /// subtype. For example:
+ ///
+ /// "macho" : Specifies an object type of MachO.
+ /// "macho-16-6" : MachO specific encoding for ARMv6.
+ /// "elf-43 : ELF specific encoding for Sparc V9.
+ ///
+ /// @param[in] arch_name The name of an architecture.
+ ///
+ /// @return True if @p arch_name was successfully translated, false
+ /// otherwise.
+ //------------------------------------------------------------------
+// bool
+// SetArchitecture (const llvm::StringRef& arch_name);
+//
+// bool
+// SetArchitecture (const char *arch_name);
+
+ //------------------------------------------------------------------
+ /// Change the architecture object type and CPU type.
+ ///
+ /// @param[in] arch_type The object type of this ArchSpec.
+ ///
+ /// @param[in] cpu The required CPU type.
+ ///
+ /// @return True if the object and CPU type were sucessfully set.
+ //------------------------------------------------------------------
+ bool
+ SetArchitecture (ArchitectureType arch_type,
+ uint32_t cpu,
+ uint32_t sub);
+
+ //------------------------------------------------------------------
+ /// Returns the byte order for the architecture specification.
+ ///
+ /// @return The endian enumeration for the current endianness of
+ /// the architecture specification
+ //------------------------------------------------------------------
+ lldb::ByteOrder
+ GetByteOrder () const;
+
+ //------------------------------------------------------------------
+ /// Sets this ArchSpec's byte order.
+ ///
+ /// In the common case there is no need to call this method as the
+ /// byte order can almost always be determined by the architecture.
+ /// However, many CPU's are bi-endian (ARM, Alpha, PowerPC, etc)
+ /// and the default/assumed byte order may be incorrect.
+ //------------------------------------------------------------------
+ void
+ SetByteOrder (lldb::ByteOrder byte_order)
+ {
+ m_byte_order = byte_order;
+ }
+
+ uint32_t
+ GetMinimumOpcodeByteSize() const;
+
+ uint32_t
+ GetMaximumOpcodeByteSize() const;
+
+ Core
+ GetCore () const
+ {
+ return m_core;
+ }
+
+ uint32_t
+ GetMachOCPUType () const;
+
+ uint32_t
+ GetMachOCPUSubType () const;
+
+ //------------------------------------------------------------------
+ /// Architecture tripple accessor.
+ ///
+ /// @return A triple describing this ArchSpec.
+ //------------------------------------------------------------------
+ llvm::Triple &
+ GetTriple ()
+ {
+ return m_triple;
+ }
+
+ //------------------------------------------------------------------
+ /// Architecture tripple accessor.
+ ///
+ /// @return A triple describing this ArchSpec.
+ //------------------------------------------------------------------
+ const llvm::Triple &
+ GetTriple () const
+ {
+ return m_triple;
+ }
+
+ //------------------------------------------------------------------
+ /// Architecture tripple setter.
+ ///
+ /// Configures this ArchSpec according to the given triple. If the
+ /// triple has unknown components in all of the vendor, OS, and
+ /// the optional environment field (i.e. "i386-unknown-unknown")
+ /// then default values are taken from the host. Architecture and
+ /// environment components are used to further resolve the CPU type
+ /// and subtype, endian characteristics, etc.
+ ///
+ /// @return A triple describing this ArchSpec.
+ //------------------------------------------------------------------
+ bool
+ SetTriple (const llvm::Triple &triple);
+
+ bool
+ SetTriple (const char *triple_cstr);
+
+ bool
+ SetTriple (const char *triple_cstr,
+ Platform *platform);
+
+ //------------------------------------------------------------------
+ /// Returns the default endianness of the architecture.
+ ///
+ /// @return The endian enumeration for the default endianness of
+ /// the architecture.
+ //------------------------------------------------------------------
+ lldb::ByteOrder
+ GetDefaultEndian () const;
+
+ //------------------------------------------------------------------
+ /// Compare an ArchSpec to another ArchSpec, requiring an exact cpu
+ /// type match between them.
+ /// e.g. armv7s is not an exact match with armv7 - this would return false
+ ///
+ /// @return true if the two ArchSpecs match.
+ //------------------------------------------------------------------
+ bool
+ IsExactMatch (const ArchSpec& rhs) const;
+
+ //------------------------------------------------------------------
+ /// Compare an ArchSpec to another ArchSpec, requiring a compatible
+ /// cpu type match between them.
+ /// e.g. armv7s is compatible with armv7 - this method would return true
+ ///
+ /// @return true if the two ArchSpecs are compatible
+ //------------------------------------------------------------------
+ bool
+ IsCompatibleMatch (const ArchSpec& rhs) const;
+
+protected:
+ bool
+ IsEqualTo (const ArchSpec& rhs, bool exact_match) const;
+
+ llvm::Triple m_triple;
+ Core m_core;
+ lldb::ByteOrder m_byte_order;
+
+ // Called when m_def or m_entry are changed. Fills in all remaining
+ // members with default values.
+ void
+ CoreUpdated (bool update_triple);
+};
+
+//------------------------------------------------------------------
+/// @fn bool operator< (const ArchSpec& lhs, const ArchSpec& rhs)
+/// @brief Less than operator.
+///
+/// Tests two ArchSpec objects to see if \a lhs is less than \a
+/// rhs.
+///
+/// @param[in] lhs The Left Hand Side ArchSpec object to compare.
+/// @param[in] rhs The Left Hand Side ArchSpec object to compare.
+///
+/// @return true if \a lhs is less than \a rhs
+//------------------------------------------------------------------
+bool operator< (const ArchSpec& lhs, const ArchSpec& rhs);
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // #ifndef liblldb_ArchSpec_h_
diff --git a/include/lldb/Core/Baton.h b/include/lldb/Core/Baton.h
new file mode 100644
index 000000000000..627e7203a4ac
--- /dev/null
+++ b/include/lldb/Core/Baton.h
@@ -0,0 +1,62 @@
+//===-- Baton.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Baton_h_
+#define lldb_Baton_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Baton Baton.h "lldb/Core/Baton.h"
+/// @brief A class designed to wrap callback batons so they can cleanup
+/// any acquired resources
+///
+/// This class is designed to be used by any objects that have a
+/// callback function that takes a baton where the baton might need to
+/// free/delete/close itself.
+///
+/// The default behavior is to not free anything. Subclasses can
+/// free any needed resources in their destructors.
+//----------------------------------------------------------------------
+class Baton
+{
+public:
+ explicit Baton(void *p) :
+ m_data (p)
+ {
+ }
+
+ virtual
+ ~Baton()
+ {
+ // The default destructor for a baton does NOT attempt to clean up
+ // anything in m_baton
+ }
+
+ virtual void
+ GetDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+ void *m_data; // Leave baton public for easy access
+
+private:
+ //------------------------------------------------------------------
+ // For Baton only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (Baton);
+};
+
+} // namespace lldb_private
+
+#endif // lldb_Baton_h_
diff --git a/include/lldb/Core/Broadcaster.h b/include/lldb/Core/Broadcaster.h
new file mode 100644
index 000000000000..64b12ca8a938
--- /dev/null
+++ b/include/lldb/Core/Broadcaster.h
@@ -0,0 +1,475 @@
+//===-- Broadcaster.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Broadcaster_h_
+#define liblldb_Broadcaster_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+//#include "lldb/Core/Flags.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Listener.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// lldb::BroadcastEventSpec
+//
+// This class is used to specify a kind of event to register for. The Debugger
+// maintains a list of BroadcastEventSpec's and when it is made
+//----------------------------------------------------------------------
+class BroadcastEventSpec
+{
+public:
+ BroadcastEventSpec (const ConstString &broadcaster_class, uint32_t event_bits) :
+ m_broadcaster_class (broadcaster_class),
+ m_event_bits (event_bits)
+ {
+ }
+
+ BroadcastEventSpec (const BroadcastEventSpec &rhs);
+
+ ~BroadcastEventSpec() {}
+
+ const ConstString &GetBroadcasterClass() const
+ {
+ return m_broadcaster_class;
+ }
+
+ uint32_t GetEventBits () const
+ {
+ return m_event_bits;
+ }
+
+ // Tell whether this BroadcastEventSpec is contained in in_spec.
+ // That is:
+ // (a) the two spec's share the same broadcaster class
+ // (b) the event bits of this spec are wholly contained in those of in_spec.
+ bool IsContainedIn (BroadcastEventSpec in_spec) const
+ {
+ if (m_broadcaster_class != in_spec.GetBroadcasterClass())
+ return false;
+ uint32_t in_bits = in_spec.GetEventBits();
+ if (in_bits == m_event_bits)
+ return true;
+ else
+ {
+ if ((m_event_bits & in_bits) != 0
+ && (m_event_bits & ~in_bits) == 0)
+ return true;
+ }
+ return false;
+ }
+
+ bool operator< (const BroadcastEventSpec &rhs) const;
+ const BroadcastEventSpec &operator= (const BroadcastEventSpec &rhs);
+
+private:
+ ConstString m_broadcaster_class;
+ uint32_t m_event_bits;
+};
+
+class BroadcasterManager
+{
+public:
+ friend class Listener;
+
+ BroadcasterManager ();
+
+ ~BroadcasterManager () {}
+
+ uint32_t
+ RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
+
+ bool
+ UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
+
+ Listener *
+ GetListenerForEventSpec (BroadcastEventSpec event_spec) const;
+
+ void
+ SignUpListenersForBroadcaster (Broadcaster &broadcaster);
+
+ void
+ RemoveListener (Listener &Listener);
+
+protected:
+ void Clear();
+
+private:
+ typedef std::pair<BroadcastEventSpec, Listener *> event_listener_key;
+ typedef std::map<BroadcastEventSpec, Listener *> collection;
+ typedef std::set<Listener *> listener_collection;
+ collection m_event_map;
+ listener_collection m_listeners;
+
+ Mutex m_manager_mutex;
+
+ // A couple of comparator classes for find_if:
+
+ class BroadcasterClassMatches
+ {
+ public:
+ BroadcasterClassMatches (const ConstString &broadcaster_class) :
+ m_broadcaster_class (broadcaster_class)
+ {
+ }
+
+ ~BroadcasterClassMatches () {}
+
+ bool operator() (const event_listener_key input) const
+ {
+ return (input.first.GetBroadcasterClass() == m_broadcaster_class);
+ }
+
+ private:
+ ConstString m_broadcaster_class;
+ };
+
+ class BroadcastEventSpecMatches
+ {
+ public:
+ BroadcastEventSpecMatches (BroadcastEventSpec broadcaster_spec) :
+ m_broadcaster_spec (broadcaster_spec)
+ {
+ }
+
+ ~BroadcastEventSpecMatches () {}
+
+ bool operator() (const event_listener_key input) const
+ {
+ return (input.first.IsContainedIn (m_broadcaster_spec));
+ }
+
+ private:
+ BroadcastEventSpec m_broadcaster_spec;
+ };
+
+ class ListenerMatchesAndSharedBits
+ {
+ public:
+ ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec,
+ const Listener &listener) :
+ m_broadcaster_spec (broadcaster_spec),
+ m_listener (&listener)
+ {
+ }
+
+ ~ListenerMatchesAndSharedBits () {}
+
+ bool operator() (const event_listener_key input) const
+ {
+ return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass()
+ && (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0
+ && input.second == m_listener);
+ }
+
+ private:
+ BroadcastEventSpec m_broadcaster_spec;
+ const Listener *m_listener;
+ };
+
+ class ListenerMatches
+ {
+ public:
+ ListenerMatches (const Listener &in_listener) :
+ m_listener (&in_listener)
+ {
+ }
+
+ ~ListenerMatches() {}
+
+ bool operator () (const event_listener_key input) const
+ {
+ if (input.second == m_listener)
+ return true;
+ else
+ return false;
+ }
+
+ private:
+ const Listener *m_listener;
+
+ };
+
+};
+
+//----------------------------------------------------------------------
+/// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h"
+/// @brief An event broadcasting class.
+///
+/// The Broadcaster class is designed to be subclassed by objects that
+/// wish to vend events in a multi-threaded environment. Broadcaster
+/// objects can each vend 32 events. Each event is represented by a bit
+/// in a 32 bit value and these bits can be set:
+/// @see Broadcaster::SetEventBits(uint32_t)
+/// or cleared:
+/// @see Broadcaster::ResetEventBits(uint32_t)
+/// When an event gets set the Broadcaster object will notify the
+/// Listener object that is listening for the event (if there is one).
+///
+/// Subclasses should provide broadcast bit definitions for any events
+/// they vend, typically using an enumeration:
+/// \code
+/// class Foo : public Broadcaster
+/// {
+/// public:
+/// //----------------------------------------------------------
+/// // Broadcaster event bits definitions.
+/// //----------------------------------------------------------
+/// enum
+/// {
+/// eBroadcastBitStateChanged = (1 << 0),
+/// eBroadcastBitInterrupt = (1 << 1),
+/// eBroadcastBitSTDOUT = (1 << 2),
+/// eBroadcastBitSTDERR = (1 << 3),
+/// eBroadcastBitProfileData = (1 << 4)
+/// };
+/// \endcode
+//----------------------------------------------------------------------
+class Broadcaster
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with a broadcaster with a name.
+ ///
+ /// @param[in] name
+ /// A NULL terminated C string that contains the name of the
+ /// broadcaster object.
+ //------------------------------------------------------------------
+ Broadcaster (BroadcasterManager *manager, const char *name);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class gets subclassed.
+ //------------------------------------------------------------------
+ virtual
+ ~Broadcaster();
+
+ void
+ CheckInWithManager ();
+
+ //------------------------------------------------------------------
+ /// Broadcast an event which has no associated data.
+ ///
+ /// @param[in] event_type
+ /// The element from the enum defining this broadcaster's events
+ /// that is being broadcast.
+ ///
+ /// @param[in] event_data
+ /// User event data that will be owned by the lldb::Event that
+ /// is created internally.
+ ///
+ /// @param[in] unique
+ /// If true, then only add an event of this type if there isn't
+ /// one already in the queue.
+ ///
+ //------------------------------------------------------------------
+ void
+ BroadcastEvent (lldb::EventSP &event_sp);
+
+ void
+ BroadcastEventIfUnique (lldb::EventSP &event_sp);
+
+ void
+ BroadcastEvent (uint32_t event_type, EventData *event_data = NULL);
+
+ void
+ BroadcastEventIfUnique (uint32_t event_type, EventData *event_data = NULL);
+
+ void
+ Clear();
+
+ virtual void
+ AddInitialEventsToListener (Listener *listener, uint32_t requested_events);
+
+ //------------------------------------------------------------------
+ /// Listen for any events specified by \a event_mask.
+ ///
+ /// Only one listener can listen to each event bit in a given
+ /// Broadcaster. Once a listener has acquired an event bit, no
+ /// other broadcaster will have access to it until it is
+ /// relinquished by the first listener that gets it. The actual
+ /// event bits that get acquired by \a listener may be different
+ /// from what is requested in \a event_mask, and to track this the
+ /// actual event bits that are acquired get returned.
+ ///
+ /// @param[in] listener
+ /// The Listener object that wants to monitor the events that
+ /// get broadcast by this object.
+ ///
+ /// @param[in] event_mask
+ /// A bit mask that indicates which events the listener is
+ /// asking to monitor.
+ ///
+ /// @return
+ /// The actual event bits that were acquired by \a listener.
+ //------------------------------------------------------------------
+ uint32_t
+ AddListener (Listener* listener, uint32_t event_mask);
+
+ //------------------------------------------------------------------
+ /// Get the NULL terminated C string name of this Broadcaster
+ /// object.
+ ///
+ /// @return
+ /// The NULL terminated C string name of this Broadcaster.
+ //------------------------------------------------------------------
+ const ConstString &
+ GetBroadcasterName ();
+
+
+ //------------------------------------------------------------------
+ /// Get the event name(s) for one or more event bits.
+ ///
+ /// @param[in] event_mask
+ /// A bit mask that indicates which events to get names for.
+ ///
+ /// @return
+ /// The NULL terminated C string name of this Broadcaster.
+ //------------------------------------------------------------------
+ bool
+ GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
+
+ //------------------------------------------------------------------
+ /// Set the name for an event bit.
+ ///
+ /// @param[in] event_mask
+ /// A bit mask that indicates which events the listener is
+ /// asking to monitor.
+ ///
+ /// @return
+ /// The NULL terminated C string name of this Broadcaster.
+ //------------------------------------------------------------------
+ void
+ SetEventName (uint32_t event_mask, const char *name)
+ {
+ m_event_names[event_mask] = name;
+ }
+
+ const char *
+ GetEventName (uint32_t event_mask) const
+ {
+ event_names_map::const_iterator pos = m_event_names.find (event_mask);
+ if (pos != m_event_names.end())
+ return pos->second.c_str();
+ return NULL;
+ }
+
+ bool
+ EventTypeHasListeners (uint32_t event_type);
+
+ //------------------------------------------------------------------
+ /// Removes a Listener from this broadcasters list and frees the
+ /// event bits specified by \a event_mask that were previously
+ /// acquired by \a listener (assuming \a listener was listening to
+ /// this object) for other listener objects to use.
+ ///
+ /// @param[in] listener
+ /// A Listener object that previously called AddListener.
+ ///
+ /// @param[in] event_mask
+ /// The event bits \a listener wishes to relinquish.
+ ///
+ /// @return
+ /// \b True if the listener was listening to this broadcaster
+ /// and was removed, \b false otherwise.
+ ///
+ /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
+ //------------------------------------------------------------------
+ bool
+ RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX);
+
+ //------------------------------------------------------------------
+ /// Provides a simple mechanism to temporarily redirect events from
+ /// broadcaster. When you call this function passing in a listener and
+ /// event type mask, all events from the broadcaster matching the mask
+ /// will now go to the hijacking listener.
+ /// Only one hijack can occur at a time. If we need more than this we
+ /// will have to implement a Listener stack.
+ ///
+ /// @param[in] listener
+ /// A Listener object. You do not need to call StartListeningForEvents
+ /// for this broadcaster (that would fail anyway since the event bits
+ /// would most likely be taken by the listener(s) you are usurping.
+ ///
+ /// @param[in] event_mask
+ /// The event bits \a listener wishes to hijack.
+ ///
+ /// @return
+ /// \b True if the event mask could be hijacked, \b false otherwise.
+ ///
+ /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
+ //------------------------------------------------------------------
+ bool
+ HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX);
+
+ bool
+ IsHijackedForEvent (uint32_t event_mask)
+ {
+ if (m_hijacking_listeners.size() > 0)
+ return (event_mask & m_hijacking_masks.back()) != 0;
+ return false;
+ }
+
+ //------------------------------------------------------------------
+ /// Restore the state of the Broadcaster from a previous hijack attempt.
+ ///
+ //------------------------------------------------------------------
+ void
+ RestoreBroadcaster ();
+
+ // This needs to be filled in if you are going to register the broadcaster with the broadcaster
+ // manager and do broadcaster class matching.
+ // FIXME: Probably should make a ManagedBroadcaster subclass with all the bits needed to work
+ // with the BroadcasterManager, so that it is clearer how to add one.
+ virtual ConstString &GetBroadcasterClass() const;
+
+ BroadcasterManager *GetManager();
+
+protected:
+
+
+ void
+ PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
+
+ //------------------------------------------------------------------
+ // Classes that inherit from Broadcaster can see and modify these
+ //------------------------------------------------------------------
+ typedef std::vector< std::pair<Listener*,uint32_t> > collection;
+ typedef std::map<uint32_t, std::string> event_names_map;
+ // Prefix the name of our member variables with "m_broadcaster_"
+ // since this is a class that gets subclassed.
+ const ConstString m_broadcaster_name; ///< The name of this broadcaster object.
+ event_names_map m_event_names; ///< Optionally define event names for readability and logging for each event bit
+ collection m_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
+ Mutex m_listeners_mutex; ///< A mutex that protects \a m_listeners.
+ std::vector<Listener *> m_hijacking_listeners; // A simple mechanism to intercept events from a broadcaster
+ std::vector<uint32_t> m_hijacking_masks; // At some point we may want to have a stack or Listener
+ // collections, but for now this is just for private hijacking.
+ BroadcasterManager *m_manager;
+
+private:
+ //------------------------------------------------------------------
+ // For Broadcaster only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (Broadcaster);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Broadcaster_h_
diff --git a/include/lldb/Core/ClangForward.h b/include/lldb/Core/ClangForward.h
new file mode 100644
index 000000000000..0b3f13a16602
--- /dev/null
+++ b/include/lldb/Core/ClangForward.h
@@ -0,0 +1,136 @@
+//===-- ClangForward.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangForward_h_
+#define liblldb_ClangForward_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#if defined(__cplusplus)
+
+namespace clang
+{
+ namespace Builtin
+ {
+ class Context;
+ }
+
+ class Action;
+ class ASTConsumer;
+ class ASTContext;
+ class ASTRecordLayout;
+ class AddrLabelExpr;
+ class AnalyzerOptions;
+ class BinaryOperator;
+ class ClassTemplateDecl;
+ class ClassTemplateSpecializationDecl;
+ class CodeGenOptions;
+ class CodeGenerator;
+ class CompilerInstance;
+ class CompoundStmt;
+ class CXXBaseSpecifier;
+ class CXXBoolLiteralExpr;
+ class CXXFunctionalCastExpr;
+ class CXXMethodDecl;
+ class CXXNamedCastExpr;
+ class CXXRecordDecl;
+ class CXXThisExpr;
+ class CharacterLiteral;
+ class CompoundAssignOperator;
+ class Decl;
+ class DeclarationName;
+ class DeclaratorDecl;
+ class DeclContext;
+ class DeclRefExpr;
+ class DeclStmt;
+ class DependencyOutputOptions;
+ class Diagnostic;
+ class DiagnosticConsumer;
+ class DiagnosticsEngine;
+ class DiagnosticOptions;
+ class EnumDecl;
+ class Expr;
+ class ExternalASTSource;
+ class ExtVectorElementExpr;
+ class FieldDecl;
+ class FileManager;
+ class FileSystemOptions;
+ class FloatingLiteral;
+ class FrontendOptions;
+ class FunctionDecl;
+ class FunctionTemplateDecl;
+ class FunctionTemplateSpecializationInfo;
+ class GotoStmt;
+ class HeaderSearchOptions;
+ class IdentifierTable;
+ class IntegerLiteral;
+ class LabelStmt;
+ class LangOptions;
+ class MemberExpr;
+ class NamedDecl;
+ class NamespaceDecl;
+ class NonTypeTemplateParmDecl;
+ class ObjCEncodeExpr;
+ class ObjCImplicitSetterGetterRefExpr;
+ class ObjCInterfaceDecl;
+ class ObjCIvarDecl;
+ class ObjCIvarRefExpr;
+ class ObjCMessageExpr;
+ class ObjCMethodDecl;
+ class ObjCPropertyRefExpr;
+ class ObjCProtocolDecl;
+ class ObjCProtocolExpr;
+ class ObjCSelectorExpr;
+ class ObjCSuperExpr;
+ class ParenExpr;
+ class ParmVarDecl;
+ class PredefinedExpr;
+ class PreprocessorOptions;
+ class PreprocessorOutputOptions;
+ class QualType;
+ class QualifiedNameType;
+ class RecordDecl;
+ class SelectorTable;
+ class SizeOfAlignOfExpr;
+ class SourceLocation;
+ class SourceManager;
+ class Stmt;
+ class StmtIteratorBase;
+ class StringLiteral;
+ class TagDecl;
+ class TargetInfo;
+ class TargetOptions;
+ class TemplateArgument;
+ class TemplateDecl;
+ class TemplateParameterList;
+ class TemplateTemplateParmDecl;
+ class TemplateTypeParmDecl;
+ class TextDiagnosticBuffer;
+ class TranslationUnitDecl;
+ class Type;
+ class TypeDecl;
+ class TypedefDecl;
+ class TypesCompatibleExpr;
+ class UnaryOperator;
+ class ValueDecl;
+ class VarDecl;
+ struct PrintingPolicy;
+}
+
+namespace llvm
+{
+ class LLVMContext;
+ class ExecutionEngine;
+}
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_ClangForward_h_
diff --git a/include/lldb/Core/Communication.h b/include/lldb/Core/Communication.h
new file mode 100644
index 000000000000..98d4dfd011b8
--- /dev/null
+++ b/include/lldb/Core/Communication.h
@@ -0,0 +1,413 @@
+//===-- Communication.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Communication_h_
+#define liblldb_Communication_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Communication Communication.h "lldb/Core/Communication.h"
+/// @brief An abstract communications class.
+///
+/// Communication is an class that handles data communication
+/// between two data sources. It uses a Connection class to do the
+/// real communication. This approach has a couple of advantages: it
+/// allows a single instance of this class to be used even though its
+/// connection can change. Connections could negotiate for different
+/// connections based on abilities like starting with Bluetooth and
+/// negotiating up to WiFi if available. It also allows this class to be
+/// subclassed by any interfaces that don't want to give bytes but want
+/// to validate and give out packets. This can be done by overriding:
+///
+/// AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast);
+///
+/// Communication inherits from Broadcaster which means it can be
+/// used in conjunction with Listener to wait for multiple broadcaster
+/// objects and multiple events from each of those objects.
+/// Communication defines a set of pre-defined event bits (see
+/// enumerations definitions that start with "eBroadcastBit" below).
+///
+/// There are two modes in which communications can occur:
+/// @li single-threaded
+/// @li multi-threaded
+///
+/// In single-threaded mode, all reads and writes happen synchronously
+/// on the calling thread.
+///
+/// In multi-threaded mode, a read thread is spawned that continually
+/// reads data and caches any received bytes. To start the read thread
+/// clients call:
+///
+/// bool Communication::StartReadThread (Error *);
+///
+/// If true is returned a read thead has been spawned that will
+/// continually execute a call to the pure virtual DoRead function:
+///
+/// size_t Communication::ReadFromConnection (void *, size_t, uint32_t);
+///
+/// When bytes are received the data gets cached in \a m_bytes and this
+/// class will broadcast a \b eBroadcastBitReadThreadGotBytes event.
+/// Clients that want packet based communication should override
+/// AppendBytesToCache. The subclasses can choose to call the
+/// built in AppendBytesToCache with the \a broadcast parameter set to
+/// false. This will cause the \b eBroadcastBitReadThreadGotBytes event
+/// not get broadcast, and then the subclass can post a \b
+/// eBroadcastBitPacketAvailable event when a full packet of data has
+/// been received.
+///
+/// If the connection is disconnected a \b eBroadcastBitDisconnected
+/// event gets broadcast. If the read thread exits a \b
+/// eBroadcastBitReadThreadDidExit event will be broadcast. Clients
+/// can also post a \b eBroadcastBitReadThreadShouldExit event to this
+/// object which will cause the read thread to exit.
+//----------------------------------------------------------------------
+class Communication : public Broadcaster
+{
+public:
+ enum {
+ eBroadcastBitDisconnected = (1 << 0), ///< Sent when the communications connection is lost.
+ eBroadcastBitReadThreadGotBytes = (1 << 1), ///< Sent by the read thread when bytes become available.
+ eBroadcastBitReadThreadDidExit = (1 << 2), ///< Sent by the read thread when it exits to inform clients.
+ eBroadcastBitReadThreadShouldExit = (1 << 3), ///< Sent by clients that need to cancel the read thread.
+ eBroadcastBitPacketAvailable = (1 << 4), ///< Sent when data received makes a complete packet.
+ kLoUserBroadcastBit = (1 << 16),///< Subclasses can used bits 31:16 for any needed events.
+ kHiUserBroadcastBit = (1 << 31),
+ eAllEventBits = 0xffffffff
+ };
+
+ typedef void (*ReadThreadBytesReceived) (void *baton, const void *src, size_t src_len);
+
+
+ //------------------------------------------------------------------
+ /// Construct the Communication object with the specified name for
+ /// the Broadcaster that this object inherits from.
+ ///
+ /// @param[in] broadcaster_name
+ /// The name of the broadcaster object. This name should be as
+ /// complete as possible to uniquely identify this object. The
+ /// broadcaster name can be updated after the connect function
+ /// is called.
+ //------------------------------------------------------------------
+ Communication(const char * broadcaster_name);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class gets subclassed.
+ //------------------------------------------------------------------
+ virtual
+ ~Communication();
+
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Connect using the current connection by passing \a url to its
+ /// connect function.
+ /// string.
+ ///
+ /// @param[in] url
+ /// A string that contains all information needed by the
+ /// subclass to connect to another client.
+ ///
+ /// @return
+ /// \b True if the connect succeeded, \b false otherwise. The
+ /// internal error object should be filled in with an
+ /// appropriate value based on the result of this function.
+ ///
+ /// @see Error& Communication::GetError ();
+ /// @see bool Connection::Connect (const char *url);
+ //------------------------------------------------------------------
+ lldb::ConnectionStatus
+ Connect (const char *url, Error *error_ptr);
+
+ //------------------------------------------------------------------
+ /// Disconnect the communications connection if one is currently
+ /// connected.
+ ///
+ /// @return
+ /// \b True if the disconnect succeeded, \b false otherwise. The
+ /// internal error object should be filled in with an
+ /// appropriate value based on the result of this function.
+ ///
+ /// @see Error& Communication::GetError ();
+ /// @see bool Connection::Disconnect ();
+ //------------------------------------------------------------------
+ lldb::ConnectionStatus
+ Disconnect (Error *error_ptr = NULL);
+
+ //------------------------------------------------------------------
+ /// Check if the connection is valid.
+ ///
+ /// @return
+ /// \b True if this object is currently connected, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsConnected () const;
+
+ bool
+ HasConnection () const;
+
+ lldb_private::Connection *
+ GetConnection ()
+ {
+ return m_connection_sp.get();
+ }
+ //------------------------------------------------------------------
+ /// Read bytes from the current connection.
+ ///
+ /// If no read thread is running, this function call the
+ /// connection's Connection::Read(...) function to get any available.
+ ///
+ /// If a read thread has been started, this function will check for
+ /// any cached bytes that have already been read and return any
+ /// currently available bytes. If no bytes are cached, it will wait
+ /// for the bytes to become available by listening for the \a
+ /// eBroadcastBitReadThreadGotBytes event. If this function consumes
+ /// all of the bytes in the cache, it will reset the
+ /// \a eBroadcastBitReadThreadGotBytes event bit.
+ ///
+ /// @param[in] dst
+ /// A destination buffer that must be at least \a dst_len bytes
+ /// long.
+ ///
+ /// @param[in] dst_len
+ /// The number of bytes to attempt to read, and also the max
+ /// number of bytes that can be placed into \a dst.
+ ///
+ /// @param[in] timeout_usec
+ /// A timeout value in micro-seconds.
+ ///
+ /// @return
+ /// The number of bytes actually read.
+ ///
+ /// @see size_t Connection::Read (void *, size_t);
+ //------------------------------------------------------------------
+ size_t
+ Read (void *dst,
+ size_t dst_len,
+ uint32_t timeout_usec,
+ lldb::ConnectionStatus &status,
+ Error *error_ptr);
+
+ //------------------------------------------------------------------
+ /// The actual write function that attempts to write to the
+ /// communications protocol.
+ ///
+ /// Subclasses must override this function.
+ ///
+ /// @param[in] src
+ /// A source buffer that must be at least \a src_len bytes
+ /// long.
+ ///
+ /// @param[in] src_len
+ /// The number of bytes to attempt to write, and also the
+ /// number of bytes are currently available in \a src.
+ ///
+ /// @return
+ /// The number of bytes actually Written.
+ //------------------------------------------------------------------
+ size_t
+ Write (const void *src,
+ size_t src_len,
+ lldb::ConnectionStatus &status,
+ Error *error_ptr);
+
+ //------------------------------------------------------------------
+ /// Sets the connection that it to be used by this class.
+ ///
+ /// By making a communication class that uses different connections
+ /// it allows a single communication interface to negotiate and
+ /// change its connection without any interruption to the client.
+ /// It also allows the Communication class to be subclassed for
+ /// packet based communication.
+ ///
+ /// @param[in] connection
+ /// A connection that this class will own and destroy.
+ ///
+ /// @see
+ /// class Connection
+ //------------------------------------------------------------------
+ void
+ SetConnection (Connection *connection);
+
+ //------------------------------------------------------------------
+ /// Starts a read thread whose sole purpose it to read bytes from
+ /// the current connection. This function will call connection's
+ /// read function:
+ ///
+ /// size_t Connection::Read (void *, size_t);
+ ///
+ /// When bytes are read and cached, this function will call:
+ ///
+ /// Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast);
+ ///
+ /// Subclasses should override this function if they wish to override
+ /// the default action of caching the bytes and broadcasting a \b
+ /// eBroadcastBitReadThreadGotBytes event.
+ ///
+ /// @return
+ /// \b True if the read thread was successfully started, \b
+ /// false otherwise.
+ ///
+ /// @see size_t Connection::Read (void *, size_t);
+ /// @see void Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast);
+ //------------------------------------------------------------------
+ virtual bool
+ StartReadThread (Error *error_ptr = NULL);
+
+ //------------------------------------------------------------------
+ /// Stops the read thread by cancelling it.
+ ///
+ /// @return
+ /// \b True if the read thread was successfully canceled, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ StopReadThread (Error *error_ptr = NULL);
+
+ //------------------------------------------------------------------
+ /// Checks if there is a currently running read thread.
+ ///
+ /// @return
+ /// \b True if the read thread is running, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ReadThreadIsRunning ();
+
+ //------------------------------------------------------------------
+ /// The static read thread function. This function will call
+ /// the "DoRead" function continuously and wait for data to become
+ /// avaialble. When data is received it will append the available
+ /// data to the internal cache and broadcast a
+ /// \b eBroadcastBitReadThreadGotBytes event.
+ ///
+ /// @param[in] comm_ptr
+ /// A pointer to an instance of this class.
+ ///
+ /// @return
+ /// \b NULL.
+ ///
+ /// @see void Communication::ReadThreadGotBytes (const uint8_t *, size_t);
+ //------------------------------------------------------------------
+ static lldb::thread_result_t
+ ReadThread (lldb::thread_arg_t comm_ptr);
+
+ void
+ SetReadThreadBytesReceivedCallback (ReadThreadBytesReceived callback,
+ void *callback_baton);
+
+ static const char *
+ ConnectionStatusAsCString (lldb::ConnectionStatus status);
+
+ bool
+ GetCloseOnEOF () const
+ {
+ return m_close_on_eof;
+ }
+
+ void
+ SetCloseOnEOF (bool b)
+ {
+ m_close_on_eof = b;
+ }
+
+ static ConstString &GetStaticBroadcasterClass ();
+
+ virtual ConstString &GetBroadcasterClass() const
+ {
+ return GetStaticBroadcasterClass();
+ }
+
+private:
+ //------------------------------------------------------------------
+ // For Communication only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (Communication);
+
+
+protected:
+ lldb::ConnectionSP m_connection_sp; ///< The connection that is current in use by this communications class.
+ lldb::thread_t m_read_thread; ///< The read thread handle in case we need to cancel the thread.
+ bool m_read_thread_enabled;
+ std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function.
+ Mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes.
+ Mutex m_write_mutex; ///< Don't let multiple threads write at the same time...
+ ReadThreadBytesReceived m_callback;
+ void *m_callback_baton;
+ bool m_close_on_eof;
+
+ size_t
+ ReadFromConnection (void *dst,
+ size_t dst_len,
+ uint32_t timeout_usec,
+ lldb::ConnectionStatus &status,
+ Error *error_ptr);
+ //------------------------------------------------------------------
+ /// Append new bytes that get read from the read thread into the
+ /// internal object byte cache. This will cause a \b
+ /// eBroadcastBitReadThreadGotBytes event to be broadcast if \a
+ /// broadcast is true.
+ ///
+ /// Subclasses can override this function in order to inspect the
+ /// received data and check if a packet is available.
+ ///
+ /// Subclasses can also still call this function from the
+ /// overridden method to allow the caching to correctly happen and
+ /// suppress the broadcasting of the \a eBroadcastBitReadThreadGotBytes
+ /// event by setting \a broadcast to false.
+ ///
+ /// @param[in] src
+ /// A source buffer that must be at least \a src_len bytes
+ /// long.
+ ///
+ /// @param[in] src_len
+ /// The number of bytes to append to the cache.
+ //------------------------------------------------------------------
+ virtual void
+ AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, lldb::ConnectionStatus status);
+
+ //------------------------------------------------------------------
+ /// Get any available bytes from our data cache. If this call
+ /// empties the data cache, the \b eBroadcastBitReadThreadGotBytes event
+ /// will be reset to signify no more bytes are available.
+ ///
+ /// @param[in] dst
+ /// A destination buffer that must be at least \a dst_len bytes
+ /// long.
+ ///
+ /// @param[in] dst_len
+ /// The number of bytes to attempt to read from the cache,
+ /// and also the max number of bytes that can be placed into
+ /// \a dst.
+ ///
+ /// @return
+ /// The number of bytes extracted from the data cache.
+ //------------------------------------------------------------------
+ size_t
+ GetCachedBytes (void *dst, size_t dst_len);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Communication_h_
diff --git a/include/lldb/Core/Connection.h b/include/lldb/Core/Connection.h
new file mode 100644
index 000000000000..dde3c4b1022c
--- /dev/null
+++ b/include/lldb/Core/Connection.h
@@ -0,0 +1,162 @@
+//===-- Connection.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Connection_h_
+#define liblldb_Connection_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Connection Connection.h "lldb/Core/Connection.h"
+/// @brief A communication connection class.
+///
+/// A class that implements that actual communication functions for
+/// connecting/disconnecting, reading/writing, and waiting for bytes
+/// to become available from a two way communication connection.
+///
+/// This class is designed to only do very simple communication
+/// functions. Instances can be instantiated and given to a
+/// Communication class to perform communications where clients can
+/// listen for broadcasts, and perform other higher level communications.
+//----------------------------------------------------------------------
+class Connection
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor
+ //------------------------------------------------------------------
+ Connection ();
+
+ //------------------------------------------------------------------
+ /// Virtual destructor since this class gets subclassed and handed
+ /// to a Communication object.
+ //------------------------------------------------------------------
+ virtual
+ ~Connection ();
+
+ //------------------------------------------------------------------
+ /// Connect using the connect string \a url.
+ ///
+ /// @param[in] url
+ /// A string that contains all information needed by the
+ /// subclass to connect to another client.
+ ///
+ /// @param[out] error_ptr
+ /// A pointer to an error object that should be given an
+ /// approriate error value if this method returns false. This
+ /// value can be NULL if the error value should be ignored.
+ ///
+ /// @return
+ /// \b True if the connect succeeded, \b false otherwise. The
+ /// internal error object should be filled in with an
+ /// appropriate value based on the result of this function.
+ ///
+ /// @see Error& Communication::GetError ();
+ //------------------------------------------------------------------
+ virtual lldb::ConnectionStatus
+ Connect (const char *url, Error *error_ptr) = 0;
+
+ //------------------------------------------------------------------
+ /// Disconnect the communications connection if one is currently
+ /// connected.
+ ///
+ /// @param[out] error_ptr
+ /// A pointer to an error object that should be given an
+ /// approriate error value if this method returns false. This
+ /// value can be NULL if the error value should be ignored.
+ ///
+ /// @return
+ /// \b True if the disconnect succeeded, \b false otherwise. The
+ /// internal error object should be filled in with an
+ /// appropriate value based on the result of this function.
+ ///
+ /// @see Error& Communication::GetError ();
+ //------------------------------------------------------------------
+ virtual lldb::ConnectionStatus
+ Disconnect (Error *error_ptr) = 0;
+
+ //------------------------------------------------------------------
+ /// Check if the connection is valid.
+ ///
+ /// @return
+ /// \b True if this object is currently connected, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ IsConnected () const = 0;
+
+ //------------------------------------------------------------------
+ /// The read function that attempts to read from the connection.
+ ///
+ /// @param[in] dst
+ /// A destination buffer that must be at least \a dst_len bytes
+ /// long.
+ ///
+ /// @param[in] dst_len
+ /// The number of bytes to attempt to read, and also the max
+ /// number of bytes that can be placed into \a dst.
+ ///
+ /// @param[out] error_ptr
+ /// A pointer to an error object that should be given an
+ /// approriate error value if this method returns zero. This
+ /// value can be NULL if the error value should be ignored.
+ ///
+ /// @return
+ /// The number of bytes actually read.
+ ///
+ /// @see size_t Communication::Read (void *, size_t, uint32_t);
+ //------------------------------------------------------------------
+ virtual size_t
+ Read (void *dst,
+ size_t dst_len,
+ uint32_t timeout_usec,
+ lldb::ConnectionStatus &status,
+ Error *error_ptr) = 0;
+
+ //------------------------------------------------------------------
+ /// The actual write function that attempts to write to the
+ /// communications protocol.
+ ///
+ /// Subclasses must override this function.
+ ///
+ /// @param[in] src
+ /// A source buffer that must be at least \a src_len bytes
+ /// long.
+ ///
+ /// @param[in] src_len
+ /// The number of bytes to attempt to write, and also the
+ /// number of bytes are currently available in \a src.
+ ///
+ /// @param[out] error_ptr
+ /// A pointer to an error object that should be given an
+ /// approriate error value if this method returns zero. This
+ /// value can be NULL if the error value should be ignored.
+ ///
+ /// @return
+ /// The number of bytes actually Written.
+ //------------------------------------------------------------------
+ virtual size_t
+ Write (const void *buffer, size_t length, lldb::ConnectionStatus &status, Error *error_ptr) = 0;
+
+private:
+ //------------------------------------------------------------------
+ // For Connection only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (Connection);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Connection_h_
diff --git a/include/lldb/Core/ConnectionFileDescriptor.h b/include/lldb/Core/ConnectionFileDescriptor.h
new file mode 100644
index 000000000000..fe704d4cadf7
--- /dev/null
+++ b/include/lldb/Core/ConnectionFileDescriptor.h
@@ -0,0 +1,139 @@
+//===-- ConnectionFileDescriptor.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ConnectionFileDescriptor_h_
+#define liblldb_ConnectionFileDescriptor_h_
+
+// C Includes
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Connection.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Host/Predicate.h"
+#include "lldb/Host/SocketAddress.h"
+
+namespace lldb_private {
+
+class ConnectionFileDescriptor :
+ public Connection
+{
+public:
+
+ ConnectionFileDescriptor ();
+
+ ConnectionFileDescriptor (int fd, bool owns_fd);
+
+ virtual
+ ~ConnectionFileDescriptor ();
+
+ virtual bool
+ IsConnected () const;
+
+ virtual lldb::ConnectionStatus
+ Connect (const char *s, Error *error_ptr);
+
+ virtual lldb::ConnectionStatus
+ Disconnect (Error *error_ptr);
+
+ virtual size_t
+ Read (void *dst,
+ size_t dst_len,
+ uint32_t timeout_usec,
+ lldb::ConnectionStatus &status,
+ Error *error_ptr);
+
+ virtual size_t
+ Write (const void *src,
+ size_t src_len,
+ lldb::ConnectionStatus &status,
+ Error *error_ptr);
+
+ // If the read file descriptor is a socket, then return
+ // the port number that is being used by the socket.
+ in_port_t
+ GetReadPort () const;
+
+ // If the write file descriptor is a socket, then return
+ // the port number that is being used by the socket.
+ in_port_t
+ GetWritePort () const;
+
+protected:
+
+ void
+ OpenCommandPipe ();
+
+ void
+ CloseCommandPipe ();
+
+ lldb::ConnectionStatus
+ BytesAvailable (uint32_t timeout_usec, Error *error_ptr);
+
+ lldb::ConnectionStatus
+ SocketListen (uint16_t listen_port_num, Error *error_ptr);
+
+ lldb::ConnectionStatus
+ ConnectTCP (const char *host_and_port, Error *error_ptr);
+
+ lldb::ConnectionStatus
+ ConnectUDP (const char *args, Error *error_ptr);
+
+ lldb::ConnectionStatus
+ NamedSocketAccept (const char *socket_name, Error *error_ptr);
+
+ lldb::ConnectionStatus
+ NamedSocketConnect (const char *socket_name, Error *error_ptr);
+
+ lldb::ConnectionStatus
+ Close (int& fd, Error *error);
+
+ typedef enum
+ {
+ eFDTypeFile, // Other FD requireing read/write
+ eFDTypeSocket, // Socket requiring send/recv
+ eFDTypeSocketUDP // Unconnected UDP socket requiring sendto/recvfrom
+ } FDType;
+
+ int m_fd_send;
+ int m_fd_recv;
+ FDType m_fd_send_type;
+ FDType m_fd_recv_type;
+ SocketAddress m_udp_send_sockaddr;
+ bool m_should_close_fd; // True if this class should close the file descriptor when it goes away.
+ uint32_t m_socket_timeout_usec;
+ int m_pipe_read; // A pipe that we select on the reading end of along with
+ int m_pipe_write; // m_fd_recv so we can force ourselves out of the select.
+ Mutex m_mutex;
+ bool m_shutting_down; // This marks that we are shutting down so if we get woken up from BytesAvailable
+ // to disconnect, we won't try to read again.
+
+ static in_port_t
+ GetSocketPort (int fd);
+
+ static int
+ GetSocketOption(int fd, int level, int option_name, int &option_value);
+
+ static int
+ SetSocketOption(int fd, int level, int option_name, int option_value);
+
+ bool
+ SetSocketReceiveTimeout (uint32_t timeout_usec);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (ConnectionFileDescriptor);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ConnectionFileDescriptor_h_
diff --git a/include/lldb/Core/ConnectionMachPort.h b/include/lldb/Core/ConnectionMachPort.h
new file mode 100644
index 000000000000..5613e7ee8008
--- /dev/null
+++ b/include/lldb/Core/ConnectionMachPort.h
@@ -0,0 +1,92 @@
+//===-- ConnectionMachPort.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#if defined(__APPLE__)
+
+#ifndef liblldb_ConnectionMachPort_h_
+#define liblldb_ConnectionMachPort_h_
+
+// C Includes
+#include <mach/mach.h>
+
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Connection.h"
+
+class ConnectionMachPort :
+ public lldb_private::Connection
+{
+public:
+ ConnectionMachPort ();
+
+ virtual
+ ~ConnectionMachPort ();
+
+ virtual bool
+ IsConnected () const;
+
+ virtual lldb::ConnectionStatus
+ BytesAvailable (uint32_t timeout_usec, lldb_private::Error *error_ptr);
+
+ virtual lldb::ConnectionStatus
+ Connect (const char *s, lldb_private::Error *error_ptr);
+
+ virtual lldb::ConnectionStatus
+ Disconnect (lldb_private::Error *error_ptr);
+
+ virtual size_t
+ Read (void *dst,
+ size_t dst_len,
+ uint32_t timeout_usec,
+ lldb::ConnectionStatus &status,
+ lldb_private::Error *error_ptr);
+
+ virtual size_t
+ Write (const void *src,
+ size_t src_len,
+ lldb::ConnectionStatus &status,
+ lldb_private::Error *error_ptr);
+
+ lldb::ConnectionStatus
+ BootstrapCheckIn (const char *port_name,
+ lldb_private::Error *error_ptr);
+
+ lldb::ConnectionStatus
+ BootstrapLookup (const char *port_name,
+ lldb_private::Error *error_ptr);
+
+ struct PayloadType
+ {
+ uint32_t command;
+ uint32_t data_length;
+ uint8_t data[32];
+ };
+
+ kern_return_t
+ Send (const PayloadType &payload);
+
+ kern_return_t
+ Receive (PayloadType &payload);
+
+
+protected:
+ mach_port_t m_task;
+ mach_port_t m_port;
+
+private:
+
+
+ DISALLOW_COPY_AND_ASSIGN (ConnectionMachPort);
+};
+
+#endif // liblldb_ConnectionMachPort_h_
+
+#endif // #if defined(__APPLE__)
diff --git a/include/lldb/Core/ConnectionSharedMemory.h b/include/lldb/Core/ConnectionSharedMemory.h
new file mode 100644
index 000000000000..0f9cdcb8a92d
--- /dev/null
+++ b/include/lldb/Core/ConnectionSharedMemory.h
@@ -0,0 +1,70 @@
+//===-- ConnectionSharedMemory.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ConnectionSharedMemory_h_
+#define liblldb_ConnectionSharedMemory_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Connection.h"
+#include "lldb/Core/DataBufferMemoryMap.h"
+
+namespace lldb_private {
+
+class ConnectionSharedMemory :
+ public Connection
+{
+public:
+
+ ConnectionSharedMemory ();
+
+ virtual
+ ~ConnectionSharedMemory ();
+
+ virtual bool
+ IsConnected () const;
+
+ virtual lldb::ConnectionStatus
+ BytesAvailable (uint32_t timeout_usec, Error *error_ptr);
+
+ virtual lldb::ConnectionStatus
+ Connect (const char *s, Error *error_ptr);
+
+ virtual lldb::ConnectionStatus
+ Disconnect (Error *error_ptr);
+
+ virtual size_t
+ Read (void *dst,
+ size_t dst_len,
+ uint32_t timeout_usec,
+ lldb::ConnectionStatus &status,
+ Error *error_ptr);
+
+ virtual size_t
+ Write (const void *src, size_t src_len, lldb::ConnectionStatus &status, Error *error_ptr);
+
+ lldb::ConnectionStatus
+ Open (bool create, const char *name, size_t size, Error *error_ptr);
+
+protected:
+
+ std::string m_name;
+ int m_fd; // One buffer that contains all we need
+ DataBufferMemoryMap m_mmap;
+private:
+ DISALLOW_COPY_AND_ASSIGN (ConnectionSharedMemory);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ConnectionSharedMemory_h_
diff --git a/include/lldb/Core/ConstString.h b/include/lldb/Core/ConstString.h
new file mode 100644
index 000000000000..e692d3b96e5d
--- /dev/null
+++ b/include/lldb/Core/ConstString.h
@@ -0,0 +1,507 @@
+//===-- ConstString.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ConstString_h_
+#define liblldb_ConstString_h_
+#if defined(__cplusplus)
+
+#include <assert.h>
+
+#include "lldb/lldb-private.h"
+#include "llvm/ADT/StringRef.h"
+
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ConstString ConstString.h "lldb/Core/ConstString.h"
+/// @brief A uniqued constant string class.
+///
+/// Provides an efficient way to store strings as uniqued strings. After
+/// the strings are uniqued, finding strings that are equal to one
+/// another is very fast as just the pointers need to be compared. It
+/// also allows for many common strings from many different sources to
+/// be shared to keep the memory footprint low.
+///
+/// No reference counting is done on strings that are added to the
+/// string pool, once strings are added they are in the string pool for
+/// the life of the program.
+//----------------------------------------------------------------------
+class ConstString
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor
+ ///
+ /// Initializes the string to an empty string.
+ //------------------------------------------------------------------
+ ConstString ():
+ m_string (NULL)
+ {
+ }
+
+
+ //------------------------------------------------------------------
+ /// Copy constructor
+ ///
+ /// Copies the string value in \a rhs into this object.
+ ///
+ /// @param[in] rhs
+ /// Another string object to copy.
+ //------------------------------------------------------------------
+ ConstString (const ConstString& rhs) :
+ m_string (rhs.m_string)
+ {
+ }
+
+ explicit ConstString (const llvm::StringRef &s);
+
+ //------------------------------------------------------------------
+ /// Construct with C String value
+ ///
+ /// Constructs this object with a C string by looking to see if the
+ /// C string already exists in the global string pool. If it doesn't
+ /// exist, it is added to the string pool.
+ ///
+ /// @param[in] cstr
+ /// A NULL terminated C string to add to the string pool.
+ //------------------------------------------------------------------
+ explicit ConstString (const char *cstr);
+
+ //------------------------------------------------------------------
+ /// Construct with C String value with max length
+ ///
+ /// Constructs this object with a C string with a length. If
+ /// \a max_cstr_len is greater than the actual length of the string,
+ /// the string length will be truncated. This allows substrings to
+ /// be created without the need to NULL terminate the string as it
+ /// is passed into this function.
+ ///
+ /// @param[in] cstr
+ /// A pointer to the first character in the C string. The C
+ /// string can be NULL terminated in a buffer that contains
+ /// more characters than the length of the stirng, or the
+ /// string can be part of another string and a new substring
+ /// can be created.
+ ///
+ /// @param[in] max_cstr_len
+ /// The max length of \a cstr. If the string length of \a cstr
+ /// is less than \a max_cstr_len, then the string will be
+ /// truncated. If the string length of \a cstr is greater than
+ /// \a max_cstr_len, then only max_cstr_len bytes will be used
+ /// from \a cstr.
+ //------------------------------------------------------------------
+ explicit ConstString (const char *cstr, size_t max_cstr_len);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ ///
+ /// Since constant string values are currently not reference counted,
+ /// there isn't much to do here.
+ //------------------------------------------------------------------
+ ~ConstString ()
+ {
+ }
+
+
+ //----------------------------------------------------------------------
+ /// C string equality binary predicate function object for ConstString
+ /// objects.
+ //----------------------------------------------------------------------
+ struct StringIsEqual
+ {
+ //--------------------------------------------------------------
+ /// C equality test.
+ ///
+ /// Two C strings are equal when they are contained in ConstString
+ /// objects when their pointer values are equal to each other.
+ ///
+ /// @return
+ /// Returns \b true if the C string in \a lhs is equal to
+ /// the C string value in \a rhs, \b false otherwise.
+ //--------------------------------------------------------------
+ bool operator()(const char* lhs, const char* rhs) const
+ {
+ return lhs == rhs;
+ }
+ };
+
+ //------------------------------------------------------------------
+ /// Convert to bool operator.
+ ///
+ /// This allows code to check a ConstString object to see if it
+ /// contains a valid string using code such as:
+ ///
+ /// @code
+ /// ConstString str(...);
+ /// if (str)
+ /// { ...
+ /// @endcode
+ ///
+ /// @return
+ /// /b True this object contains a valid non-empty C string, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ operator bool() const
+ {
+ return m_string && m_string[0];
+ }
+
+ //------------------------------------------------------------------
+ /// Assignment operator
+ ///
+ /// Assigns the string in this object with the value from \a rhs.
+ ///
+ /// @param[in] rhs
+ /// Another string object to copy into this object.
+ ///
+ /// @return
+ /// A const reference to this object.
+ //------------------------------------------------------------------
+ const ConstString&
+ operator = (const ConstString& rhs)
+ {
+ m_string = rhs.m_string;
+ return *this;
+ }
+
+ //------------------------------------------------------------------
+ /// Equal to operator
+ ///
+ /// Returns true if this string is equal to the string in \a rhs.
+ /// This operation is very fast as it results in a pointer
+ /// comparison since all strings are in a uniqued in a global string
+ /// pool.
+ ///
+ /// @param[in] rhs
+ /// Another string object to compare this object to.
+ ///
+ /// @return
+ /// @li \b true if this object is equal to \a rhs.
+ /// @li \b false if this object is not equal to \a rhs.
+ //------------------------------------------------------------------
+ bool
+ operator == (const ConstString& rhs) const
+ {
+ // We can do a pointer compare to compare these strings since they
+ // must come from the same pool in order to be equal.
+ return m_string == rhs.m_string;
+ }
+
+ //------------------------------------------------------------------
+ /// Not equal to operator
+ ///
+ /// Returns true if this string is not equal to the string in \a rhs.
+ /// This operation is very fast as it results in a pointer
+ /// comparison since all strings are in a uniqued in a global string
+ /// pool.
+ ///
+ /// @param[in] rhs
+ /// Another string object to compare this object to.
+ ///
+ /// @return
+ /// @li \b true if this object is not equal to \a rhs.
+ /// @li \b false if this object is equal to \a rhs.
+ //------------------------------------------------------------------
+ bool
+ operator != (const ConstString& rhs) const
+ {
+ return m_string != rhs.m_string;
+ }
+
+ bool
+ operator < (const ConstString& rhs) const;
+
+ //------------------------------------------------------------------
+ /// Get the string value as a C string.
+ ///
+ /// Get the value of the contained string as a NULL terminated C
+ /// string value.
+ ///
+ /// If \a value_if_empty is NULL, then NULL will be returned.
+ ///
+ /// @return
+ /// Returns \a value_if_empty if the string is empty, otherwise
+ /// the C string value contained in this object.
+ //------------------------------------------------------------------
+ const char *
+ AsCString(const char *value_if_empty = NULL) const
+ {
+ if (m_string == NULL)
+ return value_if_empty;
+ return m_string;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the string value as a llvm::StringRef
+ ///
+ /// @return
+ /// Returns a new llvm::StringRef object filled in with the
+ /// needed data.
+ //------------------------------------------------------------------
+ llvm::StringRef
+ GetStringRef () const
+ {
+ return llvm::StringRef (m_string, GetLength());
+ }
+
+ //------------------------------------------------------------------
+ /// Get the string value as a C string.
+ ///
+ /// Get the value of the contained string as a NULL terminated C
+ /// string value. Similar to the ConstString::AsCString() function,
+ /// yet this function will always return NULL if the string is not
+ /// valid. So this function is a direct accessor to the string
+ /// pointer value.
+ ///
+ /// @return
+ /// Returns NULL the string is invalid, otherwise the C string
+ /// value contained in this object.
+ //------------------------------------------------------------------
+ const char *
+ GetCString () const
+ {
+ return m_string;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Get the length in bytes of string value.
+ ///
+ /// The string pool stores the length of the string, so we can avoid
+ /// calling strlen() on the pointer value with this function.
+ ///
+ /// @return
+ /// Returns the number of bytes that this string occupies in
+ /// memory, not including the NULL termination byte.
+ //------------------------------------------------------------------
+ size_t
+ GetLength () const;
+
+ //------------------------------------------------------------------
+ /// Clear this object's state.
+ ///
+ /// Clear any contained string and reset the value to the an empty
+ /// string value.
+ //------------------------------------------------------------------
+ void
+ Clear ()
+ {
+ m_string = NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Compare two string objects.
+ ///
+ /// Compares the C string values contained in \a lhs and \a rhs and
+ /// returns an integer result.
+ ///
+ /// NOTE: only call this function when you want a true string
+ /// comparision. If you want string equality use the, use the ==
+ /// operator as it is much more efficient. Also if you want string
+ /// inequality, use the != operator for the same reasons.
+ ///
+ /// @param[in] lhs
+ /// The Left Hand Side const ConstString object reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const ConstString object reference.
+ ///
+ /// @return
+ /// @li -1 if lhs < rhs
+ /// @li 0 if lhs == rhs
+ /// @li 1 if lhs > rhs
+ //------------------------------------------------------------------
+ static int
+ Compare (const ConstString& lhs, const ConstString& rhs);
+
+ //------------------------------------------------------------------
+ /// Dump the object description to a stream.
+ ///
+ /// Dump the string value to the stream \a s. If the contained string
+ /// is empty, print \a value_if_empty to the stream instead. If
+ /// \a value_if_empty is NULL, then nothing will be dumped to the
+ /// stream.
+ ///
+ /// @param[in] s
+ /// The stream that will be used to dump the object description.
+ ///
+ /// @param[in] value_if_empty
+ /// The value to dump if the string is empty. If NULL, nothing
+ /// will be output to the stream.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, const char *value_if_empty = NULL) const;
+
+ //------------------------------------------------------------------
+ /// Dump the object debug description to a stream.
+ ///
+ /// @param[in] s
+ /// The stream that will be used to dump the object description.
+ //------------------------------------------------------------------
+ void
+ DumpDebug (Stream *s) const;
+
+ //------------------------------------------------------------------
+ /// Test for empty string.
+ ///
+ /// @return
+ /// @li \b true if the contained string is empty.
+ /// @li \b false if the contained string is not empty.
+ //------------------------------------------------------------------
+ bool
+ IsEmpty () const
+ {
+ return m_string == NULL || m_string[0] == '\0';
+ }
+
+ //------------------------------------------------------------------
+ /// Set the C string value.
+ ///
+ /// Set the string value in the object by uniquing the \a cstr
+ /// string value in our global string pool.
+ ///
+ /// If the C string already exists in the global string pool, it
+ /// finds the current entry and returns the existing value. If it
+ /// doesn't exist, it is added to the string pool.
+ ///
+ /// @param[in] cstr
+ /// A NULL terminated C string to add to the string pool.
+ //------------------------------------------------------------------
+ void
+ SetCString (const char *cstr);
+
+ void
+ SetString (const llvm::StringRef &s);
+
+ //------------------------------------------------------------------
+ /// Set the C string value and its mangled counterpart.
+ ///
+ /// Object files and debug sybmols often use mangled string to
+ /// represent the linkage name for a symbol, function or global.
+ /// The string pool can efficiently store these values and their
+ /// counterparts so when we run into another instance of a mangled
+ /// name, we can avoid calling the name demangler over and over on
+ /// the same strings and then trying to unique them.
+ ///
+ /// @param[in] demangled
+ /// The demangled C string to correlate with the \a mangled
+ /// name.
+ ///
+ /// @param[in] mangled
+ /// The already uniqued mangled ConstString to correlate the
+ /// soon to be uniqued version of \a demangled.
+ //------------------------------------------------------------------
+ void
+ SetCStringWithMangledCounterpart (const char *demangled,
+ const ConstString &mangled);
+
+ //------------------------------------------------------------------
+ /// Retrieve the mangled or demangled counterpart for a mangled
+ /// or demangled ConstString.
+ ///
+ /// Object files and debug sybmols often use mangled string to
+ /// represent the linkage name for a symbol, function or global.
+ /// The string pool can efficiently store these values and their
+ /// counterparts so when we run into another instance of a mangled
+ /// name, we can avoid calling the name demangler over and over on
+ /// the same strings and then trying to unique them.
+ ///
+ /// @param[in] counterpart
+ /// A reference to a ConstString object that might get filled in
+ /// with the demangled/mangled counterpart.
+ ///
+ /// @return
+ /// /b True if \a counterpart was filled in with the counterpart
+ /// /b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetMangledCounterpart (ConstString &counterpart) const;
+
+ //------------------------------------------------------------------
+ /// Set the C string value with length.
+ ///
+ /// Set the string value in the object by uniquing \a cstr_len bytes
+ /// starting at the \a cstr string value in our global string pool.
+ /// If trim is true, then \a cstr_len indicates a maximum length of
+ /// the CString and if the actual length of the string is less, then
+ /// it will be trimmed.
+ ///
+ /// If the C string already exists in the global string pool, it
+ /// finds the current entry and returns the existing value. If it
+ /// doesn't exist, it is added to the string pool.
+ ///
+ /// @param[in] cstr
+ /// A NULL terminated C string to add to the string pool.
+ ///
+ /// @param[in] cstr_len
+ /// The maximum length of the C string.
+ //------------------------------------------------------------------
+ void
+ SetCStringWithLength (const char *cstr, size_t cstr_len);
+
+ //------------------------------------------------------------------
+ /// Set the C string value with the minimum length between
+ /// \a fixed_cstr_len and the actual length of the C string. This
+ /// can be used for data structures that have a fixed length to
+ /// store a C string where the string might not be NULL terminated
+ /// if the string takes the entire buffer.
+ //------------------------------------------------------------------
+ void
+ SetTrimmedCStringWithLength (const char *cstr, size_t fixed_cstr_len);
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// Return the size in bytes that this object takes in memory. This
+ /// returns the size in bytes of this object, which does not include
+ /// any the shared string values it may refer to.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ size_t
+ MemorySize () const
+ {
+ return sizeof(ConstString);
+ }
+
+
+ //------------------------------------------------------------------
+ /// Get the size in bytes of the current global string pool.
+ ///
+ /// Reports the the size in bytes of all shared C string values,
+ /// containers and any other values as a byte size for the
+ /// entire string pool.
+ ///
+ /// @return
+ /// The number of bytes that the global string pool occupies
+ /// in memory.
+ //------------------------------------------------------------------
+ static size_t
+ StaticMemorySize ();
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ const char *m_string;
+};
+
+//------------------------------------------------------------------
+/// Stream the string value \a str to the stream \a s
+//------------------------------------------------------------------
+Stream& operator << (Stream& s, const ConstString& str);
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_ConstString_h_
diff --git a/include/lldb/Core/DataBuffer.h b/include/lldb/Core/DataBuffer.h
new file mode 100644
index 000000000000..e64245dead3d
--- /dev/null
+++ b/include/lldb/Core/DataBuffer.h
@@ -0,0 +1,94 @@
+//===-- DataBuffer.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DataBuffer_h_
+#define liblldb_DataBuffer_h_
+#if defined(__cplusplus)
+
+#include <stdint.h>
+#include <string.h>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class DataBuffer DataBuffer.h "lldb/Core/DataBuffer.h"
+/// @brief A pure virtual protocol class for abstracted data buffers.
+///
+/// DataBuffer is an abtract class that gets packaged into a shared pointer
+/// that can use to implement various ways to store data (on the heap,
+/// memory mapped, cached inferior memory). It gets used by DataExtractor
+/// so many DataExtractor objects can share the same data and sub-ranges
+/// of that shared data, and the last object that contains a reference
+/// to the shared data will free it.
+///
+/// Subclasses can implement as many different constructors or member
+/// functions that allow data to be stored in the object's buffer prior
+/// to handing the shared data to clients that use these buffers.
+///
+/// All subclasses must override all of the pure virtual functions as
+/// they are used by clients to access the data. Having a common
+/// interface allows different ways of storing data, yet using it in
+/// one common way.
+///
+/// This class currently expects all data to be available without any
+/// extra calls being made, but we can modify it to optionally get
+/// data on demand with some extra function calls to load the data
+/// before it gets accessed.
+//----------------------------------------------------------------------
+class DataBuffer
+{
+public:
+ //------------------------------------------------------------------
+ /// Destructor
+ ///
+ /// The destructor is virtual as other classes will inherit from
+ /// this class and be downcast to the DataBuffer pure virtual
+ /// interface. The virtual destructor ensures that destructing the
+ /// base class will destruct the class that inherited from it
+ /// correctly.
+ //------------------------------------------------------------------
+ virtual
+ ~DataBuffer()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Get a pointer to the data.
+ ///
+ /// @return
+ /// A pointer to the bytes owned by this object, or NULL if the
+ /// object contains no bytes.
+ //------------------------------------------------------------------
+ virtual uint8_t *
+ GetBytes () = 0;
+
+ //------------------------------------------------------------------
+ /// Get a const pointer to the data.
+ ///
+ /// @return
+ /// A const pointer to the bytes owned by this object, or NULL
+ /// if the object contains no bytes.
+ //------------------------------------------------------------------
+ virtual const uint8_t *
+ GetBytes () const = 0;
+
+ //------------------------------------------------------------------
+ /// Get the number of bytes in the data buffer.
+ ///
+ /// @return
+ /// The number of bytes this object currently contains.
+ //------------------------------------------------------------------
+ virtual lldb::offset_t
+ GetByteSize() const = 0;
+};
+
+} // namespace lldb_private
+
+#endif /// #if defined(__cplusplus)
+#endif /// lldb_DataBuffer_h_
diff --git a/include/lldb/Core/DataBufferHeap.h b/include/lldb/Core/DataBufferHeap.h
new file mode 100644
index 000000000000..dac9a28befb9
--- /dev/null
+++ b/include/lldb/Core/DataBufferHeap.h
@@ -0,0 +1,139 @@
+//===-- DataBufferHeap.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DataBufferHeap_h_
+#define liblldb_DataBufferHeap_h_
+#if defined(__cplusplus)
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/DataBuffer.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class DataBufferHeap DataBufferHeap.h "lldb/Core/DataBufferHeap.h"
+/// @brief A subclass of DataBuffer that stores a data buffer on the heap.
+///
+/// This class keeps its data in a heap based buffer that is owned by
+/// the object. This class is best used to store chunks of data that
+/// are created or read from sources that can't intelligently and lazily
+/// fault new data pages in. Large amounts of data that comes from files
+/// should probably use the DataBufferMemoryMap class.
+//----------------------------------------------------------------------
+class DataBufferHeap : public DataBuffer
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor
+ ///
+ /// Initializes the heap based buffer with no bytes.
+ //------------------------------------------------------------------
+ DataBufferHeap ();
+
+ //------------------------------------------------------------------
+ /// Construct with size \a n and fill with \a ch.
+ ///
+ /// Initialize this class with \a n bytes and fills the buffer with
+ /// \a ch.
+ ///
+ /// @param[in] n
+ /// The number of bytes that heap based buffer should contain.
+ ///
+ /// @param[in] ch
+ /// The character to use when filling the buffer initially.
+ //------------------------------------------------------------------
+ DataBufferHeap (lldb::offset_t n, uint8_t ch);
+
+ //------------------------------------------------------------------
+ /// Construct by making a copy of \a src_len bytes from \a src.
+ ///
+ /// @param[in] src
+ /// A pointer to the data to copy.
+ ///
+ /// @param[in] src_len
+ /// The number of bytes in \a src to copy.
+ //------------------------------------------------------------------
+ DataBufferHeap (const void *src, lldb::offset_t src_len);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// Virtual destructor since this class inherits from a pure virtual
+ /// base class #DataBuffer.
+ //------------------------------------------------------------------
+ virtual
+ ~DataBufferHeap();
+
+ //------------------------------------------------------------------
+ /// @copydoc DataBuffer::GetBytes()
+ //------------------------------------------------------------------
+ virtual uint8_t *
+ GetBytes ();
+
+ //------------------------------------------------------------------
+ /// @copydoc DataBuffer::GetBytes() const
+ //------------------------------------------------------------------
+ virtual const uint8_t *
+ GetBytes () const;
+
+ //------------------------------------------------------------------
+ /// @copydoc DataBuffer::GetByteSize() const
+ //------------------------------------------------------------------
+ virtual lldb::offset_t
+ GetByteSize () const;
+
+ //------------------------------------------------------------------
+ /// Set the number of bytes in the data buffer.
+ ///
+ /// Sets the number of bytes that this object should be able to
+ /// contain. This can be used prior to copying data into the buffer.
+ ///
+ /// @param[in] byte_size
+ /// The new size in bytes that this data buffer should attempt
+ /// to resize itself to.
+ ///
+ /// @return
+ /// The size in bytes after that this heap buffer was
+ /// successfully resized to.
+ //------------------------------------------------------------------
+ lldb::offset_t
+ SetByteSize (lldb::offset_t byte_size);
+
+ //------------------------------------------------------------------
+ /// Makes a copy of the \a src_len bytes in \a src.
+ ///
+ /// Copies the data in \a src into an internal buffer.
+ ///
+ /// @param[in] src
+ /// A pointer to the data to copy.
+ ///
+ /// @param[in] src_len
+ /// The number of bytes in \a src to copy.
+ //------------------------------------------------------------------
+ void
+ CopyData (const void *src, lldb::offset_t src_len);
+
+ void
+ Clear();
+
+private:
+ //------------------------------------------------------------------
+ // This object uses a std::vector<uint8_t> to store its data. This
+ // takes care of free the data when the object is deleted.
+ //------------------------------------------------------------------
+ typedef std::vector<uint8_t> buffer_t; ///< Buffer type
+ buffer_t m_data; ///< The heap based buffer where data is stored
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_DataBufferHeap_h_
diff --git a/include/lldb/Core/DataBufferMemoryMap.h b/include/lldb/Core/DataBufferMemoryMap.h
new file mode 100644
index 000000000000..d4a448a5df52
--- /dev/null
+++ b/include/lldb/Core/DataBufferMemoryMap.h
@@ -0,0 +1,160 @@
+//===-- DataBufferMemoryMap.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DataBufferMemoryMap_h_
+#define liblldb_DataBufferMemoryMap_h_
+#if defined(__cplusplus)
+
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/Error.h"
+#include <string>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class DataBufferMemoryMap DataBufferMemoryMap.h "lldb/Core/DataBufferMemoryMap.h"
+/// @brief A subclass of DataBuffer that memory maps data.
+///
+/// This class memory maps data and stores any needed data for the
+/// memory mapping in its internal state. Memory map requests are not
+/// required to have any alignment or size constraints, this class will
+/// work around any host OS issues regarding such things.
+///
+/// This class is designed to allow pages to be faulted in as needed and
+/// works well data from large files that won't be accessed all at once.
+//----------------------------------------------------------------------
+class DataBufferMemoryMap : public DataBuffer
+{
+public:
+ //------------------------------------------------------------------
+ /// Default Constructor
+ //------------------------------------------------------------------
+ DataBufferMemoryMap ();
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// Virtual destructor since this class inherits from a pure virtual
+ /// base class #DataBuffer.
+ //------------------------------------------------------------------
+ virtual
+ ~DataBufferMemoryMap ();
+
+ //------------------------------------------------------------------
+ /// Reverts this object to an empty state by unmapping any memory
+ /// that is currently owned.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// @copydoc DataBuffer::GetBytes()
+ //------------------------------------------------------------------
+ virtual uint8_t *
+ GetBytes ();
+
+ //------------------------------------------------------------------
+ /// @copydoc DataBuffer::GetBytes() const
+ //------------------------------------------------------------------
+ virtual const uint8_t *
+ GetBytes () const;
+
+ //------------------------------------------------------------------
+ /// @copydoc DataBuffer::GetByteSize() const
+ //------------------------------------------------------------------
+ virtual lldb::offset_t
+ GetByteSize () const;
+
+ //------------------------------------------------------------------
+ /// Error get accessor.
+ ///
+ /// @return
+ /// A const reference to Error object in case memory mapping
+ /// fails.
+ //------------------------------------------------------------------
+ const Error &
+ GetError() const;
+
+ //------------------------------------------------------------------
+ /// Memory map all or part of a file.
+ ///
+ /// Memory map \a length bytes from \a file starting \a offset
+ /// bytes into the file. If \a length is set to \c SIZE_MAX,
+ /// then map as many bytes as possible.
+ ///
+ /// @param[in] file
+ /// The file specification from which to map data.
+ ///
+ /// @param[in] offset
+ /// The offset in bytes from the beginning of the file where
+ /// memory mapping should begin.
+ ///
+ /// @param[in] length
+ /// The size in bytes that should be mapped starting \a offset
+ /// bytes into the file. If \a length is \c SIZE_MAX, map
+ /// as many bytes as possible.
+ ///
+ /// @return
+ /// The number of bytes mapped starting from the \a offset.
+ //------------------------------------------------------------------
+ size_t
+ MemoryMapFromFileSpec (const FileSpec* file,
+ lldb::offset_t offset = 0,
+ lldb::offset_t length = SIZE_MAX,
+ bool writeable = false);
+
+ //------------------------------------------------------------------
+ /// Memory map all or part of a file.
+ ///
+ /// Memory map \a length bytes from an opened file descriptor \a fd
+ /// starting \a offset bytes into the file. If \a length is set to
+ /// \c SIZE_MAX, then map as many bytes as possible.
+ ///
+ /// @param[in] fd
+ /// The posix file descriptor for an already opened file
+ /// from which to map data.
+ ///
+ /// @param[in] offset
+ /// The offset in bytes from the beginning of the file where
+ /// memory mapping should begin.
+ ///
+ /// @param[in] length
+ /// The size in bytes that should be mapped starting \a offset
+ /// bytes into the file. If \a length is \c SIZE_MAX, map
+ /// as many bytes as possible.
+ ///
+ /// @return
+ /// The number of bytes mapped starting from the \a offset.
+ //------------------------------------------------------------------
+ size_t
+ MemoryMapFromFileDescriptor (int fd,
+ lldb::offset_t offset,
+ lldb::offset_t length,
+ bool write,
+ bool fd_is_file);
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from DataBufferMemoryMap can see and modify these
+ //------------------------------------------------------------------
+ uint8_t * m_mmap_addr; ///< The actual pointer that was returned from \c mmap()
+ size_t m_mmap_size; ///< The actual number of bytes that were mapped when \c mmap() was called
+ uint8_t *m_data; ///< The data the user requested somewhere within the memory mapped data.
+ lldb::offset_t m_size; ///< The size of the data the user got when data was requested
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (DataBufferMemoryMap);
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_DataBufferMemoryMap_h_
diff --git a/include/lldb/Core/DataEncoder.h b/include/lldb/Core/DataEncoder.h
new file mode 100644
index 000000000000..658cce0d2b4b
--- /dev/null
+++ b/include/lldb/Core/DataEncoder.h
@@ -0,0 +1,459 @@
+//===-- DataEncoder.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DataEncoder_h_
+#define liblldb_DataEncoder_h_
+
+#if defined (__cplusplus)
+
+#include "lldb/lldb-private.h"
+#include <limits.h>
+#include <stdint.h>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class DataEncoder DataEncoder.h "lldb/Core/DataEncoder.h"
+/// @brief An binary data encoding class.
+///
+/// DataEncoder is a class that can encode binary data (swapping if needed)
+/// to a data buffer. The data buffer can be caller owned, or can be
+/// shared data that can be shared between multiple DataEncoder or
+/// DataEncoder instances.
+///
+/// @see DataBuffer
+//----------------------------------------------------------------------
+class DataEncoder
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize all members to a default empty state.
+ //------------------------------------------------------------------
+ DataEncoder ();
+
+ //------------------------------------------------------------------
+ /// Construct with a buffer that is owned by the caller.
+ ///
+ /// This constructor allows us to use data that is owned by the
+ /// caller. The data must stay around as long as this object is
+ /// valid.
+ ///
+ /// @param[in] data
+ /// A pointer to caller owned data.
+ ///
+ /// @param[in] data_length
+ /// The length in bytes of \a data.
+ ///
+ /// @param[in] byte_order
+ /// A byte order of the data that we are extracting from.
+ ///
+ /// @param[in] addr_size
+ /// A new address byte size value.
+ //------------------------------------------------------------------
+ DataEncoder (void* data, uint32_t data_length, lldb::ByteOrder byte_order, uint8_t addr_size);
+
+ //------------------------------------------------------------------
+ /// Construct with shared data.
+ ///
+ /// Copies the data shared pointer which adds a reference to the
+ /// contained in \a data_sp. The shared data reference is reference
+ /// counted to ensure the data lives as long as anyone still has a
+ /// valid shared pointer to the data in \a data_sp.
+ ///
+ /// @param[in] data_sp
+ /// A shared pointer to data.
+ ///
+ /// @param[in] byte_order
+ /// A byte order of the data that we are extracting from.
+ ///
+ /// @param[in] addr_size
+ /// A new address byte size value.
+ //------------------------------------------------------------------
+ DataEncoder (const lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint8_t addr_size);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ ///
+ /// If this object contains a valid shared data reference, the
+ /// reference count on the data will be decremented, and if zero,
+ /// the data will be freed.
+ //------------------------------------------------------------------
+ ~DataEncoder ();
+
+ //------------------------------------------------------------------
+ /// Clears the object state.
+ ///
+ /// Clears the object contents back to a default invalid state, and
+ /// release any references to shared data that this object may
+ /// contain.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Get the current address size.
+ ///
+ /// Return the size in bytes of any address values this object will
+ /// extract.
+ ///
+ /// @return
+ /// The size in bytes of address values that will be extracted.
+ //------------------------------------------------------------------
+ uint8_t
+ GetAddressByteSize () const
+ {
+ return m_addr_size;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Get the number of bytes contained in this object.
+ ///
+ /// @return
+ /// The total number of bytes of data this object refers to.
+ //------------------------------------------------------------------
+ size_t
+ GetByteSize () const
+ {
+ return m_end - m_start;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the data end pointer.
+ ///
+ /// @return
+ /// Returns a pointer to the next byte contained in this
+ /// object's data, or NULL of there is no data in this object.
+ //------------------------------------------------------------------
+ uint8_t *
+ GetDataEnd ()
+ {
+ return m_end;
+ }
+
+ const uint8_t *
+ GetDataEnd () const
+ {
+ return m_end;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the shared data offset.
+ ///
+ /// Get the offset of the first byte of data in the shared data (if
+ /// any).
+ ///
+ /// @return
+ /// If this object contains shared data, this function returns
+ /// the offset in bytes into that shared data, zero otherwise.
+ //------------------------------------------------------------------
+ size_t
+ GetSharedDataOffset () const;
+
+
+ //------------------------------------------------------------------
+ /// Get the current byte order value.
+ ///
+ /// @return
+ /// The current byte order value from this object's internal
+ /// state.
+ //------------------------------------------------------------------
+ lldb::ByteOrder
+ GetByteOrder() const
+ {
+ return m_byte_order;
+ }
+
+ //------------------------------------------------------------------
+ /// Get a the data start pointer.
+ ///
+ /// @return
+ /// Returns a pointer to the first byte contained in this
+ /// object's data, or NULL of there is no data in this object.
+ //------------------------------------------------------------------
+ uint8_t *
+ GetDataStart ()
+ {
+ return m_start;
+ }
+
+ const uint8_t *
+ GetDataStart () const
+ {
+ return m_start;
+ }
+
+ //------------------------------------------------------------------
+ /// Encode unsigned integer values into the data at \a offset.
+ ///
+ /// @param[in] offset
+ /// The offset within the contained data at which to put the
+ /// data.
+ ///
+ /// @param[in] value
+ /// The value to encode into the data.
+ ///
+ /// @return
+ /// The next offset in the bytes of this data if the data
+ /// was successfully encoded, UINT32_MAX if the encoding failed.
+ //------------------------------------------------------------------
+ uint32_t
+ PutU8 (uint32_t offset, uint8_t value);
+
+ uint32_t
+ PutU16 (uint32_t offset, uint16_t value);
+
+ uint32_t
+ PutU32 (uint32_t offset, uint32_t value);
+
+ uint32_t
+ PutU64 (uint32_t offset, uint64_t value);
+
+ //------------------------------------------------------------------
+ /// Encode an unsigned integer of size \a byte_size to \a offset.
+ ///
+ /// Encode a single integer value at \a offset and return the offset
+ /// that follows the newly encoded integer when the data is successfully
+ /// encoded into the existing data. There must be enough room in the
+ /// data, else UINT32_MAX will be returned to indicate that encoding
+ /// failed.
+ ///
+ /// @param[in] offset
+ /// The offset within the contained data at which to put the
+ /// encoded integer.
+ ///
+ /// @param[in] byte_size
+ /// The size in byte of the integer to encode.
+ ///
+ /// @param[in] value
+ /// The integer value to write. The least significate bytes of
+ /// the integer value will be written if the size is less than
+ /// 8 bytes.
+ ///
+ /// @return
+ /// The next offset in the bytes of this data if the integer
+ /// was successfully encoded, UINT32_MAX if the encoding failed.
+ //------------------------------------------------------------------
+ uint32_t
+ PutMaxU64 (uint32_t offset, uint32_t byte_size, uint64_t value);
+
+ //------------------------------------------------------------------
+ /// Encode an arbitrary number of bytes.
+ ///
+ /// @param[in] offset
+ /// The offset in bytes into the contained data at which to
+ /// start encoding.
+ ///
+ /// @param[int] src
+ /// The buffer that contains the the bytes to encode.
+ ///
+ /// @param[in] src_len
+ /// The number of bytes to encode.
+ ///
+ /// @return
+ /// The next valid offset within data if the put operation
+ /// was successful, else UINT32_MAX to indicate the put failed.
+ //------------------------------------------------------------------
+ uint32_t
+ PutData (uint32_t offset,
+ const void *src,
+ uint32_t src_len);
+
+ //------------------------------------------------------------------
+ /// Encode an address in the existing buffer at \a offset bytes into
+ /// the buffer.
+ ///
+ /// Encode a single address (honoring the m_addr_size member) to
+ /// the data and return the next offset where subsequent data would
+ /// go.
+ /// pointed to by \a offset_ptr. The size of the extracted address
+ /// comes from the \a m_addr_size member variable and should be
+ /// set correctly prior to extracting any address values.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The next valid offset within data if the put operation
+ /// was successful, else UINT32_MAX to indicate the put failed.
+ //------------------------------------------------------------------
+ uint32_t
+ PutAddress (uint32_t offset, lldb::addr_t addr);
+
+ //------------------------------------------------------------------
+ /// Put a C string to \a offset.
+ ///
+ /// Encodes a C string into the existing data including the
+ /// terminating
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// A pointer to the C string value in the data. If the offset
+ /// pointed to by \a offset_ptr is out of bounds, or if the
+ /// offset plus the length of the C string is out of bounds,
+ /// NULL will be returned.
+ //------------------------------------------------------------------
+ uint32_t
+ PutCString (uint32_t offset_ptr, const char *cstr);
+
+ lldb::DataBufferSP &
+ GetSharedDataBuffer ()
+ {
+ return m_data_sp;
+ }
+
+ //------------------------------------------------------------------
+ /// Set the address byte size.
+ ///
+ /// Set the size in bytes that will be used when extracting any
+ /// address and pointer values from data contained in this object.
+ ///
+ /// @param[in] addr_size
+ /// The size in bytes to use when extracting addresses.
+ //------------------------------------------------------------------
+ void
+ SetAddressByteSize (uint8_t addr_size)
+ {
+ m_addr_size = addr_size;
+ }
+
+ //------------------------------------------------------------------
+ /// Set data with a buffer that is caller owned.
+ ///
+ /// Use data that is owned by the caller when extracting values.
+ /// The data must stay around as long as this object, or any object
+ /// that copies a subset of this object's data, is valid. If \a
+ /// bytes is NULL, or \a length is zero, this object will contain
+ /// no data.
+ ///
+ /// @param[in] bytes
+ /// A pointer to caller owned data.
+ ///
+ /// @param[in] length
+ /// The length in bytes of \a bytes.
+ ///
+ /// @param[in] byte_order
+ /// A byte order of the data that we are extracting from.
+ ///
+ /// @return
+ /// The number of bytes that this object now contains.
+ //------------------------------------------------------------------
+ uint32_t
+ SetData (const void *bytes, uint32_t length, lldb::ByteOrder byte_order);
+
+ //------------------------------------------------------------------
+ /// Adopt a subset of shared data in \a data_sp.
+ ///
+ /// Copies the data shared pointer which adds a reference to the
+ /// contained in \a data_sp. The shared data reference is reference
+ /// counted to ensure the data lives as long as anyone still has a
+ /// valid shared pointer to the data in \a data_sp. The byte order
+ /// and address byte size settings remain the same. If
+ /// \a offset is not a valid offset in \a data_sp, then no reference
+ /// to the shared data will be added. If there are not \a length
+ /// bytes available in \a data starting at \a offset, the length
+ /// will be truncated to contains as many bytes as possible.
+ ///
+ /// @param[in] data_sp
+ /// A shared pointer to data.
+ ///
+ /// @param[in] offset
+ /// The offset into \a data_sp at which the subset starts.
+ ///
+ /// @param[in] length
+ /// The length in bytes of the subset of \a data_sp.
+ ///
+ /// @return
+ /// The number of bytes that this object now contains.
+ //------------------------------------------------------------------
+ uint32_t
+ SetData (const lldb::DataBufferSP& data_sp, uint32_t offset = 0, uint32_t length = UINT32_MAX);
+
+ //------------------------------------------------------------------
+ /// Set the byte_order value.
+ ///
+ /// Sets the byte order of the data to extract. Extracted values
+ /// will be swapped if necessary when decoding.
+ ///
+ /// @param[in] byte_order
+ /// The byte order value to use when extracting data.
+ //------------------------------------------------------------------
+ void
+ SetByteOrder (lldb::ByteOrder byte_order)
+ {
+ m_byte_order = byte_order;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Test the validity of \a offset.
+ ///
+ /// @return
+ /// \b true if \a offset is a valid offset into the data in this
+ /// object, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ValidOffset (uint32_t offset) const
+ {
+ return offset < GetByteSize();
+ }
+
+ //------------------------------------------------------------------
+ /// Test the availability of \a length bytes of data from \a offset.
+ ///
+ /// @return
+ /// \b true if \a offset is a valid offset and there are \a
+ /// length bytes available at that offset, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ValidOffsetForDataOfSize (uint32_t offset, uint32_t length) const
+ {
+ return length <= BytesLeft (offset);
+ }
+
+ uint32_t
+ BytesLeft (uint32_t offset) const
+ {
+ const uint32_t size = GetByteSize();
+ if (size > offset)
+ return size - offset;
+ return 0;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ uint8_t *m_start; ///< A pointer to the first byte of data.
+ uint8_t *m_end; ///< A pointer to the byte that is past the end of the data.
+ lldb::ByteOrder m_byte_order; ///< The byte order of the data we are extracting from.
+ uint8_t m_addr_size; ///< The address size to use when extracting pointers or addresses
+ mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can be shared among multilple instances
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (DataEncoder);
+
+};
+
+} // namespace lldb_private
+
+#endif // #if defined (__cplusplus)
+#endif // #ifndef liblldb_DataEncoder_h_
diff --git a/include/lldb/Core/DataExtractor.h b/include/lldb/Core/DataExtractor.h
new file mode 100644
index 000000000000..a8593043cb15
--- /dev/null
+++ b/include/lldb/Core/DataExtractor.h
@@ -0,0 +1,1298 @@
+//===-- DataExtractor.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DataExtractor_h_
+#define liblldb_DataExtractor_h_
+#if defined (__cplusplus)
+
+
+#include "lldb/lldb-private.h"
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class DataExtractor DataExtractor.h "lldb/Core/DataExtractor.h"
+/// @brief An data extractor class.
+///
+/// DataExtractor is a class that can extract data (swapping if needed)
+/// from a data buffer. The data buffer can be caller owned, or can be
+/// shared data that can be shared between multiple DataExtractor
+/// instances. Multiple DataExtractor objects can share the same data,
+/// yet extract values in different address sizes and byte order modes.
+/// Each object can have a unique position in the shared data and extract
+/// data from different offsets.
+///
+/// @see DataBuffer
+//----------------------------------------------------------------------
+class DataExtractor
+{
+public:
+ //------------------------------------------------------------------
+ /// @typedef DataExtractor::Type
+ /// @brief Type enumerations used in the dump routines.
+ /// @see DataExtractor::Dump()
+ /// @see DataExtractor::DumpRawHexBytes()
+ //------------------------------------------------------------------
+ typedef enum
+ {
+ TypeUInt8, ///< Format output as unsigned 8 bit integers
+ TypeChar, ///< Format output as characters
+ TypeUInt16, ///< Format output as unsigned 16 bit integers
+ TypeUInt32, ///< Format output as unsigned 32 bit integers
+ TypeUInt64, ///< Format output as unsigned 64 bit integers
+ TypePointer, ///< Format output as pointers
+ TypeULEB128, ///< Format output as ULEB128 numbers
+ TypeSLEB128 ///< Format output as SLEB128 numbers
+ } Type;
+
+ static void
+ DumpHexBytes (Stream *s,
+ const void *src,
+ size_t src_len,
+ uint32_t bytes_per_line,
+ lldb::addr_t base_addr); // Pass LLDB_INVALID_ADDRESS to not show address at start of line
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize all members to a default empty state.
+ //------------------------------------------------------------------
+ DataExtractor ();
+
+ //------------------------------------------------------------------
+ /// Construct with a buffer that is owned by the caller.
+ ///
+ /// This constructor allows us to use data that is owned by the
+ /// caller. The data must stay around as long as this object is
+ /// valid.
+ ///
+ /// @param[in] data
+ /// A pointer to caller owned data.
+ ///
+ /// @param[in] data_length
+ /// The length in bytes of \a data.
+ ///
+ /// @param[in] byte_order
+ /// A byte order of the data that we are extracting from.
+ ///
+ /// @param[in] addr_size
+ /// A new address byte size value.
+ //------------------------------------------------------------------
+ DataExtractor (const void* data, lldb::offset_t data_length, lldb::ByteOrder byte_order, uint32_t addr_size);
+
+ //------------------------------------------------------------------
+ /// Construct with shared data.
+ ///
+ /// Copies the data shared pointer which adds a reference to the
+ /// contained in \a data_sp. The shared data reference is reference
+ /// counted to ensure the data lives as long as anyone still has a
+ /// valid shared pointer to the data in \a data_sp.
+ ///
+ /// @param[in] data_sp
+ /// A shared pointer to data.
+ ///
+ /// @param[in] byte_order
+ /// A byte order of the data that we are extracting from.
+ ///
+ /// @param[in] addr_size
+ /// A new address byte size value.
+ //------------------------------------------------------------------
+ DataExtractor (const lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint32_t addr_size);
+
+ //------------------------------------------------------------------
+ /// Construct with a subset of \a data.
+ ///
+ /// Initialize this object with a subset of the data bytes in \a
+ /// data. If \a data contains shared data, then a reference to the
+ /// shared data will be added to ensure the shared data stays around
+ /// as long as any objects have references to the shared data. The
+ /// byte order value and the address size settings are copied from \a
+ /// data. If \a offset is not a valid offset in \a data, then no
+ /// reference to the shared data will be added. If there are not
+ /// \a length bytes available in \a data starting at \a offset,
+ /// the length will be truncated to contain as many bytes as
+ /// possible.
+ ///
+ /// @param[in] data
+ /// Another DataExtractor object that contains data.
+ ///
+ /// @param[in] offset
+ /// The offset into \a data at which the subset starts.
+ ///
+ /// @param[in] length
+ /// The length in bytes of the subset of data.
+ //------------------------------------------------------------------
+ DataExtractor (const DataExtractor& data, lldb::offset_t offset, lldb::offset_t length);
+
+ DataExtractor (const DataExtractor& rhs);
+ //------------------------------------------------------------------
+ /// Assignment operator.
+ ///
+ /// Copies all data, byte order and address size settings from \a rhs into
+ /// this object. If \a rhs contains shared data, a reference to that
+ /// shared data will be added.
+ ///
+ /// @param[in] rhs
+ /// Another DataExtractor object to copy.
+ ///
+ /// @return
+ /// A const reference to this object.
+ //------------------------------------------------------------------
+ const DataExtractor&
+ operator= (const DataExtractor& rhs);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ ///
+ /// If this object contains a valid shared data reference, the
+ /// reference count on the data will be decremented, and if zero,
+ /// the data will be freed.
+ //------------------------------------------------------------------
+ ~DataExtractor ();
+
+ //------------------------------------------------------------------
+ /// Clears the object state.
+ ///
+ /// Clears the object contents back to a default invalid state, and
+ /// release any references to shared data that this object may
+ /// contain.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Dumps the binary data as \a type objects to stream \a s (or to
+ /// Log() if \a s is NULL) starting \a offset bytes into the data
+ /// and stopping after dumping \a length bytes. The offset into the
+ /// data is displayed at the beginning of each line and can be
+ /// offset by base address \a base_addr. \a num_per_line objects
+ /// will be displayed on each line.
+ ///
+ /// @param[in] s
+ /// The stream to dump the output to. If NULL the output will
+ /// be dumped to Log().
+ ///
+ /// @param[in] offset
+ /// The offset into the data at which to start dumping.
+ ///
+ /// @param[in] length
+ /// The number of bytes to dump.
+ ///
+ /// @param[in] base_addr
+ /// The base address that gets added to the offset displayed on
+ /// each line.
+ ///
+ /// @param[in] num_per_line
+ /// The number of \a type objects to display on each line.
+ ///
+ /// @param[in] type
+ /// The type of objects to use when dumping data from this
+ /// object. See DataExtractor::Type.
+ ///
+ /// @param[in] type_format
+ /// The optional format to use for the \a type objects. If this
+ /// is NULL, the default format for the \a type will be used.
+ ///
+ /// @return
+ /// The offset at which dumping ended.
+ //------------------------------------------------------------------
+ lldb::offset_t
+ PutToLog (Log *log,
+ lldb::offset_t offset,
+ lldb::offset_t length,
+ uint64_t base_addr,
+ uint32_t num_per_line,
+ Type type,
+ const char *type_format = NULL) const;
+
+ //------------------------------------------------------------------
+ /// Dumps \a item_count objects into the stream \a s.
+ ///
+ /// Dumps \a item_count objects using \a item_format, each of which
+ /// are \a item_byte_size bytes long starting at offset \a offset
+ /// bytes into the contained data, into the stream \a s. \a
+ /// num_per_line objects will be dumped on each line before a new
+ /// line will be output. If \a base_addr is a valid address, then
+ /// each new line of output will be prededed by the address value
+ /// plus appropriate offset, and a colon and space. Bitfield values
+ /// can be dumped by calling this function multiple times with the
+ /// same start offset, format and size, yet differing \a
+ /// item_bit_size and \a item_bit_offset values.
+ ///
+ /// @param[in] s
+ /// The stream to dump the output to. This value can not be NULL.
+ ///
+ /// @param[in] offset
+ /// The offset into the data at which to start dumping.
+ ///
+ /// @param[in] item_format
+ /// The format to use when dumping each item.
+ ///
+ /// @param[in] item_byte_size
+ /// The byte size of each item.
+ ///
+ /// @param[in] item_count
+ /// The number of items to dump.
+ ///
+ /// @param[in] num_per_line
+ /// The number of items to display on each line.
+ ///
+ /// @param[in] base_addr
+ /// The base address that gets added to the offset displayed on
+ /// each line if the value is valid. Is \a base_addr is
+ /// LLDB_INVALID_ADDRESS then no address values will be prepended
+ /// to any lines.
+ ///
+ /// @param[in] item_bit_size
+ /// If the value to display is a bitfield, this value should
+ /// be the number of bits that the bitfield item has within the
+ /// item's byte size value. This function will need to be called
+ /// multiple times with identical \a offset and \a item_byte_size
+ /// values in order to display multiple bitfield values that
+ /// exist within the same integer value. If the items being
+ /// displayed are not bitfields, this value should be zero.
+ ///
+ /// @param[in] item_bit_offset
+ /// If the value to display is a bitfield, this value should
+ /// be the offset in bits, or shift right amount, that the
+ /// bitfield item occupies within the item's byte size value.
+ /// This function will need to be called multiple times with
+ /// identical \a offset and \a item_byte_size values in order
+ /// to display multiple bitfield values that exist within the
+ /// same integer value. If the items being displayed are not
+ /// bitfields, this value should be zero.
+ ///
+ /// @return
+ /// The offset at which dumping ended.
+ //------------------------------------------------------------------
+ lldb::offset_t
+ Dump (Stream *s,
+ lldb::offset_t offset,
+ lldb::Format item_format,
+ size_t item_byte_size,
+ size_t item_count,
+ size_t num_per_line,
+ uint64_t base_addr,
+ uint32_t item_bit_size,
+ uint32_t item_bit_offset,
+ ExecutionContextScope *exe_scope = NULL) const;
+
+ //------------------------------------------------------------------
+ /// Dump a UUID value at \a offset.
+ ///
+ /// Dump a UUID starting at \a offset bytes into this object's data.
+ /// If the stream \a s is NULL, the output will be sent to Log().
+ ///
+ /// @param[in] s
+ /// The stream to dump the output to. If NULL the output will
+ /// be dumped to Log().
+ ///
+ /// @param[in] offset
+ /// The offset into the data at which to extract and dump a
+ /// UUID value.
+ //------------------------------------------------------------------
+ void
+ DumpUUID (Stream *s, lldb::offset_t offset) const;
+
+ //------------------------------------------------------------------
+ /// Extract an arbitrary number of bytes in the specified byte
+ /// order.
+ ///
+ /// Attemps to extract \a length bytes starting at \a offset bytes
+ /// into this data in the requested byte order (\a dst_byte_order)
+ /// and place the results in \a dst. \a dst must be at least \a
+ /// length bytes long.
+ ///
+ /// @param[in] offset
+ /// The offset in bytes into the contained data at which to
+ /// start extracting.
+ ///
+ /// @param[in] length
+ /// The number of bytes to extract.
+ ///
+ /// @param[in] dst_byte_order
+ /// A byte order of the data that we want when the value in
+ /// copied to \a dst.
+ ///
+ /// @param[out] dst
+ /// The buffer that will receive the extracted value if there
+ /// are enough bytes available in the current data.
+ ///
+ /// @return
+ /// The number of bytes that were extracted which will be \a
+ /// length when the value is successfully extracted, or zero
+ /// if there aren't enough bytes at the specified offset.
+ //------------------------------------------------------------------
+ size_t
+ ExtractBytes (lldb::offset_t offset, lldb::offset_t length, lldb::ByteOrder dst_byte_order, void *dst) const;
+
+ //------------------------------------------------------------------
+ /// Extract an address from \a *offset_ptr.
+ ///
+ /// Extract a single address from the data and update the offset
+ /// pointed to by \a offset_ptr. The size of the extracted address
+ /// comes from the \a m_addr_size member variable and should be
+ /// set correctly prior to extracting any address values.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted address value.
+ //------------------------------------------------------------------
+ uint64_t
+ GetAddress (lldb::offset_t *offset_ptr) const;
+
+ uint64_t
+ GetAddress_unchecked (lldb::offset_t *offset_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Get the current address size.
+ ///
+ /// Return the size in bytes of any address values this object will
+ /// extract.
+ ///
+ /// @return
+ /// The size in bytes of address values that will be extracted.
+ //------------------------------------------------------------------
+ uint32_t
+ GetAddressByteSize () const
+ {
+ return m_addr_size;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the number of bytes contained in this object.
+ ///
+ /// @return
+ /// The total number of bytes of data this object refers to.
+ //------------------------------------------------------------------
+ uint64_t
+ GetByteSize () const
+ {
+ return m_end - m_start;
+ }
+
+ //------------------------------------------------------------------
+ /// Extract a C string from \a *offset_ptr.
+ ///
+ /// Returns a pointer to a C String from the data at the offset
+ /// pointed to by \a offset_ptr. A variable length NULL terminated C
+ /// string will be extracted and the \a offset_ptr will be
+ /// updated with the offset of the byte that follows the NULL
+ /// terminator byte.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// A pointer to the C string value in the data. If the offset
+ /// pointed to by \a offset_ptr is out of bounds, or if the
+ /// offset plus the length of the C string is out of bounds,
+ /// NULL will be returned.
+ //------------------------------------------------------------------
+ const char *
+ GetCStr (lldb::offset_t *offset_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Extract a C string from \a *offset_ptr with field size \a len.
+ ///
+ /// Returns a pointer to a C String from the data at the offset
+ /// pointed to by \a offset_ptr, with a field length of \a len.
+ /// A NULL terminated C string will be extracted and the \a offset_ptr
+ /// will be updated with the offset of the byte that follows the fixed
+ /// length field.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// A pointer to the C string value in the data. If the offset
+ /// pointed to by \a offset_ptr is out of bounds, or if the
+ /// offset plus the length of the field is out of bounds, or if
+ /// the field does not contain a NULL terminator byte, NULL will
+ /// be returned.
+ const char *
+ GetCStr (lldb::offset_t *offset_ptr, lldb::offset_t len) const;
+
+ //------------------------------------------------------------------
+ /// Extract \a length bytes from \a *offset_ptr.
+ ///
+ /// Returns a pointer to a bytes in this object's data at the offset
+ /// pointed to by \a offset_ptr. If \a length is zero or too large,
+ /// then the offset pointed to by \a offset_ptr will not be updated
+ /// and NULL will be returned.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[in] length
+ /// The optional length of a string to extract. If the value is
+ /// zero, a NULL terminated C string will be extracted.
+ ///
+ /// @return
+ /// A pointer to the bytes in this object's data if the offset
+ /// and length are valid, or NULL otherwise.
+ //------------------------------------------------------------------
+ const void*
+ GetData (lldb::offset_t *offset_ptr, lldb::offset_t length) const
+ {
+ const uint8_t *ptr = PeekData (*offset_ptr, length);
+ if (ptr)
+ *offset_ptr += length;
+ return ptr;
+ }
+
+ //------------------------------------------------------------------
+ /// Copy \a dst_len bytes from \a *offset_ptr and ensure the copied
+ /// data is treated as a value that can be swapped to match the
+ /// specified byte order.
+ ///
+ /// For values that are larger than the supported integer sizes,
+ /// this function can be used to extract data in a specified byte
+ /// order. It can also be used to copy a smaller integer value from
+ /// to a larger value. The extra bytes left over will be padded
+ /// correctly according to the byte order of this object and the
+ /// \a dst_byte_order. This can be very handy when say copying a
+ /// partial data value into a register.
+ ///
+ /// @param[in] src_offset
+ /// The offset into this data from which to start copying an
+ /// endian entity
+ ///
+ /// @param[in] src_len
+ /// The length of the endian data to copy from this object
+ /// into the \a dst object
+ ///
+ /// @param[out] dst
+ /// The buffer where to place the endian data. The data might
+ /// need to be byte swapped (and appropriately padded with
+ /// zeroes if \a src_len != \a dst_len) if \a dst_byte_order
+ /// does not match the byte order in this object.
+ ///
+ /// @param[in] dst_len
+ /// The length number of bytes that the endian value will
+ /// occupy is \a dst.
+ ///
+ /// @param[in] byte_order
+ /// The byte order that the endian value should be in the \a dst
+ /// buffer.
+ ///
+ /// @return
+ /// Returns the number of bytes that were copied, or zero if
+ /// anything goes wrong.
+ //------------------------------------------------------------------
+ lldb::offset_t
+ CopyByteOrderedData (lldb::offset_t src_offset,
+ lldb::offset_t src_len,
+ void *dst,
+ lldb::offset_t dst_len,
+ lldb::ByteOrder dst_byte_order) const;
+
+ //------------------------------------------------------------------
+ /// Get the data end pointer.
+ ///
+ /// @return
+ /// Returns a pointer to the next byte contained in this
+ /// object's data, or NULL of there is no data in this object.
+ //------------------------------------------------------------------
+ const uint8_t *
+ GetDataEnd () const
+ {
+ return m_end;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the shared data offset.
+ ///
+ /// Get the offset of the first byte of data in the shared data (if
+ /// any).
+ ///
+ /// @return
+ /// If this object contains shared data, this function returns
+ /// the offset in bytes into that shared data, zero otherwise.
+ //------------------------------------------------------------------
+ size_t
+ GetSharedDataOffset () const;
+
+ //------------------------------------------------------------------
+ /// Get a the data start pointer.
+ ///
+ /// @return
+ /// Returns a pointer to the first byte contained in this
+ /// object's data, or NULL of there is no data in this object.
+ //------------------------------------------------------------------
+ const uint8_t *
+ GetDataStart () const
+ {
+ return m_start;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Extract a float from \a *offset_ptr.
+ ///
+ /// Extract a single float value.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The floating value that was extracted, or zero on failure.
+ //------------------------------------------------------------------
+ float
+ GetFloat (lldb::offset_t *offset_ptr) const;
+
+ double
+ GetDouble (lldb::offset_t *offset_ptr) const;
+
+ long double
+ GetLongDouble (lldb::offset_t *offset_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Extract a GNU encoded pointer value from \a *offset_ptr.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[in] eh_ptr_enc
+ /// The GNU pointer encoding type.
+ ///
+ /// @param[in] pc_rel_addr
+ /// The PC relative address to use when the encoding is
+ /// \c DW_GNU_EH_PE_pcrel.
+ ///
+ /// @param[in] text_addr
+ /// The text (code) relative address to use when the encoding is
+ /// \c DW_GNU_EH_PE_textrel.
+ ///
+ /// @param[in] data_addr
+ /// The data relative address to use when the encoding is
+ /// \c DW_GNU_EH_PE_datarel.
+ ///
+ /// @return
+ /// The extracted GNU encoded pointer value.
+ //------------------------------------------------------------------
+ uint64_t
+ GetGNUEHPointer (lldb::offset_t *offset_ptr,
+ uint32_t eh_ptr_enc,
+ lldb::addr_t pc_rel_addr,
+ lldb::addr_t text_addr,
+ lldb::addr_t data_addr);
+
+ //------------------------------------------------------------------
+ /// Extract an integer of size \a byte_size from \a *offset_ptr.
+ ///
+ /// Extract a single integer value and update the offset pointed to
+ /// by \a offset_ptr. The size of the extracted integer is specified
+ /// by the \a byte_size argument. \a byte_size should have a value
+ /// >= 1 and <= 4 since the return value is only 32 bits wide. Any
+ /// \a byte_size values less than 1 or greater than 4 will result in
+ /// nothing being extracted, and zero being returned.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[in] byte_size
+ /// The size in byte of the integer to extract.
+ ///
+ /// @return
+ /// The integer value that was extracted, or zero on failure.
+ //------------------------------------------------------------------
+ uint32_t
+ GetMaxU32 (lldb::offset_t *offset_ptr, size_t byte_size) const;
+
+ //------------------------------------------------------------------
+ /// Extract an unsigned integer of size \a byte_size from \a
+ /// *offset_ptr.
+ ///
+ /// Extract a single unsigned integer value and update the offset
+ /// pointed to by \a offset_ptr. The size of the extracted integer
+ /// is specified by the \a byte_size argument. \a byte_size should
+ /// have a value greater than or equal to one and less than or equal
+ /// to eight since the return value is 64 bits wide. Any
+ /// \a byte_size values less than 1 or greater than 8 will result in
+ /// nothing being extracted, and zero being returned.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[in] byte_size
+ /// The size in byte of the integer to extract.
+ ///
+ /// @return
+ /// The unsigned integer value that was extracted, or zero on
+ /// failure.
+ //------------------------------------------------------------------
+ uint64_t
+ GetMaxU64 (lldb::offset_t *offset_ptr, size_t byte_size) const;
+
+ uint64_t
+ GetMaxU64_unchecked (lldb::offset_t *offset_ptr, size_t byte_size) const;
+
+ //------------------------------------------------------------------
+ /// Extract an signed integer of size \a byte_size from \a *offset_ptr.
+ ///
+ /// Extract a single signed integer value (sign extending if required)
+ /// and update the offset pointed to by \a offset_ptr. The size of
+ /// the extracted integer is specified by the \a byte_size argument.
+ /// \a byte_size should have a value greater than or equal to one
+ /// and less than or equal to eight since the return value is 64
+ /// bits wide. Any \a byte_size values less than 1 or greater than
+ /// 8 will result in nothing being extracted, and zero being returned.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[in] byte_size
+ /// The size in byte of the integer to extract.
+ ///
+ /// @return
+ /// The sign extended signed integer value that was extracted,
+ /// or zero on failure.
+ //------------------------------------------------------------------
+ int64_t
+ GetMaxS64 (lldb::offset_t *offset_ptr, size_t size) const;
+
+ //------------------------------------------------------------------
+ /// Extract an unsigned integer of size \a byte_size from \a
+ /// *offset_ptr, then extract the bitfield from this value if
+ /// \a bitfield_bit_size is non-zero.
+ ///
+ /// Extract a single unsigned integer value and update the offset
+ /// pointed to by \a offset_ptr. The size of the extracted integer
+ /// is specified by the \a byte_size argument. \a byte_size should
+ /// have a value greater than or equal to one and less than or equal
+ /// to 8 since the return value is 64 bits wide. Any
+ /// \a byte_size values less than 1 or greater than 8 will result in
+ /// nothing being extracted, and zero being returned.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[in] byte_size
+ /// The size in byte of the integer to extract.
+ ///
+ /// @param[in] bitfield_bit_size
+ /// The size in bits of the bitfield value to extract, or zero
+ /// to just extract the entire integer value.
+ ///
+ /// @param[in] bitfield_bit_offset
+ /// The bit offset of the bitfield value in the extracted
+ /// integer (the number of bits to shift the integer to the
+ /// right).
+ ///
+ /// @return
+ /// The unsigned bitfield integer value that was extracted, or
+ /// zero on failure.
+ //------------------------------------------------------------------
+ uint64_t
+ GetMaxU64Bitfield (lldb::offset_t *offset_ptr,
+ size_t size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset) const;
+
+ //------------------------------------------------------------------
+ /// Extract an signed integer of size \a byte_size from \a
+ /// *offset_ptr, then extract and signe extend the bitfield from
+ /// this value if \a bitfield_bit_size is non-zero.
+ ///
+ /// Extract a single signed integer value (sign extending if required)
+ /// and update the offset pointed to by \a offset_ptr. The size of
+ /// the extracted integer is specified by the \a byte_size argument.
+ /// \a byte_size should have a value greater than or equal to one
+ /// and less than or equal to eight since the return value is 64
+ /// bits wide. Any \a byte_size values less than 1 or greater than
+ /// 8 will result in nothing being extracted, and zero being returned.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[in] byte_size
+ /// The size in bytes of the integer to extract.
+ ///
+ /// @param[in] bitfield_bit_size
+ /// The size in bits of the bitfield value to extract, or zero
+ /// to just extract the entire integer value.
+ ///
+ /// @param[in] bitfield_bit_offset
+ /// The bit offset of the bitfield value in the extracted
+ /// integer (the number of bits to shift the integer to the
+ /// right).
+ ///
+ /// @return
+ /// The signed bitfield integer value that was extracted, or
+ /// zero on failure.
+ //------------------------------------------------------------------
+ int64_t
+ GetMaxS64Bitfield (lldb::offset_t *offset_ptr,
+ size_t size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset) const;
+
+ //------------------------------------------------------------------
+ /// Extract an pointer from \a *offset_ptr.
+ ///
+ /// Extract a single pointer from the data and update the offset
+ /// pointed to by \a offset_ptr. The size of the extracted pointer
+ /// comes from the \a m_addr_size member variable and should be
+ /// set correctly prior to extracting any pointer values.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted pointer value as a 64 integer.
+ //------------------------------------------------------------------
+ uint64_t
+ GetPointer (lldb::offset_t *offset_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Get the current byte order value.
+ ///
+ /// @return
+ /// The current byte order value from this object's internal
+ /// state.
+ //------------------------------------------------------------------
+ lldb::ByteOrder
+ GetByteOrder() const
+ {
+ return m_byte_order;
+ }
+
+ //------------------------------------------------------------------
+ /// Extract a uint8_t value from \a *offset_ptr.
+ ///
+ /// Extract a single uint8_t from the binary data at the offset
+ /// pointed to by \a offset_ptr, and advance the offset on success.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted uint8_t value.
+ //------------------------------------------------------------------
+ uint8_t
+ GetU8 ( lldb::offset_t *offset_ptr) const;
+
+ uint8_t
+ GetU8_unchecked (lldb::offset_t *offset_ptr) const
+ {
+ uint8_t val = m_start[*offset_ptr];
+ *offset_ptr += 1;
+ return val;
+ }
+
+ uint16_t
+ GetU16_unchecked (lldb::offset_t *offset_ptr) const;
+
+ uint32_t
+ GetU32_unchecked (lldb::offset_t *offset_ptr) const;
+
+ uint64_t
+ GetU64_unchecked (lldb::offset_t *offset_ptr) const;
+ //------------------------------------------------------------------
+ /// Extract \a count uint8_t values from \a *offset_ptr.
+ ///
+ /// Extract \a count uint8_t values from the binary data at the
+ /// offset pointed to by \a offset_ptr, and advance the offset on
+ /// success. The extracted values are copied into \a dst.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[out] dst
+ /// A buffer to copy \a count uint8_t values into. \a dst must
+ /// be large enough to hold all requested data.
+ ///
+ /// @param[in] count
+ /// The number of uint8_t values to extract.
+ ///
+ /// @return
+ /// \a dst if all values were properly extracted and copied,
+ /// NULL otherise.
+ //------------------------------------------------------------------
+ void *
+ GetU8 (lldb::offset_t *offset_ptr, void *dst, uint32_t count) const;
+
+ //------------------------------------------------------------------
+ /// Extract a uint16_t value from \a *offset_ptr.
+ ///
+ /// Extract a single uint16_t from the binary data at the offset
+ /// pointed to by \a offset_ptr, and update the offset on success.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted uint16_t value.
+ //------------------------------------------------------------------
+ uint16_t
+ GetU16 (lldb::offset_t *offset_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Extract \a count uint16_t values from \a *offset_ptr.
+ ///
+ /// Extract \a count uint16_t values from the binary data at the
+ /// offset pointed to by \a offset_ptr, and advance the offset on
+ /// success. The extracted values are copied into \a dst.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[out] dst
+ /// A buffer to copy \a count uint16_t values into. \a dst must
+ /// be large enough to hold all requested data.
+ ///
+ /// @param[in] count
+ /// The number of uint16_t values to extract.
+ ///
+ /// @return
+ /// \a dst if all values were properly extracted and copied,
+ /// NULL otherise.
+ //------------------------------------------------------------------
+ void *
+ GetU16 (lldb::offset_t *offset_ptr, void *dst, uint32_t count) const;
+
+ //------------------------------------------------------------------
+ /// Extract a uint32_t value from \a *offset_ptr.
+ ///
+ /// Extract a single uint32_t from the binary data at the offset
+ /// pointed to by \a offset_ptr, and update the offset on success.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted uint32_t value.
+ //------------------------------------------------------------------
+ uint32_t
+ GetU32 (lldb::offset_t *offset_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Extract \a count uint32_t values from \a *offset_ptr.
+ ///
+ /// Extract \a count uint32_t values from the binary data at the
+ /// offset pointed to by \a offset_ptr, and advance the offset on
+ /// success. The extracted values are copied into \a dst.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[out] dst
+ /// A buffer to copy \a count uint32_t values into. \a dst must
+ /// be large enough to hold all requested data.
+ ///
+ /// @param[in] count
+ /// The number of uint32_t values to extract.
+ ///
+ /// @return
+ /// \a dst if all values were properly extracted and copied,
+ /// NULL otherise.
+ //------------------------------------------------------------------
+ void *
+ GetU32 (lldb::offset_t *offset_ptr, void *dst, uint32_t count) const;
+
+ //------------------------------------------------------------------
+ /// Extract a uint64_t value from \a *offset_ptr.
+ ///
+ /// Extract a single uint64_t from the binary data at the offset
+ /// pointed to by \a offset_ptr, and update the offset on success.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted uint64_t value.
+ //------------------------------------------------------------------
+ uint64_t
+ GetU64 (lldb::offset_t *offset_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Extract \a count uint64_t values from \a *offset_ptr.
+ ///
+ /// Extract \a count uint64_t values from the binary data at the
+ /// offset pointed to by \a offset_ptr, and advance the offset on
+ /// success. The extracted values are copied into \a dst.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[out] dst
+ /// A buffer to copy \a count uint64_t values into. \a dst must
+ /// be large enough to hold all requested data.
+ ///
+ /// @param[in] count
+ /// The number of uint64_t values to extract.
+ ///
+ /// @return
+ /// \a dst if all values were properly extracted and copied,
+ /// NULL otherise.
+ //------------------------------------------------------------------
+ void *
+ GetU64 ( lldb::offset_t *offset_ptr, void *dst, uint32_t count) const;
+
+ //------------------------------------------------------------------
+ /// Extract a signed LEB128 value from \a *offset_ptr.
+ ///
+ /// Extracts an signed LEB128 number from this object's data
+ /// starting at the offset pointed to by \a offset_ptr. The offset
+ /// pointed to by \a offset_ptr will be updated with the offset of
+ /// the byte following the last extracted byte.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted signed integer value.
+ //------------------------------------------------------------------
+ int64_t
+ GetSLEB128 (lldb::offset_t *offset_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Extract a unsigned LEB128 value from \a *offset_ptr.
+ ///
+ /// Extracts an unsigned LEB128 number from this object's data
+ /// starting at the offset pointed to by \a offset_ptr. The offset
+ /// pointed to by \a offset_ptr will be updated with the offset of
+ /// the byte following the last extracted byte.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted unsigned integer value.
+ //------------------------------------------------------------------
+ uint64_t
+ GetULEB128 (lldb::offset_t *offset_ptr) const;
+
+ lldb::DataBufferSP &
+ GetSharedDataBuffer ()
+ {
+ return m_data_sp;
+ }
+
+ //------------------------------------------------------------------
+ /// Peek at a C string at \a offset.
+ ///
+ /// Peeks at a string in the contained data. No verification is done
+ /// to make sure the entire string lies within the bounds of this
+ /// object's data, only \a offset is verified to be a valid offset.
+ ///
+ /// @param[in] offset
+ /// An offset into the data.
+ ///
+ /// @return
+ /// A non-NULL C string pointer if \a offset is a valid offset,
+ /// NULL otherwise.
+ //------------------------------------------------------------------
+ const char *
+ PeekCStr (lldb::offset_t offset) const;
+
+ //------------------------------------------------------------------
+ /// Peek at a bytes at \a offset.
+ ///
+ /// Returns a pointer to \a length bytes at \a offset as long as
+ /// there are \a length bytes available starting at \a offset.
+ ///
+ /// @return
+ /// A non-NULL data pointer if \a offset is a valid offset and
+ /// there are \a length bytes available at that offset, NULL
+ /// otherwise.
+ //------------------------------------------------------------------
+ const uint8_t*
+ PeekData (lldb::offset_t offset, lldb::offset_t length) const
+ {
+ if (length > 0 && ValidOffsetForDataOfSize(offset, length))
+ return m_start + offset;
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Set the address byte size.
+ ///
+ /// Set the size in bytes that will be used when extracting any
+ /// address and pointer values from data contained in this object.
+ ///
+ /// @param[in] addr_size
+ /// The size in bytes to use when extracting addresses.
+ //------------------------------------------------------------------
+ void
+ SetAddressByteSize (uint32_t addr_size)
+ {
+ m_addr_size = addr_size;
+ }
+
+ //------------------------------------------------------------------
+ /// Set data with a buffer that is caller owned.
+ ///
+ /// Use data that is owned by the caller when extracting values.
+ /// The data must stay around as long as this object, or any object
+ /// that copies a subset of this object's data, is valid. If \a
+ /// bytes is NULL, or \a length is zero, this object will contain
+ /// no data.
+ ///
+ /// @param[in] bytes
+ /// A pointer to caller owned data.
+ ///
+ /// @param[in] length
+ /// The length in bytes of \a bytes.
+ ///
+ /// @param[in] byte_order
+ /// A byte order of the data that we are extracting from.
+ ///
+ /// @return
+ /// The number of bytes that this object now contains.
+ //------------------------------------------------------------------
+ lldb::offset_t
+ SetData (const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order);
+
+ //------------------------------------------------------------------
+ /// Adopt a subset of \a data.
+ ///
+ /// Set this object's data to be a subset of the data bytes in \a
+ /// data. If \a data contains shared data, then a reference to the
+ /// shared data will be added to ensure the shared data stays around
+ /// as long as any objects have references to the shared data. The
+ /// byte order and the address size settings are copied from \a
+ /// data. If \a offset is not a valid offset in \a data, then no
+ /// reference to the shared data will be added. If there are not
+ /// \a length bytes available in \a data starting at \a offset,
+ /// the length will be truncated to contains as many bytes as
+ /// possible.
+ ///
+ /// @param[in] data
+ /// Another DataExtractor object that contains data.
+ ///
+ /// @param[in] offset
+ /// The offset into \a data at which the subset starts.
+ ///
+ /// @param[in] length
+ /// The length in bytes of the subset of \a data.
+ ///
+ /// @return
+ /// The number of bytes that this object now contains.
+ //------------------------------------------------------------------
+ lldb::offset_t
+ SetData (const DataExtractor& data, lldb::offset_t offset, lldb::offset_t length);
+
+ //------------------------------------------------------------------
+ /// Adopt a subset of shared data in \a data_sp.
+ ///
+ /// Copies the data shared pointer which adds a reference to the
+ /// contained in \a data_sp. The shared data reference is reference
+ /// counted to ensure the data lives as long as anyone still has a
+ /// valid shared pointer to the data in \a data_sp. The byte order
+ /// and address byte size settings remain the same. If
+ /// \a offset is not a valid offset in \a data_sp, then no reference
+ /// to the shared data will be added. If there are not \a length
+ /// bytes available in \a data starting at \a offset, the length
+ /// will be truncated to contains as many bytes as possible.
+ ///
+ /// @param[in] data_sp
+ /// A shared pointer to data.
+ ///
+ /// @param[in] offset
+ /// The offset into \a data_sp at which the subset starts.
+ ///
+ /// @param[in] length
+ /// The length in bytes of the subset of \a data_sp.
+ ///
+ /// @return
+ /// The number of bytes that this object now contains.
+ //------------------------------------------------------------------
+ lldb::offset_t
+ SetData (const lldb::DataBufferSP& data_sp, lldb::offset_t offset = 0, lldb::offset_t length = LLDB_INVALID_OFFSET);
+
+ //------------------------------------------------------------------
+ /// Set the byte_order value.
+ ///
+ /// Sets the byte order of the data to extract. Extracted values
+ /// will be swapped if necessary when decoding.
+ ///
+ /// @param[in] byte_order
+ /// The byte order value to use when extracting data.
+ //------------------------------------------------------------------
+ void
+ SetByteOrder (lldb::ByteOrder byte_order)
+ {
+ m_byte_order = byte_order;
+ }
+
+ //------------------------------------------------------------------
+ /// Skip an LEB128 number at \a *offset_ptr.
+ ///
+ /// Skips a LEB128 number (signed or unsigned) from this object's
+ /// data starting at the offset pointed to by \a offset_ptr. The
+ /// offset pointed to by \a offset_ptr will be updated with the
+ /// offset of the byte following the last extracted byte.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ // The number of bytes consumed during the extraction.
+ //------------------------------------------------------------------
+ uint32_t
+ Skip_LEB128 (lldb::offset_t *offset_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Test the validity of \a offset.
+ ///
+ /// @return
+ /// \b true if \a offset is a valid offset into the data in this
+ /// object, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ValidOffset (lldb::offset_t offset) const
+ {
+ return offset < GetByteSize();
+ }
+
+ //------------------------------------------------------------------
+ /// Test the availability of \a length bytes of data from \a offset.
+ ///
+ /// @return
+ /// \b true if \a offset is a valid offset and there are \a
+ /// length bytes available at that offset, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ValidOffsetForDataOfSize (lldb::offset_t offset, lldb::offset_t length) const
+ {
+ return length <= BytesLeft (offset);
+ }
+
+ size_t
+ Copy (DataExtractor& dest_data) const;
+
+ bool
+ Append (DataExtractor& rhs);
+
+ bool
+ Append (void* bytes, lldb::offset_t length);
+
+ lldb::offset_t
+ BytesLeft (lldb::offset_t offset) const
+ {
+ const lldb::offset_t size = GetByteSize();
+ if (size > offset)
+ return size - offset;
+ return 0;
+ }
+
+protected:
+
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ const uint8_t * m_start; ///< A pointer to the first byte of data.
+ const uint8_t * m_end; ///< A pointer to the byte that is past the end of the data.
+ lldb::ByteOrder m_byte_order; ///< The byte order of the data we are extracting from.
+ uint32_t m_addr_size; ///< The address size to use when extracting pointers or addresses
+ mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can be shared among multilple instances
+};
+
+} // namespace lldb_private
+
+#endif // #if defined (__cplusplus)
+#endif // #ifndef liblldb_DataExtractor_h_
diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h
new file mode 100644
index 000000000000..bed93fe02528
--- /dev/null
+++ b/include/lldb/Core/Debugger.h
@@ -0,0 +1,397 @@
+//===-- Debugger.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Debugger_h_
+#define liblldb_Debugger_h_
+#if defined(__cplusplus)
+
+
+#include <stdint.h>
+#include <unistd.h>
+
+#include <stack>
+
+#include "lldb/lldb-public.h"
+
+#include "lldb/API/SBDefines.h"
+
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Communication.h"
+#include "lldb/Core/InputReaderStack.h"
+#include "lldb/Core/Listener.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/SourceManager.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Host/Terminal.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Platform.h"
+#include "lldb/Target/TargetList.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Debugger Debugger.h "lldb/Core/Debugger.h"
+/// @brief A class to manage flag bits.
+///
+/// Provides a global root objects for the debugger core.
+//----------------------------------------------------------------------
+
+
+class Debugger :
+ public std::enable_shared_from_this<Debugger>,
+ public UserID,
+ public Properties,
+ public BroadcasterManager
+{
+friend class SourceManager; // For GetSourceFileCache.
+
+public:
+
+ static lldb::DebuggerSP
+ CreateInstance (lldb::LogOutputCallback log_callback = NULL, void *baton = NULL);
+
+ static lldb::TargetSP
+ FindTargetWithProcessID (lldb::pid_t pid);
+
+ static lldb::TargetSP
+ FindTargetWithProcess (Process *process);
+
+ static void
+ Initialize ();
+
+ static void
+ Terminate ();
+
+ static void
+ SettingsInitialize ();
+
+ static void
+ SettingsTerminate ();
+
+ static void
+ Destroy (lldb::DebuggerSP &debugger_sp);
+
+ virtual
+ ~Debugger ();
+
+ void Clear();
+
+ bool
+ GetAsyncExecution ();
+
+ void
+ SetAsyncExecution (bool async);
+
+ File &
+ GetInputFile ()
+ {
+ return m_input_file.GetFile();
+ }
+
+ File &
+ GetOutputFile ()
+ {
+ return m_output_file.GetFile();
+ }
+
+ File &
+ GetErrorFile ()
+ {
+ return m_error_file.GetFile();
+ }
+
+ void
+ SetInputFileHandle (FILE *fh, bool tranfer_ownership);
+
+ void
+ SetOutputFileHandle (FILE *fh, bool tranfer_ownership);
+
+ void
+ SetErrorFileHandle (FILE *fh, bool tranfer_ownership);
+
+ void
+ SaveInputTerminalState();
+
+ void
+ RestoreInputTerminalState();
+
+ Stream&
+ GetOutputStream ()
+ {
+ return m_output_file;
+ }
+
+ Stream&
+ GetErrorStream ()
+ {
+ return m_error_file;
+ }
+
+ lldb::StreamSP
+ GetAsyncOutputStream ();
+
+ lldb::StreamSP
+ GetAsyncErrorStream ();
+
+ CommandInterpreter &
+ GetCommandInterpreter ()
+ {
+ assert (m_command_interpreter_ap.get());
+ return *m_command_interpreter_ap;
+ }
+
+ Listener &
+ GetListener ()
+ {
+ return m_listener;
+ }
+
+ // This returns the Debugger's scratch source manager. It won't be able to look up files in debug
+ // information, but it can look up files by absolute path and display them to you.
+ // To get the target's source manager, call GetSourceManager on the target instead.
+ SourceManager &
+ GetSourceManager ();
+
+public:
+
+ lldb::TargetSP
+ GetSelectedTarget ()
+ {
+ return m_target_list.GetSelectedTarget ();
+ }
+
+ ExecutionContext
+ GetSelectedExecutionContext();
+ //------------------------------------------------------------------
+ /// Get accessor for the target list.
+ ///
+ /// The target list is part of the global debugger object. This
+ /// the single debugger shared instance to control where targets
+ /// get created and to allow for tracking and searching for targets
+ /// based on certain criteria.
+ ///
+ /// @return
+ /// A global shared target list.
+ //------------------------------------------------------------------
+ TargetList &
+ GetTargetList ()
+ {
+ return m_target_list;
+ }
+
+ PlatformList &
+ GetPlatformList ()
+ {
+ return m_platform_list;
+ }
+
+ void
+ DispatchInputInterrupt ();
+
+ void
+ DispatchInputEndOfFile ();
+
+ void
+ DispatchInput (const char *bytes, size_t bytes_len);
+
+ void
+ WriteToDefaultReader (const char *bytes, size_t bytes_len);
+
+ void
+ PushInputReader (const lldb::InputReaderSP& reader_sp);
+
+ bool
+ PopInputReader (const lldb::InputReaderSP& reader_sp);
+
+ void
+ NotifyTopInputReader (lldb::InputReaderAction notification);
+
+ bool
+ InputReaderIsTopReader (const lldb::InputReaderSP& reader_sp);
+
+ static lldb::DebuggerSP
+ FindDebuggerWithID (lldb::user_id_t id);
+
+ static lldb::DebuggerSP
+ FindDebuggerWithInstanceName (const ConstString &instance_name);
+
+ static size_t
+ GetNumDebuggers();
+
+ static lldb::DebuggerSP
+ GetDebuggerAtIndex (size_t index);
+
+ static bool
+ FormatPrompt (const char *format,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr,
+ Stream &s,
+ ValueObject* valobj = NULL);
+
+
+ void
+ CleanUpInputReaders ();
+
+ static int
+ TestDebuggerRefCount ();
+
+ bool
+ GetCloseInputOnEOF () const;
+
+ void
+ SetCloseInputOnEOF (bool b);
+
+ bool
+ EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream);
+
+ void
+ SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton);
+
+
+ //----------------------------------------------------------------------
+ // Properties Functions
+ //----------------------------------------------------------------------
+ enum StopDisassemblyType
+ {
+ eStopDisassemblyTypeNever = 0,
+ eStopDisassemblyTypeNoSource,
+ eStopDisassemblyTypeAlways
+ };
+
+ virtual Error
+ SetPropertyValue (const ExecutionContext *exe_ctx,
+ VarSetOperationType op,
+ const char *property_path,
+ const char *value);
+
+ bool
+ GetAutoConfirm () const;
+
+ const char *
+ GetFrameFormat() const;
+
+ const char *
+ GetThreadFormat() const;
+
+ lldb::ScriptLanguage
+ GetScriptLanguage() const;
+
+ bool
+ SetScriptLanguage (lldb::ScriptLanguage script_lang);
+
+ uint32_t
+ GetTerminalWidth () const;
+
+ bool
+ SetTerminalWidth (uint32_t term_width);
+
+ const char *
+ GetPrompt() const;
+
+ void
+ SetPrompt(const char *p);
+
+ bool
+ GetUseExternalEditor () const;
+
+ bool
+ SetUseExternalEditor (bool use_external_editor_p);
+
+ bool
+ GetUseColor () const;
+
+ bool
+ SetUseColor (bool use_color);
+
+ uint32_t
+ GetStopSourceLineCount (bool before) const;
+
+ StopDisassemblyType
+ GetStopDisassemblyDisplay () const;
+
+ uint32_t
+ GetDisassemblyLineCount () const;
+
+ bool
+ GetNotifyVoid () const;
+
+
+ const ConstString &
+ GetInstanceName()
+ {
+ return m_instance_name;
+ }
+
+ typedef bool (*LLDBCommandPluginInit) (lldb::SBDebugger& debugger);
+
+ bool
+ LoadPlugin (const FileSpec& spec, Error& error);
+
+protected:
+
+ static void
+ DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len);
+
+ lldb::InputReaderSP
+ GetCurrentInputReader ();
+
+ void
+ ActivateInputReader (const lldb::InputReaderSP &reader_sp);
+
+ bool
+ CheckIfTopInputReaderIsDone ();
+
+ SourceManager::SourceFileCache &
+ GetSourceFileCache ()
+ {
+ return m_source_file_cache;
+ }
+ Communication m_input_comm;
+ StreamFile m_input_file;
+ StreamFile m_output_file;
+ StreamFile m_error_file;
+ TerminalState m_terminal_state;
+ TargetList m_target_list;
+ PlatformList m_platform_list;
+ Listener m_listener;
+ std::unique_ptr<SourceManager> m_source_manager_ap; // This is a scratch source manager that we return if we have no targets.
+ SourceManager::SourceFileCache m_source_file_cache; // All the source managers for targets created in this debugger used this shared
+ // source file cache.
+ std::unique_ptr<CommandInterpreter> m_command_interpreter_ap;
+
+ InputReaderStack m_input_reader_stack;
+ std::string m_input_reader_data;
+ typedef std::map<std::string, lldb::StreamWP> LogStreamMap;
+ LogStreamMap m_log_streams;
+ lldb::StreamSP m_log_callback_stream_sp;
+ ConstString m_instance_name;
+ typedef std::vector<lldb::DynamicLibrarySP> LoadedPluginsList;
+ LoadedPluginsList m_loaded_plugins;
+
+ void
+ InstanceInitialize ();
+
+private:
+
+ // Use Debugger::CreateInstance() to get a shared pointer to a new
+ // debugger object
+ Debugger (lldb::LogOutputCallback m_log_callback, void *baton);
+
+ DISALLOW_COPY_AND_ASSIGN (Debugger);
+
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_Debugger_h_
diff --git a/include/lldb/Core/Disassembler.h b/include/lldb/Core/Disassembler.h
new file mode 100644
index 000000000000..d6e90071dc5b
--- /dev/null
+++ b/include/lldb/Core/Disassembler.h
@@ -0,0 +1,422 @@
+//===-- Disassembler.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Disassembler_h_
+#define liblldb_Disassembler_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Core/Opcode.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class Instruction
+{
+public:
+ Instruction (const Address &address,
+ lldb::AddressClass addr_class = lldb::eAddressClassInvalid);
+
+ virtual
+ ~Instruction();
+
+ const Address &
+ GetAddress () const
+ {
+ return m_address;
+ }
+
+ const char *
+ GetMnemonic (const ExecutionContext* exe_ctx)
+ {
+ CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
+ return m_opcode_name.c_str();
+ }
+ const char *
+ GetOperands (const ExecutionContext* exe_ctx)
+ {
+ CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
+ return m_mnemonics.c_str();
+ }
+
+ const char *
+ GetComment (const ExecutionContext* exe_ctx)
+ {
+ CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
+ return m_comment.c_str();
+ }
+
+ virtual void
+ CalculateMnemonicOperandsAndComment (const ExecutionContext* exe_ctx) = 0;
+
+ lldb::AddressClass
+ GetAddressClass ();
+
+ void
+ SetAddress (const Address &addr)
+ {
+ // Invalidate the address class to lazily discover
+ // it if we need to.
+ m_address_class = lldb::eAddressClassInvalid;
+ m_address = addr;
+ }
+
+ virtual void
+ Dump (Stream *s,
+ uint32_t max_opcode_byte_size,
+ bool show_address,
+ bool show_bytes,
+ const ExecutionContext* exe_ctx);
+
+ virtual bool
+ DoesBranch () = 0;
+
+ virtual size_t
+ Decode (const Disassembler &disassembler,
+ const DataExtractor& data,
+ lldb::offset_t data_offset) = 0;
+
+ virtual void
+ SetDescription (const char *) {} // May be overridden in sub-classes that have descriptions.
+
+ lldb::OptionValueSP
+ ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type);
+
+ lldb::OptionValueSP
+ ReadDictionary (FILE *in_file, Stream *out_stream);
+
+ bool
+ DumpEmulation (const ArchSpec &arch);
+
+ virtual bool
+ TestEmulation (Stream *stream, const char *test_file_name);
+
+ bool
+ Emulate (const ArchSpec &arch,
+ uint32_t evaluate_options,
+ void *baton,
+ EmulateInstruction::ReadMemoryCallback read_mem_callback,
+ EmulateInstruction::WriteMemoryCallback write_mem_calback,
+ EmulateInstruction::ReadRegisterCallback read_reg_callback,
+ EmulateInstruction::WriteRegisterCallback write_reg_callback);
+
+ const Opcode &
+ GetOpcode () const
+ {
+ return m_opcode;
+ }
+
+ uint32_t
+ GetData (DataExtractor &data);
+
+protected:
+ Address m_address; // The section offset address of this instruction
+ // We include an address class in the Instruction class to
+ // allow the instruction specify the eAddressClassCodeAlternateISA
+ // (currently used for thumb), and also to specify data (eAddressClassData).
+ // The usual value will be eAddressClassCode, but often when
+ // disassembling memory, you might run into data. This can
+ // help us to disassemble appropriately.
+private:
+ lldb::AddressClass m_address_class; // Use GetAddressClass () accessor function!
+protected:
+ Opcode m_opcode; // The opcode for this instruction
+ std::string m_opcode_name;
+ std::string m_mnemonics;
+ std::string m_comment;
+ bool m_calculated_strings;
+
+ void
+ CalculateMnemonicOperandsAndCommentIfNeeded (const ExecutionContext* exe_ctx)
+ {
+ if (!m_calculated_strings)
+ {
+ m_calculated_strings = true;
+ CalculateMnemonicOperandsAndComment(exe_ctx);
+ }
+ }
+};
+
+
+class InstructionList
+{
+public:
+ InstructionList();
+ ~InstructionList();
+
+ size_t
+ GetSize() const;
+
+ uint32_t
+ GetMaxOpcocdeByteSize () const;
+
+ lldb::InstructionSP
+ GetInstructionAtIndex (size_t idx) const;
+
+ uint32_t
+ GetIndexOfNextBranchInstruction(uint32_t start) const;
+
+ uint32_t
+ GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target);
+
+ void
+ Clear();
+
+ void
+ Append (lldb::InstructionSP &inst_sp);
+
+ void
+ Dump (Stream *s,
+ bool show_address,
+ bool show_bytes,
+ const ExecutionContext* exe_ctx);
+
+private:
+ typedef std::vector<lldb::InstructionSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ collection m_instructions;
+};
+
+class PseudoInstruction :
+ public Instruction
+{
+public:
+
+ PseudoInstruction ();
+
+ virtual
+ ~PseudoInstruction ();
+
+ virtual bool
+ DoesBranch ();
+
+ virtual void
+ CalculateMnemonicOperandsAndComment (const ExecutionContext* exe_ctx)
+ {
+ // TODO: fill this in and put opcode name into Instruction::m_opcode_name,
+ // mnemonic into Instruction::m_mnemonics, and any comment into
+ // Instruction::m_comment
+ }
+
+ virtual size_t
+ Decode (const Disassembler &disassembler,
+ const DataExtractor &data,
+ lldb::offset_t data_offset);
+
+ void
+ SetOpcode (size_t opcode_size, void *opcode_data);
+
+ virtual void
+ SetDescription (const char *description);
+
+protected:
+ std::string m_description;
+
+ DISALLOW_COPY_AND_ASSIGN (PseudoInstruction);
+};
+
+class Disassembler :
+ public std::enable_shared_from_this<Disassembler>,
+ public PluginInterface
+{
+public:
+
+ enum
+ {
+ eOptionNone = 0u,
+ eOptionShowBytes = (1u << 0),
+ eOptionRawOuput = (1u << 1),
+ eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains the current PC (mixed mode only)
+ eOptionMarkPCAddress = (1u << 3) // Mark the disassembly line the contains the PC
+ };
+
+ enum HexImmediateStyle
+ {
+ eHexStyleC,
+ eHexStyleAsm,
+ };
+
+ // FindPlugin should be lax about the flavor string (it is too annoying to have various internal uses of the
+ // disassembler fail because the global flavor string gets set wrong. Instead, if you get a flavor string you
+ // don't understand, use the default. Folks who care to check can use the FlavorValidForArchSpec method on the
+ // disassembler they got back.
+ static lldb::DisassemblerSP
+ FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name);
+
+ // This version will use the value in the Target settings if flavor is NULL;
+ static lldb::DisassemblerSP
+ FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name);
+
+ static lldb::DisassemblerSP
+ DisassembleRange (const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const AddressRange &disasm_range);
+
+ static lldb::DisassemblerSP
+ DisassembleBytes (const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const Address &start,
+ const void *bytes,
+ size_t length,
+ uint32_t max_num_instructions,
+ bool data_from_file);
+
+ static bool
+ Disassemble (Debugger &debugger,
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const AddressRange &range,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm);
+
+ static bool
+ Disassemble (Debugger &debugger,
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const Address &start,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm);
+
+ static size_t
+ Disassemble (Debugger &debugger,
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ SymbolContextList &sc_list,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm);
+
+ static bool
+ Disassemble (Debugger &debugger,
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const ConstString &name,
+ Module *module,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm);
+
+ static bool
+ Disassemble (Debugger &debugger,
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const char *flavor,
+ const ExecutionContext &exe_ctx,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ Disassembler(const ArchSpec &arch, const char *flavor);
+ virtual ~Disassembler();
+
+ typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
+
+ static bool
+ PrintInstructions (Disassembler *disasm_ptr,
+ Debugger &debugger,
+ const ArchSpec &arch,
+ const ExecutionContext &exe_ctx,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ uint32_t options,
+ Stream &strm);
+
+ size_t
+ ParseInstructions (const ExecutionContext *exe_ctx,
+ const AddressRange &range,
+ Stream *error_strm_ptr,
+ bool prefer_file_cache);
+
+ size_t
+ ParseInstructions (const ExecutionContext *exe_ctx,
+ const Address &range,
+ uint32_t num_instructions,
+ bool prefer_file_cache);
+
+ virtual size_t
+ DecodeInstructions (const Address &base_addr,
+ const DataExtractor& data,
+ lldb::offset_t data_offset,
+ size_t num_instructions,
+ bool append,
+ bool data_from_file) = 0;
+
+ InstructionList &
+ GetInstructionList ();
+
+ const InstructionList &
+ GetInstructionList () const;
+
+ const ArchSpec &
+ GetArchitecture () const
+ {
+ return m_arch;
+ }
+
+ const char *
+ GetFlavor () const
+ {
+ return m_flavor.c_str();
+ }
+
+ virtual bool
+ FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor) = 0;
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from Disassembler can see and modify these
+ //------------------------------------------------------------------
+ const ArchSpec m_arch;
+ InstructionList m_instruction_list;
+ lldb::addr_t m_base_addr;
+ std::string m_flavor;
+
+private:
+ //------------------------------------------------------------------
+ // For Disassembler only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (Disassembler);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Disassembler_h_
diff --git a/include/lldb/Core/EmulateInstruction.h b/include/lldb/Core/EmulateInstruction.h
new file mode 100644
index 000000000000..08b97e424913
--- /dev/null
+++ b/include/lldb/Core/EmulateInstruction.h
@@ -0,0 +1,641 @@
+//===-- EmulateInstruction.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_EmulateInstruction_h_
+#define lldb_EmulateInstruction_h_
+
+#include <string>
+
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/Opcode.h"
+#include "lldb/Core/RegisterValue.h"
+
+//----------------------------------------------------------------------
+/// @class EmulateInstruction EmulateInstruction.h "lldb/Core/EmulateInstruction.h"
+/// @brief A class that allows emulation of CPU opcodes.
+///
+/// This class is a plug-in interface that is accessed through the
+/// standard static FindPlugin function call in the EmulateInstruction
+/// class. The FindPlugin takes a target triple and returns a new object
+/// if there is a plug-in that supports the architecture and OS. Four
+/// callbacks and a baton are provided. The four callbacks are read
+/// register, write register, read memory and write memory.
+///
+/// This class is currently designed for these main use cases:
+/// - Auto generation of Call Frame Information (CFI) from assembly code
+/// - Predicting single step breakpoint locations
+/// - Emulating instructions for breakpoint traps
+///
+/// Objects can be asked to read an instruction which will cause a call
+/// to the read register callback to get the PC, followed by a read
+/// memory call to read the opcode. If ReadInstruction () returns true,
+/// then a call to EmulateInstruction::EvaluateInstruction () can be
+/// made. At this point the EmulateInstruction subclass will use all of
+/// the callbacks to emulate an instruction.
+///
+/// Clients that provide the callbacks can either do the read/write
+/// registers/memory to actually emulate the instruction on a real or
+/// virtual CPU, or watch for the EmulateInstruction::Context which
+/// is context for the read/write register/memory which explains why
+/// the callback is being called. Examples of a context are:
+/// "pushing register 3 onto the stack at offset -12", or "adjusting
+/// stack pointer by -16". This extra context allows the generation of
+/// CFI information from assembly code without having to actually do
+/// the read/write register/memory.
+///
+/// Clients must be prepared that not all instructions for an
+/// Instruction Set Architecture (ISA) will be emulated.
+///
+/// Subclasses at the very least should implement the instructions that
+/// save and restore registers onto the stack and adjustment to the stack
+/// pointer. By just implementing a few instructions for an ISA that are
+/// the typical prologue opcodes, you can then generate CFI using a
+/// class that will soon be available.
+///
+/// Implementing all of the instructions that affect the PC can then
+/// allow single step prediction support.
+///
+/// Implementing all of the instructions allows for emulation of opcodes
+/// for breakpoint traps and will pave the way for "thread centric"
+/// debugging. The current debugging model is "process centric" where
+/// all threads must be stopped when any thread is stopped; when
+/// hitting software breakpoints we must disable the breakpoint by
+/// restoring the original breakpoint opcde, single stepping and
+/// restoring the breakpoint trap. If all threads were allowed to run
+/// then other threads could miss the breakpoint.
+///
+/// This class centralizes the code that usually is done in separate
+/// code paths in a debugger (single step prediction, finding save
+/// restore locations of registers for unwinding stack frame variables)
+/// and emulating the intruction is just a bonus.
+//----------------------------------------------------------------------
+
+namespace lldb_private {
+
+class EmulateInstruction :
+ public PluginInterface
+{
+public:
+
+ static EmulateInstruction*
+ FindPlugin (const ArchSpec &arch,
+ InstructionType supported_inst_type,
+ const char *plugin_name);
+
+ enum ContextType
+ {
+ eContextInvalid = 0,
+ // Read an instruciton opcode from memory
+ eContextReadOpcode,
+
+ // Usually used for writing a register value whose source value is an
+ // immediate
+ eContextImmediate,
+
+ // Exclusively used when saving a register to the stack as part of the
+ // prologue
+ eContextPushRegisterOnStack,
+
+ // Exclusively used when restoring a register off the stack as part of
+ // the epilogue
+ eContextPopRegisterOffStack,
+
+ // Add or subtract a value from the stack
+ eContextAdjustStackPointer,
+
+ // Adjust the frame pointer for the current frame
+ eContextSetFramePointer,
+
+ // Add or subtract a value from a base address register (other than SP)
+ eContextAdjustBaseRegister,
+
+ // Add or subtract a value from the PC or store a value to the PC.
+ eContextAdjustPC,
+
+ // Used in WriteRegister callbacks to indicate where the
+ eContextRegisterPlusOffset,
+
+ // Used in WriteMemory callback to indicate where the data came from
+ eContextRegisterStore,
+
+ eContextRegisterLoad,
+
+ // Used when performing a PC-relative branch where the
+ eContextRelativeBranchImmediate,
+
+ // Used when performing an absolute branch where the
+ eContextAbsoluteBranchRegister,
+
+ // Used when performing a supervisor call to an operating system to
+ // provide a service:
+ eContextSupervisorCall,
+
+ // Used when performing a MemU operation to read the PC-relative offset
+ // from an address.
+ eContextTableBranchReadMemory,
+
+ // Used when random bits are written into a register
+ eContextWriteRegisterRandomBits,
+
+ // Used when random bits are written to memory
+ eContextWriteMemoryRandomBits,
+
+ eContextArithmetic,
+
+ eContextAdvancePC,
+
+ eContextReturnFromException
+ };
+
+ enum InfoType {
+ eInfoTypeRegisterPlusOffset,
+ eInfoTypeRegisterPlusIndirectOffset,
+ eInfoTypeRegisterToRegisterPlusOffset,
+ eInfoTypeRegisterToRegisterPlusIndirectOffset,
+ eInfoTypeRegisterRegisterOperands,
+ eInfoTypeOffset,
+ eInfoTypeRegister,
+ eInfoTypeImmediate,
+ eInfoTypeImmediateSigned,
+ eInfoTypeAddress,
+ eInfoTypeISAAndImmediate,
+ eInfoTypeISAAndImmediateSigned,
+ eInfoTypeISA,
+ eInfoTypeNoArgs
+ } InfoType;
+
+ struct Context
+ {
+ ContextType type;
+ enum InfoType info_type;
+ union
+ {
+ struct RegisterPlusOffset
+ {
+ RegisterInfo reg; // base register
+ int64_t signed_offset; // signed offset added to base register
+ } RegisterPlusOffset;
+
+ struct RegisterPlusIndirectOffset
+ {
+ RegisterInfo base_reg; // base register number
+ RegisterInfo offset_reg; // offset register kind
+ } RegisterPlusIndirectOffset;
+
+ struct RegisterToRegisterPlusOffset
+ {
+ RegisterInfo data_reg; // source/target register for data
+ RegisterInfo base_reg; // base register for address calculation
+ int64_t offset; // offset for address calculation
+ } RegisterToRegisterPlusOffset;
+
+ struct RegisterToRegisterPlusIndirectOffset
+ {
+ RegisterInfo base_reg; // base register for address calculation
+ RegisterInfo offset_reg; // offset register for address calculation
+ RegisterInfo data_reg; // source/target register for data
+ } RegisterToRegisterPlusIndirectOffset;
+
+ struct RegisterRegisterOperands
+ {
+ RegisterInfo operand1; // register containing first operand for binary op
+ RegisterInfo operand2; // register containing second operand for binary op
+ } RegisterRegisterOperands;
+
+ int64_t signed_offset; // signed offset by which to adjust self (for registers only)
+
+ RegisterInfo reg; // plain register
+
+ uint64_t unsigned_immediate;// unsigned immediate value
+ int64_t signed_immediate; // signed immediate value
+
+ lldb::addr_t address; // direct address
+
+ struct ISAAndImmediate
+ {
+ uint32_t isa;
+ uint32_t unsigned_data32; // immdiate data
+ } ISAAndImmediate;
+
+ struct ISAAndImmediateSigned
+ {
+ uint32_t isa;
+ int32_t signed_data32; // signed immdiate data
+ } ISAAndImmediateSigned;
+
+ uint32_t isa;
+
+ } info;
+
+ Context () :
+ type (eContextInvalid),
+ info_type (eInfoTypeNoArgs)
+ {
+ }
+
+ void
+ SetRegisterPlusOffset (RegisterInfo base_reg,
+ int64_t signed_offset)
+ {
+ info_type = eInfoTypeRegisterPlusOffset;
+ info.RegisterPlusOffset.reg = base_reg;
+ info.RegisterPlusOffset.signed_offset = signed_offset;
+ }
+
+ void
+ SetRegisterPlusIndirectOffset (RegisterInfo base_reg,
+ RegisterInfo offset_reg)
+ {
+ info_type = eInfoTypeRegisterPlusIndirectOffset;
+ info.RegisterPlusIndirectOffset.base_reg = base_reg;
+ info.RegisterPlusIndirectOffset.offset_reg = offset_reg;
+ }
+
+ void
+ SetRegisterToRegisterPlusOffset (RegisterInfo data_reg,
+ RegisterInfo base_reg,
+ int64_t offset)
+ {
+ info_type = eInfoTypeRegisterToRegisterPlusOffset;
+ info.RegisterToRegisterPlusOffset.data_reg = data_reg;
+ info.RegisterToRegisterPlusOffset.base_reg = base_reg;
+ info.RegisterToRegisterPlusOffset.offset = offset;
+ }
+
+ void
+ SetRegisterToRegisterPlusIndirectOffset (RegisterInfo base_reg,
+ RegisterInfo offset_reg,
+ RegisterInfo data_reg)
+ {
+ info_type = eInfoTypeRegisterToRegisterPlusIndirectOffset;
+ info.RegisterToRegisterPlusIndirectOffset.base_reg = base_reg;
+ info.RegisterToRegisterPlusIndirectOffset.offset_reg = offset_reg;
+ info.RegisterToRegisterPlusIndirectOffset.data_reg = data_reg;
+ }
+
+ void
+ SetRegisterRegisterOperands (RegisterInfo op1_reg,
+ RegisterInfo op2_reg)
+ {
+ info_type = eInfoTypeRegisterRegisterOperands;
+ info.RegisterRegisterOperands.operand1 = op1_reg;
+ info.RegisterRegisterOperands.operand2 = op2_reg;
+ }
+
+ void
+ SetOffset (int64_t signed_offset)
+ {
+ info_type = eInfoTypeOffset;
+ info.signed_offset = signed_offset;
+ }
+
+ void
+ SetRegister (RegisterInfo reg)
+ {
+ info_type = eInfoTypeRegister;
+ info.reg = reg;
+ }
+
+ void
+ SetImmediate (uint64_t immediate)
+ {
+ info_type = eInfoTypeImmediate;
+ info.unsigned_immediate = immediate;
+ }
+
+ void
+ SetImmediateSigned (int64_t signed_immediate)
+ {
+ info_type = eInfoTypeImmediateSigned;
+ info.signed_immediate = signed_immediate;
+ }
+
+ void
+ SetAddress (lldb::addr_t address)
+ {
+ info_type = eInfoTypeAddress;
+ info.address = address;
+ }
+ void
+ SetISAAndImmediate (uint32_t isa, uint32_t data)
+ {
+ info_type = eInfoTypeISAAndImmediate;
+ info.ISAAndImmediate.isa = isa;
+ info.ISAAndImmediate.unsigned_data32 = data;
+ }
+
+ void
+ SetISAAndImmediateSigned (uint32_t isa, int32_t data)
+ {
+ info_type = eInfoTypeISAAndImmediateSigned;
+ info.ISAAndImmediateSigned.isa = isa;
+ info.ISAAndImmediateSigned.signed_data32 = data;
+ }
+
+ void
+ SetISA (uint32_t isa)
+ {
+ info_type = eInfoTypeISA;
+ info.isa = isa;
+ }
+
+ void
+ SetNoArgs ()
+ {
+ info_type = eInfoTypeNoArgs;
+ }
+
+ void
+ Dump (Stream &s,
+ EmulateInstruction *instruction) const;
+
+ };
+
+ typedef size_t (*ReadMemoryCallback) (EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ lldb::addr_t addr,
+ void *dst,
+ size_t length);
+
+ typedef size_t (*WriteMemoryCallback) (EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ lldb::addr_t addr,
+ const void *dst,
+ size_t length);
+
+ typedef bool (*ReadRegisterCallback) (EmulateInstruction *instruction,
+ void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value);
+
+ typedef bool (*WriteRegisterCallback) (EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value);
+
+ EmulateInstruction (const ArchSpec &arch);
+
+ virtual ~EmulateInstruction()
+ {
+ }
+ //----------------------------------------------------------------------
+ // Mandatory overrides
+ //----------------------------------------------------------------------
+ virtual bool
+ SupportsEmulatingIntructionsOfType (InstructionType inst_type) = 0;
+
+ virtual bool
+ SetTargetTriple (const ArchSpec &arch) = 0;
+
+ virtual bool
+ ReadInstruction () = 0;
+
+ virtual bool
+ EvaluateInstruction (uint32_t evaluate_options) = 0;
+
+ virtual bool
+ TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) = 0;
+
+ virtual bool
+ GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info) = 0;
+
+ //----------------------------------------------------------------------
+ // Optional overrides
+ //----------------------------------------------------------------------
+ virtual bool
+ SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target);
+
+ virtual bool
+ CreateFunctionEntryUnwind (UnwindPlan &unwind_plan);
+
+ static const char *
+ TranslateRegister (uint32_t reg_kind, uint32_t reg_num, std::string &reg_name);
+
+ //----------------------------------------------------------------------
+ // RegisterInfo variants
+ //----------------------------------------------------------------------
+ bool
+ ReadRegister (const RegisterInfo *reg_info,
+ RegisterValue& reg_value);
+
+ uint64_t
+ ReadRegisterUnsigned (const RegisterInfo *reg_info,
+ uint64_t fail_value,
+ bool *success_ptr);
+
+ bool
+ WriteRegister (const Context &context,
+ const RegisterInfo *ref_info,
+ const RegisterValue& reg_value);
+
+ bool
+ WriteRegisterUnsigned (const Context &context,
+ const RegisterInfo *reg_info,
+ uint64_t reg_value);
+
+ //----------------------------------------------------------------------
+ // Register kind and number variants
+ //----------------------------------------------------------------------
+ bool
+ ReadRegister (uint32_t reg_kind,
+ uint32_t reg_num,
+ RegisterValue& reg_value);
+
+ bool
+ WriteRegister (const Context &context,
+ uint32_t reg_kind,
+ uint32_t reg_num,
+ const RegisterValue& reg_value);
+
+ uint64_t
+ ReadRegisterUnsigned (uint32_t reg_kind,
+ uint32_t reg_num,
+ uint64_t fail_value,
+ bool *success_ptr);
+
+ bool
+ WriteRegisterUnsigned (const Context &context,
+ uint32_t reg_kind,
+ uint32_t reg_num,
+ uint64_t reg_value);
+
+
+ size_t
+ ReadMemory (const Context &context,
+ lldb::addr_t addr,
+ void *dst,
+ size_t dst_len);
+
+ uint64_t
+ ReadMemoryUnsigned (const Context &context,
+ lldb::addr_t addr,
+ size_t byte_size,
+ uint64_t fail_value,
+ bool *success_ptr);
+
+ bool
+ WriteMemory (const Context &context,
+ lldb::addr_t addr,
+ const void *src,
+ size_t src_len);
+
+ bool
+ WriteMemoryUnsigned (const Context &context,
+ lldb::addr_t addr,
+ uint64_t uval,
+ size_t uval_byte_size);
+
+ uint32_t
+ GetAddressByteSize () const
+ {
+ return m_arch.GetAddressByteSize();
+ }
+
+ lldb::ByteOrder
+ GetByteOrder () const
+ {
+ return m_arch.GetByteOrder();
+ }
+
+ const Opcode &
+ GetOpcode () const
+ {
+ return m_opcode;
+ }
+
+ lldb::addr_t
+ GetAddress () const
+ {
+ return m_addr;
+ }
+
+ const ArchSpec &
+ GetArchitecture () const
+ {
+ return m_arch;
+ }
+
+
+ static size_t
+ ReadMemoryFrame (EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ lldb::addr_t addr,
+ void *dst,
+ size_t length);
+
+ static size_t
+ WriteMemoryFrame (EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ lldb::addr_t addr,
+ const void *dst,
+ size_t length);
+
+ static bool
+ ReadRegisterFrame (EmulateInstruction *instruction,
+ void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value);
+
+
+ static bool
+ WriteRegisterFrame (EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value);
+
+ static size_t
+ ReadMemoryDefault (EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ lldb::addr_t addr,
+ void *dst,
+ size_t length);
+
+ static size_t
+ WriteMemoryDefault (EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ lldb::addr_t addr,
+ const void *dst,
+ size_t length);
+
+ static bool
+ ReadRegisterDefault (EmulateInstruction *instruction,
+ void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value);
+
+
+ static bool
+ WriteRegisterDefault (EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value);
+
+ void
+ SetBaton (void *baton);
+
+ void
+ SetCallbacks (ReadMemoryCallback read_mem_callback,
+ WriteMemoryCallback write_mem_callback,
+ ReadRegisterCallback read_reg_callback,
+ WriteRegisterCallback write_reg_callback);
+
+ void
+ SetReadMemCallback (ReadMemoryCallback read_mem_callback);
+
+ void
+ SetWriteMemCallback (WriteMemoryCallback write_mem_callback);
+
+ void
+ SetReadRegCallback (ReadRegisterCallback read_reg_callback);
+
+ void
+ SetWriteRegCallback (WriteRegisterCallback write_reg_callback);
+
+ static bool
+ GetBestRegisterKindAndNumber (const RegisterInfo *reg_info,
+ uint32_t &reg_kind,
+ uint32_t &reg_num);
+
+ static uint32_t
+ GetInternalRegisterNumber (RegisterContext *reg_ctx,
+ const RegisterInfo &reg_info);
+
+protected:
+ ArchSpec m_arch;
+ void * m_baton;
+ ReadMemoryCallback m_read_mem_callback;
+ WriteMemoryCallback m_write_mem_callback;
+ ReadRegisterCallback m_read_reg_callback;
+ WriteRegisterCallback m_write_reg_callback;
+ lldb::addr_t m_addr;
+ Opcode m_opcode;
+
+
+private:
+ //------------------------------------------------------------------
+ // For EmulateInstruction only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (EmulateInstruction);
+};
+
+} // namespace lldb_private
+
+#endif // lldb_EmulateInstruction_h_
diff --git a/include/lldb/Core/Error.h b/include/lldb/Core/Error.h
new file mode 100644
index 000000000000..9e45d5f555d6
--- /dev/null
+++ b/include/lldb/Core/Error.h
@@ -0,0 +1,312 @@
+//===-- Error.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __DCError_h__
+#define __DCError_h__
+#if defined(__cplusplus)
+
+#if defined (__APPLE__)
+#include <mach/mach.h>
+#endif
+#include <stdint.h>
+#include <stdio.h>
+#include <string>
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class Log;
+
+//----------------------------------------------------------------------
+/// @class Error Error.h "lldb/Core/Error.h"
+/// @brief An error handling class.
+///
+/// This class is designed to be able to hold any error code that can be
+/// encountered on a given platform. The errors are stored as a value
+/// of type Error::ValueType. This value should be large enough to hold
+/// any and all errors that the class supports. Each error has an
+/// associated type that is of type lldb::ErrorType. New types
+/// can be added to support new error types, and architecture specific
+/// types can be enabled. In the future we may wish to switch to a
+/// registration mechanism where new error types can be registered at
+/// runtime instead of a hard coded scheme.
+///
+/// All errors in this class also know how to generate a string
+/// representation of themselves for printing results and error codes.
+/// The string value will be fetched on demand and its string value will
+/// be cached until the error is cleared of the value of the error
+/// changes.
+//----------------------------------------------------------------------
+class Error
+{
+public:
+ //------------------------------------------------------------------
+ /// Every error value that this object can contain needs to be able
+ /// to fit into ValueType.
+ //------------------------------------------------------------------
+ typedef uint32_t ValueType;
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize the error object with a generic success value.
+ ///
+ /// @param[in] err
+ /// An error code.
+ ///
+ /// @param[in] type
+ /// The type for \a err.
+ //------------------------------------------------------------------
+ Error ();
+
+ explicit
+ Error (ValueType err, lldb::ErrorType type = lldb::eErrorTypeGeneric);
+
+ explicit
+ Error (const char* err_str);
+
+ Error (const Error &rhs);
+ //------------------------------------------------------------------
+ /// Assignment operator.
+ ///
+ /// @param[in] err
+ /// An error code.
+ ///
+ /// @return
+ /// A const reference to this object.
+ //------------------------------------------------------------------
+ const Error&
+ operator = (const Error& rhs);
+
+
+ //------------------------------------------------------------------
+ /// Assignment operator from a kern_return_t.
+ ///
+ /// Sets the type to \c MachKernel and the error code to \a err.
+ ///
+ /// @param[in] err
+ /// A mach error code.
+ ///
+ /// @return
+ /// A const reference to this object.
+ //------------------------------------------------------------------
+ const Error&
+ operator = (uint32_t err);
+
+ ~Error();
+
+ //------------------------------------------------------------------
+ /// Get the error string associated with the current error.
+ //
+ /// Gets the error value as a NULL terminated C string. The error
+ /// string will be fetched and cached on demand. The error string
+ /// will be retrieved from a callback that is appropriate for the
+ /// type of the error and will be cached until the error value is
+ /// changed or cleared.
+ ///
+ /// @return
+ /// The error as a NULL terminated C string value if the error
+ /// is valid and is able to be converted to a string value,
+ /// NULL otherwise.
+ //------------------------------------------------------------------
+ const char *
+ AsCString (const char *default_error_str = "unknown error") const;
+
+ //------------------------------------------------------------------
+ /// Clear the object state.
+ ///
+ /// Reverts the state of this object to contain a generic success
+ /// value and frees any cached error string value.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Test for error condition.
+ ///
+ /// @return
+ /// \b true if this object contains an error, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ Fail () const;
+
+ //------------------------------------------------------------------
+ /// Access the error value.
+ ///
+ /// @return
+ /// The error value.
+ //------------------------------------------------------------------
+ ValueType
+ GetError () const;
+
+ //------------------------------------------------------------------
+ /// Access the error type.
+ ///
+ /// @return
+ /// The error type enumeration value.
+ //------------------------------------------------------------------
+ lldb::ErrorType
+ GetType () const;
+
+ //------------------------------------------------------------------
+ /// Log an error to Log().
+ ///
+ /// Log the error given a formatted string \a format. If the this
+ /// object contains an error code, update the error string to
+ /// contain the prefix "error: ", followed by the formatted string,
+ /// followed by the error value and any string that describes the
+ /// error value. This allows more context to be given to an error
+ /// string that remains cached in this object. Logging always occurs
+ /// even when the error code contains a non-error value.
+ ///
+ /// @param[in] format
+ /// A printf style format string.
+ ///
+ /// @param[in] ...
+ /// Variable arguments that are needed for the printf style
+ /// format string \a format.
+ //------------------------------------------------------------------
+ void
+ PutToLog (Log *log, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
+
+ //------------------------------------------------------------------
+ /// Log an error to Log() if the error value is an error.
+ ///
+ /// Log the error given a formatted string \a format only if the
+ /// error value in this object describes an error condition. If the
+ /// this object contains an error, update the error string to
+ /// contain the prefix "error: " followed by the formatted string,
+ /// followed by the error value and any string that describes the
+ /// error value. This allows more context to be given to an error
+ /// string that remains cached in this object.
+ ///
+ /// @param[in] format
+ /// A printf style format string.
+ ///
+ /// @param[in] ...
+ /// Variable arguments that are needed for the printf style
+ /// format string \a format.
+ //------------------------------------------------------------------
+ void
+ LogIfError (Log *log, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
+
+ //------------------------------------------------------------------
+ /// Set accessor from a kern_return_t.
+ ///
+ /// Set accesssor for the error value to \a err and the error type
+ /// to \c MachKernel.
+ ///
+ /// @param[in] err
+ /// A mach error code.
+ //------------------------------------------------------------------
+ void
+ SetMachError (uint32_t err);
+
+ //------------------------------------------------------------------
+ /// Set accesssor with an error value and type.
+ ///
+ /// Set accesssor for the error value to \a err and the error type
+ /// to \a type.
+ ///
+ /// @param[in] err
+ /// A mach error code.
+ ///
+ /// @param[in] type
+ /// The type for \a err.
+ //------------------------------------------------------------------
+ void
+ SetError (ValueType err, lldb::ErrorType type);
+
+ //------------------------------------------------------------------
+ /// Set the current error to errno.
+ ///
+ /// Update the error value to be \c errno and update the type to
+ /// be \c Error::POSIX.
+ //------------------------------------------------------------------
+ void
+ SetErrorToErrno ();
+
+ //------------------------------------------------------------------
+ /// Set the current error to a generic error.
+ ///
+ /// Update the error value to be \c LLDB_GENERIC_ERROR and update the
+ /// type to be \c Error::Generic.
+ //------------------------------------------------------------------
+ void
+ SetErrorToGenericError ();
+
+ //------------------------------------------------------------------
+ /// Set the current error string to \a err_str.
+ ///
+ /// Set accessor for the error string value for a generic errors,
+ /// or to supply additional details above and beyond the standard
+ /// error strings that the standard type callbacks typically
+ /// provide. This allows custom strings to be supplied as an
+ /// error explanation. The error string value will remain until the
+ /// error value is cleared or a new error value/type is assigned.
+ ///
+ /// @param err_str
+ /// The new custom error string to copy and cache.
+ //------------------------------------------------------------------
+ void
+ SetErrorString (const char *err_str);
+
+ //------------------------------------------------------------------
+ /// Set the current error string to a formatted error string.
+ ///
+ /// @param format
+ /// A printf style format string
+ //------------------------------------------------------------------
+ int
+ SetErrorStringWithFormat (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ int
+ SetErrorStringWithVarArg (const char *format, va_list args);
+
+ //------------------------------------------------------------------
+ /// Test for success condition.
+ ///
+ /// Returns true if the error code in this object is considered a
+ /// successful return value.
+ ///
+ /// @return
+ /// \b true if this object contains an value that describes
+ /// success (non-erro), \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Success () const;
+
+ //------------------------------------------------------------------
+ /// Test for a failure due to a generic interrupt.
+ ///
+ /// Returns true if the error code in this object was caused by an interrupt.
+ /// At present only supports Posix EINTR.
+ ///
+ /// @return
+ /// \b true if this object contains an value that describes
+ /// failure due to interrupt, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ WasInterrupted() const;
+
+protected:
+ //------------------------------------------------------------------
+ /// Member variables
+ //------------------------------------------------------------------
+ ValueType m_code; ///< Error code as an integer value.
+ lldb::ErrorType m_type; ///< The type of the above error code.
+ mutable std::string m_string; ///< A string representation of the error code.
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // #ifndef __DCError_h__
diff --git a/include/lldb/Core/Event.h b/include/lldb/Core/Event.h
new file mode 100644
index 000000000000..1c3eec0359c3
--- /dev/null
+++ b/include/lldb/Core/Event.h
@@ -0,0 +1,217 @@
+//===-- Event.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Event_h_
+#define liblldb_Event_h_
+
+// C Includes
+// C++ Includes
+#include <list>
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Host/Predicate.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// lldb::EventData
+//----------------------------------------------------------------------
+class EventData
+{
+ friend class Event;
+
+public:
+ EventData ();
+
+ virtual
+ ~EventData();
+
+ virtual const ConstString &
+ GetFlavor () const = 0;
+
+ virtual void
+ Dump (Stream *s) const;
+
+private:
+ virtual void
+ DoOnRemoval (Event *event_ptr)
+ {
+ }
+
+ DISALLOW_COPY_AND_ASSIGN (EventData);
+
+};
+
+//----------------------------------------------------------------------
+// lldb::EventDataBytes
+//----------------------------------------------------------------------
+class EventDataBytes : public EventData
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors
+ //------------------------------------------------------------------
+ EventDataBytes ();
+
+ EventDataBytes (const char *cstr);
+
+ EventDataBytes (const void *src, size_t src_len);
+
+ virtual
+ ~EventDataBytes();
+
+ //------------------------------------------------------------------
+ // Member functions
+ //------------------------------------------------------------------
+ virtual const ConstString &
+ GetFlavor () const;
+
+ virtual void
+ Dump (Stream *s) const;
+
+ const void *
+ GetBytes() const;
+
+ size_t
+ GetByteSize() const;
+
+ void
+ SetBytes (const void *src, size_t src_len);
+
+ void
+ SwapBytes (std::string &new_bytes);
+
+ void
+ SetBytesFromCString (const char *cstr);
+
+ //------------------------------------------------------------------
+ // Static functions
+ //------------------------------------------------------------------
+ static const EventDataBytes *
+ GetEventDataFromEvent (const Event *event_ptr);
+
+ static const void *
+ GetBytesFromEvent (const Event *event_ptr);
+
+ static size_t
+ GetByteSizeFromEvent (const Event *event_ptr);
+
+ static const ConstString &
+ GetFlavorString ();
+
+private:
+ std::string m_bytes;
+
+ DISALLOW_COPY_AND_ASSIGN (EventDataBytes);
+
+};
+
+//----------------------------------------------------------------------
+// lldb::Event
+//----------------------------------------------------------------------
+class Event
+{
+ friend class Broadcaster;
+ friend class Listener;
+ friend class EventData;
+
+public:
+
+ Event (Broadcaster *broadcaster, uint32_t event_type, EventData *data = NULL);
+
+ Event (uint32_t event_type, EventData *data = NULL);
+
+ ~Event ();
+
+ void
+ Dump (Stream *s) const;
+
+ EventData *
+ GetData ()
+ {
+ return m_data_ap.get();
+ }
+
+ const EventData *
+ GetData () const
+ {
+ return m_data_ap.get();
+ }
+
+ void
+ SetData (EventData *new_data)
+ {
+ m_data_ap.reset (new_data);
+ }
+
+ uint32_t
+ GetType () const
+ {
+ return m_type;
+ }
+
+ void
+ SetType (uint32_t new_type)
+ {
+ m_type = new_type;
+ }
+
+ Broadcaster *
+ GetBroadcaster () const
+ {
+ return m_broadcaster;
+ }
+
+ bool
+ BroadcasterIs (Broadcaster *broadcaster)
+ {
+ return broadcaster == m_broadcaster;
+ }
+
+ void
+ Clear()
+ {
+ m_data_ap.reset();
+ }
+
+
+private:
+ // This is only called by Listener when it pops an event off the queue for
+ // the listener. It calls the Event Data's DoOnRemoval() method, which is
+ // virtual and can be overridden by the specific data classes.
+
+ void
+ DoOnRemoval ();
+
+ // Called by Broadcaster::BroadcastEvent prior to letting all the listeners
+ // know about it update the contained broadcaster so that events can be
+ // popped off one queue and re-broadcast to others.
+ void
+ SetBroadcaster (Broadcaster *broadcaster)
+ {
+ m_broadcaster = broadcaster;
+ }
+
+
+ Broadcaster * m_broadcaster; // The broadcaster that sent this event
+ uint32_t m_type; // The bit describing this event
+ std::unique_ptr<EventData> m_data_ap; // User specific data for this event
+
+
+ DISALLOW_COPY_AND_ASSIGN (Event);
+ Event(); // Disallow default constructor
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Event_h_
diff --git a/include/lldb/Core/FileLineResolver.h b/include/lldb/Core/FileLineResolver.h
new file mode 100644
index 000000000000..e1928f1b063d
--- /dev/null
+++ b/include/lldb/Core/FileLineResolver.h
@@ -0,0 +1,81 @@
+//===-- FileLineResolver.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_FileLineResolver_h_
+#define liblldb_FileLineResolver_h_
+
+// Project includes
+#include "lldb/Core/AddressResolver.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class FileLineResolver FileLineResolver.h "lldb/Core/FileLineResolver.h"
+/// @brief This class finds address for source file and line. Optionally, it will look for inlined
+/// instances of the file and line specification.
+//----------------------------------------------------------------------
+
+class FileLineResolver :
+ public Searcher
+{
+public:
+ FileLineResolver () :
+ m_file_spec(),
+ m_line_number(UINT32_MAX), // Set this to zero for all lines in a file
+ m_sc_list (),
+ m_inlines (true)
+ {
+ }
+
+ FileLineResolver (const FileSpec &resolver,
+ uint32_t line_no,
+ bool check_inlines);
+
+ virtual
+ ~FileLineResolver ();
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing);
+
+ virtual Searcher::Depth
+ GetDepth ();
+
+ virtual void
+ GetDescription (Stream *s);
+
+ const SymbolContextList &
+ GetFileLineMatches()
+ {
+ return m_sc_list;
+ }
+
+ void
+ Clear();
+
+ void
+ Reset (const FileSpec &file_spec,
+ uint32_t line,
+ bool check_inlines);
+protected:
+ FileSpec m_file_spec; // This is the file spec we are looking for.
+ uint32_t m_line_number; // This is the line number that we are looking for.
+ SymbolContextList m_sc_list;
+ bool m_inlines; // This determines whether the resolver looks for inlined functions or not.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(FileLineResolver);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_FileLineResolver_h_
diff --git a/include/lldb/Core/FileSpecList.h b/include/lldb/Core/FileSpecList.h
new file mode 100644
index 000000000000..f94bdae83c01
--- /dev/null
+++ b/include/lldb/Core/FileSpecList.h
@@ -0,0 +1,243 @@
+//===-- FileSpecList.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_FileSpecList_h_
+#define liblldb_FileSpecList_h_
+#if defined(__cplusplus)
+
+#include "lldb/lldb-private.h"
+#include "lldb/Host/FileSpec.h"
+#include <vector>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class FileSpecList FileSpecList.h "lldb/Core/FileSpecList.h"
+/// @brief A file collection class.
+///
+/// A class that contains a mutable list of FileSpec objects.
+//----------------------------------------------------------------------
+class FileSpecList
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize this object with an empty file list.
+ //------------------------------------------------------------------
+ FileSpecList ();
+
+ //------------------------------------------------------------------
+ /// Copy constructor.
+ ///
+ /// Initialize this object with a copy of the file list from \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A const reference to another file list object.
+ //------------------------------------------------------------------
+ FileSpecList (const FileSpecList &rhs);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~FileSpecList ();
+
+ //------------------------------------------------------------------
+ /// Assignment operator.
+ ///
+ /// Replace the file list in this object with the file list from
+ /// \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A file list object to copy.
+ ///
+ /// @return
+ /// A const reference to this object.
+ //------------------------------------------------------------------
+ const FileSpecList&
+ operator= (const FileSpecList &rhs);
+
+ //------------------------------------------------------------------
+ /// Append a FileSpec object to the list.
+ ///
+ /// Appends \a file to the end of the file list.
+ ///
+ /// @param[in] file
+ /// A new file to append to this file list.
+ //------------------------------------------------------------------
+ void
+ Append (const FileSpec &file);
+
+ //------------------------------------------------------------------
+ /// Append a FileSpec object if unique.
+ ///
+ /// Appends \a file to the end of the file list if it doesn't
+ /// already exist in the file list.
+ ///
+ /// @param[in] file
+ /// A new file to append to this file list.
+ ///
+ /// @return
+ /// \b true if the file was appended, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ AppendIfUnique (const FileSpec &file);
+
+ //------------------------------------------------------------------
+ /// Clears the file list.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Dumps the file list to the supplied stream pointer "s".
+ ///
+ /// @param[in] s
+ /// The stream that will be used to dump the object description.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, const char *separator_cstr = "\n") const;
+
+ //------------------------------------------------------------------
+ /// Find a file index.
+ ///
+ /// Find the index of the file in the file spec list that matches
+ /// \a file starting \a idx entries into the file spec list.
+ ///
+ /// @param[in] idx
+ /// An index into the file list.
+ ///
+ /// @param[in] file
+ /// The file specification to search for.
+ ///
+ /// @param[in] full
+ /// Should FileSpec::Equal be called with "full" true or false.
+ ///
+ /// @return
+ /// The index of the file that matches \a file if it is found,
+ /// else UINT32_MAX is returned.
+ //------------------------------------------------------------------
+ size_t
+ FindFileIndex (size_t idx, const FileSpec &file, bool full) const;
+
+ //------------------------------------------------------------------
+ /// Get file at index.
+ ///
+ /// Gets a file from the file list. If \a idx is not a valid index,
+ /// an empty FileSpec object will be returned. The file objects
+ /// that are returned can be tested using
+ /// FileSpec::operator void*().
+ ///
+ /// @param[in] idx
+ /// An index into the file list.
+ ///
+ /// @return
+ /// A copy of the FileSpec object at index \a idx. If \a idx
+ /// is out of range, then an empty FileSpec object will be
+ /// returned.
+ //------------------------------------------------------------------
+ const FileSpec &
+ GetFileSpecAtIndex (size_t idx) const;
+
+ //------------------------------------------------------------------
+ /// Get file specification pointer at index.
+ ///
+ /// Gets a file from the file list. The file objects that are
+ /// returned can be tested using FileSpec::operator void*().
+ ///
+ /// @param[in] idx
+ /// An index into the file list.
+ ///
+ /// @return
+ /// A pointer to a contained FileSpec object at index \a idx.
+ /// If \a idx is out of range, then an NULL is returned.
+ //------------------------------------------------------------------
+ const FileSpec *
+ GetFileSpecPointerAtIndex (size_t idx) const;
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// Return the size in bytes that this object takes in memory. This
+ /// returns the size in bytes of this object, not any shared string
+ /// values it may refer to.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ size_t
+ MemorySize () const;
+
+ bool
+ IsEmpty() const
+ {
+ return m_files.empty();
+ }
+
+ //------------------------------------------------------------------
+ /// Get the number of files in the file list.
+ ///
+ /// @return
+ /// The number of files in the file spec list.
+ //------------------------------------------------------------------
+ size_t
+ GetSize () const;
+
+ bool
+ Insert (size_t idx, const FileSpec &file)
+ {
+ if (idx < m_files.size())
+ {
+ m_files.insert(m_files.begin() + idx, file);
+ return true;
+ }
+ else if (idx == m_files.size())
+ {
+ m_files.push_back(file);
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ Replace (size_t idx, const FileSpec &file)
+ {
+ if (idx < m_files.size())
+ {
+ m_files[idx] = file;
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ Remove (size_t idx)
+ {
+ if (idx < m_files.size())
+ {
+ m_files.erase(m_files.begin() + idx);
+ return true;
+ }
+ return false;
+ }
+
+ static size_t GetFilesMatchingPartialPath (const char *path, bool dir_okay, FileSpecList &matches);
+
+protected:
+ typedef std::vector<FileSpec> collection; ///< The collection type for the file list.
+ collection m_files; ///< A collection of FileSpec objects.
+};
+
+} // namespace lldb_private
+
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_FileSpecList_h_
diff --git a/include/lldb/Core/Flags.h b/include/lldb/Core/Flags.h
new file mode 100644
index 000000000000..233f098ead23
--- /dev/null
+++ b/include/lldb/Core/Flags.h
@@ -0,0 +1,253 @@
+//===-- Flags.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Flags_h_
+#define liblldb_Flags_h_
+#if defined(__cplusplus)
+
+
+#include <stdint.h>
+#include <unistd.h>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Flags Flags.h "lldb/Core/Flags.h"
+/// @brief A class to manage flags.
+///
+/// The Flags class managed flag bits and allows testing and
+/// modification of individual or multiple flag bits.
+//----------------------------------------------------------------------
+class Flags
+{
+public:
+ //----------------------------------------------------------------------
+ /// The value type for flags is a 32 bit unsigned integer type.
+ //----------------------------------------------------------------------
+ typedef uint32_t ValueType;
+
+ //----------------------------------------------------------------------
+ /// Construct with initial flag bit values.
+ ///
+ /// Constructs this object with \a mask as the initial value for all
+ /// of the flags.
+ ///
+ /// @param[in] mask
+ /// The initial value for all flags.
+ //----------------------------------------------------------------------
+ Flags (ValueType flags = 0) :
+ m_flags (flags)
+ {
+ }
+
+ //----------------------------------------------------------------------
+ /// Copy constructor.
+ ///
+ /// Construct and copy the flags from \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A const Flags object reference to copy.
+ //----------------------------------------------------------------------
+ Flags (const Flags& rhs) :
+ m_flags(rhs.m_flags)
+ {
+ }
+
+ //----------------------------------------------------------------------
+ /// Destructor.
+ //----------------------------------------------------------------------
+ ~Flags ()
+ {
+ }
+
+ //----------------------------------------------------------------------
+ /// Get accessor for all flags.
+ ///
+ /// @return
+ /// Returns all of the flags as a Flags::ValueType.
+ //----------------------------------------------------------------------
+ ValueType
+ Get () const
+ {
+ return m_flags;
+ }
+
+ //----------------------------------------------------------------------
+ /// Return the number of flags that can be represented in this
+ /// object.
+ ///
+ /// @return
+ /// The maximum number bits in this flag object.
+ //----------------------------------------------------------------------
+ size_t
+ GetBitSize() const
+ {
+ return sizeof (ValueType) * 8;
+ }
+
+ //----------------------------------------------------------------------
+ /// Set accessor for all flags.
+ ///
+ /// @param[in] flags
+ /// The bits with which to replace all of the current flags.
+ //----------------------------------------------------------------------
+ void
+ Reset (ValueType flags)
+ {
+ m_flags = flags;
+ }
+
+ //----------------------------------------------------------------------
+ /// Clear one or more flags.
+ ///
+ /// @param[in] mask
+ /// A bitfield containing one or more flags.
+ ///
+ /// @return
+ /// The new flags after clearing all bits from \a mask.
+ //----------------------------------------------------------------------
+ ValueType
+ Clear (ValueType mask = ~(ValueType)0)
+ {
+ m_flags &= ~mask;
+ return m_flags;
+ }
+
+
+ //----------------------------------------------------------------------
+ /// Set one or more flags by logical OR'ing \a mask with the current
+ /// flags.
+ ///
+ /// @param[in] mask
+ /// A bitfield containing one or more flags.
+ ///
+ /// @return
+ /// The new flags after setting all bits from \a mask.
+ //----------------------------------------------------------------------
+ ValueType
+ Set (ValueType mask)
+ {
+ m_flags |= mask;
+ return m_flags;
+ }
+
+
+ //----------------------------------------------------------------------
+ /// Test if all bits in \a mask are 1 in the current flags
+ ///
+ /// @return
+ /// \b true if all flags in \a mask are 1, \b false
+ /// otherwise.
+ //----------------------------------------------------------------------
+ bool
+ AllSet (ValueType mask) const
+ {
+ return (m_flags & mask) == mask;
+ }
+
+ //----------------------------------------------------------------------
+ /// Test one or more flags.
+ ///
+ /// @return
+ /// \b true if any flags in \a mask are 1, \b false
+ /// otherwise.
+ //----------------------------------------------------------------------
+ bool
+ AnySet (ValueType mask) const
+ {
+ return (m_flags & mask) != 0;
+ }
+
+ //----------------------------------------------------------------------
+ /// Test a single flag bit.
+ ///
+ /// @return
+ /// \b true if \a bit is set, \b false otherwise.
+ //----------------------------------------------------------------------
+ bool
+ Test (ValueType bit) const
+ {
+ return (m_flags & bit) != 0;
+ }
+
+ //----------------------------------------------------------------------
+ /// Test if all bits in \a mask are clear.
+ ///
+ /// @return
+ /// \b true if \b all flags in \a mask are clear, \b false
+ /// otherwise.
+ //----------------------------------------------------------------------
+ bool
+ AllClear (ValueType mask) const
+ {
+ return (m_flags & mask) == 0;
+ }
+
+ bool
+ AnyClear (ValueType mask) const
+ {
+ return (m_flags & mask) != mask;
+ }
+
+ //----------------------------------------------------------------------
+ /// Test a single flag bit to see if it is clear (zero).
+ ///
+ /// @return
+ /// \b true if \a bit is 0, \b false otherwise.
+ //----------------------------------------------------------------------
+ bool
+ IsClear (ValueType bit) const
+ {
+ return (m_flags & bit) == 0;
+ }
+
+ //----------------------------------------------------------------------
+ /// Get the number of zero bits in \a m_flags.
+ ///
+ /// @return
+ /// The number of bits that are set to 0 in the current flags.
+ //----------------------------------------------------------------------
+ size_t
+ ClearCount () const
+ {
+ size_t count = 0;
+ for (ValueType shift = 0; shift < sizeof(ValueType)*8; ++shift)
+ {
+ if ((m_flags & (1u << shift)) == 0)
+ ++count;
+ }
+ return count;
+ }
+
+ //----------------------------------------------------------------------
+ /// Get the number of one bits in \a m_flags.
+ ///
+ /// @return
+ /// The number of bits that are set to 1 in the current flags.
+ //----------------------------------------------------------------------
+ size_t
+ SetCount () const
+ {
+ size_t count = 0;
+ for (ValueType mask = m_flags; mask; mask >>= 1)
+ {
+ if (mask & 1u)
+ ++count;
+ }
+ return count;
+ }
+
+protected:
+ ValueType m_flags; ///< The flags.
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_Flags_h_
diff --git a/include/lldb/Core/History.h b/include/lldb/Core/History.h
new file mode 100644
index 000000000000..b3626882f843
--- /dev/null
+++ b/include/lldb/Core/History.h
@@ -0,0 +1,177 @@
+//===-- History.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_History_h_
+#define lldb_History_h_
+
+// C Includes
+#include <stdint.h>
+
+// C++ Includes
+#include <stack>
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class HistorySource History.h "lldb/Core/History.h"
+/// @brief A class that defines history events.
+//----------------------------------------------------------------------
+
+class HistorySource
+{
+public:
+ typedef const void * HistoryEvent;
+
+ HistorySource () :
+ m_mutex (Mutex::eMutexTypeRecursive),
+ m_events ()
+ {
+ }
+
+ virtual
+ ~HistorySource()
+ {
+ }
+
+ // Create a new history event. Subclasses should use any data or members
+ // in the subclass of this class to produce a history event and push it
+ // onto the end of the history stack.
+
+ virtual HistoryEvent
+ CreateHistoryEvent () = 0;
+
+ virtual void
+ DeleteHistoryEvent (HistoryEvent event) = 0;
+
+ virtual void
+ DumpHistoryEvent (Stream &strm, HistoryEvent event) = 0;
+
+ virtual size_t
+ GetHistoryEventCount() = 0;
+
+ virtual HistoryEvent
+ GetHistoryEventAtIndex (uint32_t idx) = 0;
+
+ virtual HistoryEvent
+ GetCurrentHistoryEvent () = 0;
+
+ // Return 0 when lhs == rhs, 1 if lhs > rhs, or -1 if lhs < rhs.
+ virtual int
+ CompareHistoryEvents (const HistoryEvent lhs,
+ const HistoryEvent rhs) = 0;
+
+ virtual bool
+ IsCurrentHistoryEvent (const HistoryEvent event) = 0;
+
+private:
+ typedef std::stack<HistoryEvent> collection;
+
+ Mutex m_mutex;
+ collection m_events;
+
+ DISALLOW_COPY_AND_ASSIGN (HistorySource);
+
+};
+
+//----------------------------------------------------------------------
+/// @class HistorySourceUInt History.h "lldb/Core/History.h"
+/// @brief A class that defines history events that are represented by
+/// unsigned integers.
+///
+/// Any history event that is defined by a unique monotonically
+/// increasing unsigned integer
+//----------------------------------------------------------------------
+
+class HistorySourceUInt : public HistorySource
+{
+ HistorySourceUInt (const char *id_name, uintptr_t start_value = 0u) :
+ HistorySource(),
+ m_name (id_name),
+ m_curr_id (start_value)
+ {
+ }
+
+ virtual
+ ~HistorySourceUInt()
+ {
+ }
+
+ // Create a new history event. Subclasses should use any data or members
+ // in the subclass of this class to produce a history event and push it
+ // onto the end of the history stack.
+
+ virtual HistoryEvent
+ CreateHistoryEvent ()
+ {
+ ++m_curr_id;
+ return (HistoryEvent)m_curr_id;
+ }
+
+ virtual void
+ DeleteHistoryEvent (HistoryEvent event)
+ {
+ // Nothing to delete, the event contains the integer
+ }
+
+ virtual void
+ DumpHistoryEvent (Stream &strm, HistoryEvent event);
+
+ virtual size_t
+ GetHistoryEventCount()
+ {
+ return m_curr_id;
+ }
+
+ virtual HistoryEvent
+ GetHistoryEventAtIndex (uint32_t idx)
+ {
+ return (HistoryEvent)((uintptr_t)idx);
+ }
+
+ virtual HistoryEvent
+ GetCurrentHistoryEvent ()
+ {
+ return (HistoryEvent)m_curr_id;
+ }
+
+ // Return 0 when lhs == rhs, 1 if lhs > rhs, or -1 if lhs < rhs.
+ virtual int
+ CompareHistoryEvents (const HistoryEvent lhs,
+ const HistoryEvent rhs)
+ {
+ uintptr_t lhs_uint = (uintptr_t)lhs;
+ uintptr_t rhs_uint = (uintptr_t)rhs;
+ if (lhs_uint < rhs_uint)
+ return -1;
+ if (lhs_uint > rhs_uint)
+ return +1;
+ return 0;
+ }
+
+ virtual bool
+ IsCurrentHistoryEvent (const HistoryEvent event)
+ {
+ return (uintptr_t)event == m_curr_id;
+ }
+
+protected:
+ std::string m_name; // The name of the history unsigned integer
+ uintptr_t m_curr_id; // The current value of the history unsigned unteger
+};
+
+
+} // namespace lldb_private
+
+#endif // lldb_History_h_
diff --git a/include/lldb/Core/IOStreamMacros.h b/include/lldb/Core/IOStreamMacros.h
new file mode 100644
index 000000000000..cc4eeb0e050f
--- /dev/null
+++ b/include/lldb/Core/IOStreamMacros.h
@@ -0,0 +1,38 @@
+//===-- IOStreamMacros.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_IOStreamMacros_h_
+#define liblldb_IOStreamMacros_h_
+#if defined(__cplusplus)
+
+#include <iomanip>
+
+#define RAW_HEXBASE std::setfill('0') << std::hex << std::right
+#define HEXBASE '0' << 'x' << RAW_HEXBASE
+#define RAWHEX8(x) RAW_HEXBASE << std::setw(2) << ((uint32_t)(x))
+#define RAWHEX16 RAW_HEXBASE << std::setw(4)
+#define RAWHEX32 RAW_HEXBASE << std::setw(8)
+#define RAWHEX64 RAW_HEXBASE << std::setw(16)
+#define HEX8(x) HEXBASE << std::setw(2) << ((uint32_t)(x))
+#define HEX16 HEXBASE << std::setw(4)
+#define HEX32 HEXBASE << std::setw(8)
+#define HEX64 HEXBASE << std::setw(16)
+#define RAW_HEX(x) RAW_HEXBASE << std::setw(sizeof(x)*2) << (x)
+#define HEX(x) HEXBASE << std::setw(sizeof(x)*2) << (x)
+#define HEX_SIZE(x, sz) HEXBASE << std::setw((sz)) << (x)
+#define STRING_WIDTH(w) std::setfill(' ') << std::setw(w)
+#define LEFT_STRING_WIDTH(s, w) std::left << std::setfill(' ') << std::setw(w) << (s) << std::right
+#define DECIMAL std::dec << std::setfill(' ')
+#define DECIMAL_WIDTH(w) DECIMAL << std::setw(w)
+//#define FLOAT(n, d) std::setfill(' ') << std::setw((n)+(d)+1) << std::setprecision(d) << std::showpoint << std::fixed
+#define INDENT_WITH_SPACES(iword_idx) std::setfill(' ') << std::setw((iword_idx)) << ""
+#define INDENT_WITH_TABS(iword_idx) std::setfill('\t') << std::setw((iword_idx)) << ""
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_IOStreamMacros_h_
diff --git a/include/lldb/Core/InputReader.h b/include/lldb/Core/InputReader.h
new file mode 100644
index 000000000000..fa86e9a39e2b
--- /dev/null
+++ b/include/lldb/Core/InputReader.h
@@ -0,0 +1,274 @@
+//===-- InputReader.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_InputReader_h_
+#define liblldb_InputReader_h_
+
+#include <string.h>
+
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Host/Predicate.h"
+
+
+namespace lldb_private {
+
+class InputReader
+{
+public:
+
+ typedef size_t (*Callback) (void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+ struct HandlerData
+ {
+ InputReader& reader;
+ const char *bytes;
+ size_t bytes_len;
+ void* baton;
+
+ HandlerData(InputReader& r,
+ const char* b,
+ size_t l,
+ void* t) :
+ reader(r),
+ bytes(b),
+ bytes_len(l),
+ baton(t)
+ {
+ }
+
+ lldb::StreamSP
+ GetOutStream();
+
+ bool
+ GetBatchMode();
+ };
+
+ struct InitializationParameters
+ {
+ private:
+ void* m_baton;
+ lldb::InputReaderGranularity m_token_size;
+ char* m_end_token;
+ char* m_prompt;
+ bool m_echo;
+ bool m_save_user_input;
+ public:
+ InitializationParameters() :
+ m_baton(NULL),
+ m_token_size(lldb::eInputReaderGranularityLine),
+ m_echo(true),
+ m_save_user_input(false)
+ {
+ SetEndToken("DONE");
+ SetPrompt("> ");
+ }
+
+ InitializationParameters&
+ SetEcho(bool e)
+ {
+ m_echo = e;
+ return *this;
+ }
+
+ InitializationParameters&
+ SetSaveUserInput(bool s)
+ {
+ m_save_user_input = s;
+ return *this;
+ }
+
+ InitializationParameters&
+ SetBaton(void* b)
+ {
+ m_baton = b;
+ return *this;
+ }
+
+ InitializationParameters&
+ SetGranularity(lldb::InputReaderGranularity g)
+ {
+ m_token_size = g;
+ return *this;
+ }
+
+ InitializationParameters&
+ SetEndToken(const char* e)
+ {
+ m_end_token = new char[strlen(e)+1];
+ ::strcpy(m_end_token,e);
+ return *this;
+ }
+
+ InitializationParameters&
+ SetPrompt(const char* p)
+ {
+ m_prompt = new char[strlen(p)+1];
+ ::strcpy(m_prompt,p);
+ return *this;
+ }
+
+ friend class InputReaderEZ;
+
+ };
+
+ InputReader (Debugger &debugger);
+
+ virtual
+ ~InputReader ();
+
+ virtual Error
+ Initialize (Callback callback,
+ void *baton,
+ lldb::InputReaderGranularity token_size,
+ const char *end_token,
+ const char *prompt,
+ bool echo);
+
+ virtual Error Initialize(void* baton,
+ lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
+ const char* end_token = "DONE",
+ const char *prompt = "> ",
+ bool echo = true)
+ {
+ return Error("unimplemented");
+ }
+
+ virtual Error
+ Initialize(InitializationParameters& params)
+ {
+ return Error("unimplemented");
+ }
+
+ // to use these handlers instead of the Callback function, you must subclass
+ // InputReaderEZ, and redefine the handlers for the events you care about
+ virtual void
+ ActivateHandler(HandlerData&) {}
+
+ virtual void
+ DeactivateHandler(HandlerData&) {}
+
+ virtual void
+ ReactivateHandler(HandlerData&) {}
+
+ virtual void
+ AsynchronousOutputWrittenHandler(HandlerData&) {}
+
+ virtual void
+ GotTokenHandler(HandlerData&) {}
+
+ virtual void
+ InterruptHandler(HandlerData&) {}
+
+ virtual void
+ EOFHandler(HandlerData&) {}
+
+ virtual void
+ DoneHandler(HandlerData&) {}
+
+ bool
+ IsDone () const
+ {
+ return m_done;
+ }
+
+ void
+ SetIsDone (bool b)
+ {
+ m_done = b;
+ }
+
+ lldb::InputReaderGranularity
+ GetGranularity () const
+ {
+ return m_granularity;
+ }
+
+ bool
+ GetEcho () const
+ {
+ return m_echo;
+ }
+
+ StringList&
+ GetUserInput()
+ {
+ return m_user_input;
+ }
+
+ virtual bool
+ GetSaveUserInput()
+ {
+ return false;
+ }
+
+ // Subclasses _can_ override this function to get input as it comes in
+ // without any granularity
+ virtual size_t
+ HandleRawBytes (const char *bytes, size_t bytes_len);
+
+ Debugger &
+ GetDebugger()
+ {
+ return m_debugger;
+ }
+
+ bool
+ IsActive () const
+ {
+ return m_active;
+ }
+
+ const char *
+ GetPrompt () const;
+
+ void
+ RefreshPrompt();
+
+ // If you want to read from an input reader synchronously, then just initialize the
+ // reader and then call WaitOnReaderIsDone, which will return when the reader is popped.
+ void
+ WaitOnReaderIsDone ();
+
+ static const char *
+ GranularityAsCString (lldb::InputReaderGranularity granularity);
+
+protected:
+ friend class Debugger;
+
+ void
+ Notify (lldb::InputReaderAction notification);
+
+ Debugger &m_debugger;
+ Callback m_callback;
+ void *m_callback_baton;
+ std::string m_end_token;
+ std::string m_prompt;
+ lldb::InputReaderGranularity m_granularity;
+ bool m_done;
+ bool m_echo;
+ bool m_active;
+ Predicate<bool> m_reader_done;
+ StringList m_user_input;
+ bool m_save_user_input;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (InputReader);
+
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_InputReader_h_
diff --git a/include/lldb/Core/InputReaderEZ.h b/include/lldb/Core/InputReaderEZ.h
new file mode 100644
index 000000000000..85561b6f0a9e
--- /dev/null
+++ b/include/lldb/Core/InputReaderEZ.h
@@ -0,0 +1,87 @@
+//===-- InputReaderEZ.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_InputReaderEZ_h_
+#define liblldb_InputReaderEZ_h_
+
+#include "lldb/Core/InputReader.h"
+
+namespace lldb_private {
+
+class InputReaderEZ : public InputReader
+{
+
+private:
+
+ static size_t Callback_Impl(void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+public:
+
+ InputReaderEZ (Debugger &debugger) :
+ InputReader(debugger)
+ {}
+
+ virtual
+ ~InputReaderEZ ();
+
+ using InputReader::Initialize;
+ virtual Error
+ Initialize(void* baton,
+ lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
+ const char* end_token = "DONE",
+ const char *prompt = "> ",
+ bool echo = true);
+
+ virtual Error
+ Initialize(InitializationParameters& params);
+
+ virtual void
+ ActivateHandler(HandlerData&) {}
+
+ virtual void
+ DeactivateHandler(HandlerData&) {}
+
+ virtual void
+ ReactivateHandler(HandlerData&) {}
+
+ virtual void
+ AsynchronousOutputWrittenHandler(HandlerData&) {}
+
+ virtual void
+ GotTokenHandler(HandlerData&) {}
+
+ virtual void
+ InterruptHandler(HandlerData&) {}
+
+ virtual void
+ EOFHandler(HandlerData&) {}
+
+ virtual void
+ DoneHandler(HandlerData&) {}
+
+ virtual bool
+ GetSaveUserInput()
+ {
+ return m_save_user_input;
+ }
+
+protected:
+ friend class Debugger;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (InputReaderEZ);
+
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_InputReaderEZ_h_
diff --git a/include/lldb/Core/InputReaderStack.h b/include/lldb/Core/InputReaderStack.h
new file mode 100644
index 000000000000..a73b97cad571
--- /dev/null
+++ b/include/lldb/Core/InputReaderStack.h
@@ -0,0 +1,58 @@
+//===-- InputReaderStack.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_InputReaderStack_h_
+#define liblldb_InputReaderStack_h_
+
+#include <stack>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+class InputReaderStack
+{
+public:
+
+ InputReaderStack ();
+
+ ~InputReaderStack ();
+
+ size_t
+ GetSize () const;
+
+ void
+ Push (const lldb::InputReaderSP& reader_sp);
+
+ bool
+ IsEmpty () const;
+
+ lldb::InputReaderSP
+ Top ();
+
+ void
+ Pop ();
+
+ Mutex &
+ GetStackMutex ();
+
+protected:
+
+ std::stack<lldb::InputReaderSP> m_input_readers;
+ mutable Mutex m_input_readers_mutex;
+
+private:
+
+ DISALLOW_COPY_AND_ASSIGN (InputReaderStack);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_InputReaderStack_h_
diff --git a/include/lldb/Core/Language.h b/include/lldb/Core/Language.h
new file mode 100644
index 000000000000..670c6aa695e1
--- /dev/null
+++ b/include/lldb/Core/Language.h
@@ -0,0 +1,117 @@
+//===-- Language.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Language_h_
+#define liblldb_Language_h_
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Language Language.h "lldb/Core/Language.h"
+/// @brief Encapsulates the programming language for an lldb object.
+///
+/// Languages are represented by an enumeration value.
+///
+/// The enumeration values used when describing the programming language
+/// are the same values as the latest DWARF specification.
+//----------------------------------------------------------------------
+class Language
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with optional language enumeration.
+ //------------------------------------------------------------------
+ Language(lldb::LanguageType language = lldb::eLanguageTypeUnknown);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual in case this class is subclassed.
+ //------------------------------------------------------------------
+ virtual
+ ~Language();
+
+ //------------------------------------------------------------------
+ /// Get the language value as a NULL termianted C string.
+ ///
+ /// @return
+ /// The C string representation of the language. The returned
+ /// string does not need to be freed as it comes from constant
+ /// strings. NULL can be returned when the language is set to
+ /// a value that doesn't match of of the lldb::LanguageType
+ /// enumerations.
+ //------------------------------------------------------------------
+ const char *
+ AsCString (lldb::DescriptionLevel level = lldb::eDescriptionLevelBrief) const;
+
+ void
+ Clear();
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+ //------------------------------------------------------------------
+ /// Dump the language value to the stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the language description.
+ //------------------------------------------------------------------
+ void
+ Dump(Stream *s) const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the language.
+ ///
+ /// @return
+ /// The enumeration value that describes the programming
+ /// language that an object is associated with.
+ //------------------------------------------------------------------
+ virtual lldb::LanguageType
+ GetLanguage() const;
+
+ //------------------------------------------------------------------
+ /// Set accessor for the language.
+ ///
+ /// @param[in] language
+ /// The new enumeration value that describes the programming
+ /// language that an object is associated with.
+ //------------------------------------------------------------------
+ void
+ SetLanguage(lldb::LanguageType language);
+
+ //------------------------------------------------------------------
+ /// Set accessor for the language.
+ ///
+ /// @param[in] language_cstr
+ /// The language name as a C string.
+ //------------------------------------------------------------------
+ bool
+ SetLanguageFromCString(const char *language_cstr);
+
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ lldb::LanguageType m_language; ///< The programming language enumeration value.
+ ///< The enumeration values are the same as the
+ ///< latest DWARF specification.
+};
+
+//--------------------------------------------------------------
+/// Stream the language enumeration as a string object to a
+/// Stream.
+//--------------------------------------------------------------
+Stream& operator << (Stream& s, const Language& language);
+
+} // namespace lldb_private
+
+#endif // liblldb_Language_h_
diff --git a/include/lldb/Core/Listener.h b/include/lldb/Core/Listener.h
new file mode 100644
index 000000000000..a12a65d705db
--- /dev/null
+++ b/include/lldb/Core/Listener.h
@@ -0,0 +1,194 @@
+//===-- Listener.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Select_h_
+#define liblldb_Select_h_
+
+// C Includes
+// C++ Includes
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Host/Predicate.h"
+#include "lldb/Core/Event.h"
+
+namespace lldb_private {
+
+class Listener
+{
+public:
+ typedef bool (*HandleBroadcastCallback) (lldb::EventSP &event_sp, void *baton);
+
+ friend class Broadcaster;
+ friend class BroadcasterManager;
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ Listener (const char *name);
+
+ ~Listener ();
+
+ void
+ AddEvent (lldb::EventSP &event);
+
+ void
+ Clear ();
+
+ const char *
+ GetName ()
+ {
+ return m_name.c_str();
+ }
+
+ uint32_t
+ StartListeningForEventSpec (BroadcasterManager &manager,
+ const BroadcastEventSpec &event_spec);
+
+ bool
+ StopListeningForEventSpec (BroadcasterManager &manager,
+ const BroadcastEventSpec &event_spec);
+
+ uint32_t
+ StartListeningForEvents (Broadcaster* broadcaster,
+ uint32_t event_mask);
+
+ uint32_t
+ StartListeningForEvents (Broadcaster* broadcaster,
+ uint32_t event_mask,
+ HandleBroadcastCallback callback,
+ void *callback_user_data);
+
+ bool
+ StopListeningForEvents (Broadcaster* broadcaster,
+ uint32_t event_mask);
+
+ // Returns true if an event was recieved, false if we timed out.
+ bool
+ WaitForEvent (const TimeValue *timeout,
+ lldb::EventSP &event_sp);
+
+ bool
+ WaitForEventForBroadcaster (const TimeValue *timeout,
+ Broadcaster *broadcaster,
+ lldb::EventSP &event_sp);
+
+ bool
+ WaitForEventForBroadcasterWithType (const TimeValue *timeout,
+ Broadcaster *broadcaster,
+ uint32_t event_type_mask,
+ lldb::EventSP &event_sp);
+
+ Event *
+ PeekAtNextEvent ();
+
+ Event *
+ PeekAtNextEventForBroadcaster (Broadcaster *broadcaster);
+
+ Event *
+ PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster,
+ uint32_t event_type_mask);
+
+ bool
+ GetNextEvent (lldb::EventSP &event_sp);
+
+ bool
+ GetNextEventForBroadcaster (Broadcaster *broadcaster,
+ lldb::EventSP &event_sp);
+
+ bool
+ GetNextEventForBroadcasterWithType (Broadcaster *broadcaster,
+ uint32_t event_type_mask,
+ lldb::EventSP &event_sp);
+
+ size_t
+ HandleBroadcastEvent (lldb::EventSP &event_sp);
+
+private:
+
+ //------------------------------------------------------------------
+ // Classes that inherit from Listener can see and modify these
+ //------------------------------------------------------------------
+ struct BroadcasterInfo
+ {
+ BroadcasterInfo(uint32_t mask, HandleBroadcastCallback cb = NULL, void *ud = NULL) :
+ event_mask (mask),
+ callback (cb),
+ callback_user_data (ud)
+ {
+ }
+
+ uint32_t event_mask;
+ HandleBroadcastCallback callback;
+ void *callback_user_data;
+ };
+
+ typedef std::multimap<Broadcaster*, BroadcasterInfo> broadcaster_collection;
+ typedef std::list<lldb::EventSP> event_collection;
+ typedef std::vector<BroadcasterManager *> broadcaster_manager_collection;
+
+ bool
+ FindNextEventInternal (Broadcaster *broadcaster, // NULL for any broadcaster
+ const ConstString *sources, // NULL for any event
+ uint32_t num_sources,
+ uint32_t event_type_mask,
+ lldb::EventSP &event_sp,
+ bool remove);
+
+ bool
+ GetNextEventInternal (Broadcaster *broadcaster, // NULL for any broadcaster
+ const ConstString *sources, // NULL for any event
+ uint32_t num_sources,
+ uint32_t event_type_mask,
+ lldb::EventSP &event_sp);
+
+ bool
+ WaitForEventsInternal (const TimeValue *timeout,
+ Broadcaster *broadcaster, // NULL for any broadcaster
+ const ConstString *sources, // NULL for any event
+ uint32_t num_sources,
+ uint32_t event_type_mask,
+ lldb::EventSP &event_sp);
+
+ std::string m_name;
+ broadcaster_collection m_broadcasters;
+ Mutex m_broadcasters_mutex; // Protects m_broadcasters
+ event_collection m_events;
+ Mutex m_events_mutex; // Protects m_broadcasters and m_events
+ Predicate<bool> m_cond_wait;
+ broadcaster_manager_collection m_broadcaster_managers;
+
+ void
+ BroadcasterWillDestruct (Broadcaster *);
+
+ void
+ BroadcasterManagerWillDestruct (BroadcasterManager *manager);
+
+
+// broadcaster_collection::iterator
+// FindBroadcasterWithMask (Broadcaster *broadcaster,
+// uint32_t event_mask,
+// bool exact);
+
+ //------------------------------------------------------------------
+ // For Listener only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (Listener);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Select_h_
diff --git a/include/lldb/Core/Log.h b/include/lldb/Core/Log.h
new file mode 100644
index 000000000000..ced6f2565d9a
--- /dev/null
+++ b/include/lldb/Core/Log.h
@@ -0,0 +1,236 @@
+//===-- Log.h ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Log_h_
+#define liblldb_Log_h_
+
+// C Includes
+#include <stdbool.h>
+#include <stdint.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Core/PluginInterface.h"
+
+//----------------------------------------------------------------------
+// Logging types
+//----------------------------------------------------------------------
+#define LLDB_LOG_FLAG_STDOUT (1u << 0)
+#define LLDB_LOG_FLAG_STDERR (1u << 1)
+#define LLDB_LOG_FLAG_FATAL (1u << 2)
+#define LLDB_LOG_FLAG_ERROR (1u << 3)
+#define LLDB_LOG_FLAG_WARNING (1u << 4)
+#define LLDB_LOG_FLAG_DEBUG (1u << 5)
+#define LLDB_LOG_FLAG_VERBOSE (1u << 6)
+
+//----------------------------------------------------------------------
+// Logging Options
+//----------------------------------------------------------------------
+#define LLDB_LOG_OPTION_THREADSAFE (1u << 0)
+#define LLDB_LOG_OPTION_VERBOSE (1u << 1)
+#define LLDB_LOG_OPTION_DEBUG (1u << 2)
+#define LLDB_LOG_OPTION_PREPEND_SEQUENCE (1u << 3)
+#define LLDB_LOG_OPTION_PREPEND_TIMESTAMP (1u << 4)
+#define LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD (1u << 5)
+#define LLDB_LOG_OPTION_PREPEND_THREAD_NAME (1U << 6)
+#define LLDB_LOG_OPTION_BACKTRACE (1U << 7)
+
+//----------------------------------------------------------------------
+// Logging Functions
+//----------------------------------------------------------------------
+namespace lldb_private {
+
+class Log
+{
+public:
+
+ //------------------------------------------------------------------
+ // Callback definitions for abstracted plug-in log access.
+ //------------------------------------------------------------------
+ typedef void (*DisableCallback) (const char **categories, Stream *feedback_strm);
+ typedef Log * (*EnableCallback) (lldb::StreamSP &log_stream_sp,
+ uint32_t log_options,
+ const char **categories,
+ Stream *feedback_strm);
+ typedef void (*ListCategoriesCallback) (Stream *strm);
+
+ struct Callbacks
+ {
+ DisableCallback disable;
+ EnableCallback enable;
+ ListCategoriesCallback list_categories;
+ };
+
+ //------------------------------------------------------------------
+ // Static accessors for logging channels
+ //------------------------------------------------------------------
+ static void
+ RegisterLogChannel (const ConstString &channel,
+ const Log::Callbacks &log_callbacks);
+
+ static bool
+ UnregisterLogChannel (const ConstString &channel);
+
+ static bool
+ GetLogChannelCallbacks (const ConstString &channel,
+ Log::Callbacks &log_callbacks);
+
+
+ static void
+ EnableAllLogChannels (lldb::StreamSP &log_stream_sp,
+ uint32_t log_options,
+ const char **categories,
+ Stream *feedback_strm);
+
+ static void
+ DisableAllLogChannels (Stream *feedback_strm);
+
+ static void
+ ListAllLogChannels (Stream *strm);
+
+ static void
+ Initialize ();
+
+ static void
+ Terminate ();
+
+ //------------------------------------------------------------------
+ // Auto completion
+ //------------------------------------------------------------------
+ static void
+ AutoCompleteChannelName (const char *channel_name,
+ StringList &matches);
+
+ //------------------------------------------------------------------
+ // Member functions
+ //------------------------------------------------------------------
+ Log ();
+
+ Log (const lldb::StreamSP &stream_sp);
+
+ ~Log ();
+
+ void
+ PutCString (const char *cstr);
+
+ void
+ Printf (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ VAPrintf (const char *format, va_list args);
+
+ void
+ PrintfWithFlags( uint32_t flags, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
+
+ void
+ LogIf (uint32_t mask, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
+
+ void
+ Debug (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ DebugVerbose (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ Error (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ FatalError (int err, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
+
+ void
+ Verbose (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ Warning (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ WarningVerbose (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
+ Flags &
+ GetOptions();
+
+ const Flags &
+ GetOptions() const;
+
+ Flags &
+ GetMask();
+
+ const Flags &
+ GetMask() const;
+
+ bool
+ GetVerbose() const;
+
+ bool
+ GetDebug() const;
+
+ void
+ SetStream (const lldb::StreamSP &stream_sp)
+ {
+ m_stream_sp = stream_sp;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ lldb::StreamSP m_stream_sp;
+ Flags m_options;
+ Flags m_mask_bits;
+
+ void
+ PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (Log);
+};
+
+
+class LogChannel : public PluginInterface
+{
+public:
+ LogChannel ();
+
+ virtual
+ ~LogChannel ();
+
+ static lldb::LogChannelSP
+ FindPlugin (const char *plugin_name);
+
+ // categories is a an array of chars that ends with a NULL element.
+ virtual void
+ Disable (const char **categories, Stream *feedback_strm) = 0;
+
+ virtual bool
+ Enable (lldb::StreamSP &log_stream_sp,
+ uint32_t log_options,
+ Stream *feedback_strm, // Feedback stream for argument errors etc
+ const char **categories) = 0;// The categories to enable within this logging stream, if empty, enable default set
+
+ virtual void
+ ListCategories (Stream *strm) = 0;
+
+protected:
+ std::unique_ptr<Log> m_log_ap;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (LogChannel);
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_Log_H_
diff --git a/include/lldb/Core/Mangled.h b/include/lldb/Core/Mangled.h
new file mode 100644
index 000000000000..8732dc00270c
--- /dev/null
+++ b/include/lldb/Core/Mangled.h
@@ -0,0 +1,306 @@
+//===-- Mangled.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Mangled_h_
+#define liblldb_Mangled_h_
+#if defined(__cplusplus)
+
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ConstString.h"
+#include <vector>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Mangled Mangled.h "lldb/Core/Mangled.h"
+/// @brief A class that handles mangled names.
+///
+/// Designed to handle mangled names. The demangled version of any names
+/// will be computed when the demangled name is accessed through the
+/// Demangled() acccessor. This class can also tokenize the demangled
+/// version of the name for powerful searches. Functions and symbols
+/// could make instances of this class for their mangled names. Uniqued
+/// string pools are used for the mangled, demangled, and token string
+/// values to allow for faster comparisons and for efficient memory use.
+//----------------------------------------------------------------------
+class Mangled
+{
+public:
+
+ enum NamePreference
+ {
+ ePreferMangled,
+ ePreferDemangled
+ };
+
+ //----------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize with both mangled and demangled names empty.
+ //----------------------------------------------------------------------
+ Mangled ();
+
+ //----------------------------------------------------------------------
+ /// Construct with name.
+ ///
+ /// Constructor with an optional string and a boolean indicating if it is
+ /// the mangled version.
+ ///
+ /// @param[in] name
+ /// The already const name to copy into this object.
+ ///
+ /// @param[in] is_mangled
+ /// If \b true then \a name is a mangled name, if \b false then
+ /// \a name is demangled.
+ //----------------------------------------------------------------------
+ explicit
+ Mangled (const ConstString &name, bool is_mangled);
+
+ //----------------------------------------------------------------------
+ /// Construct with name.
+ ///
+ /// Constructor with an optional string and auto-detect if \a name is
+ /// mangled or not.
+ ///
+ /// @param[in] name
+ /// The already const name to copy into this object.
+ //----------------------------------------------------------------------
+ explicit
+ Mangled (const ConstString &name);
+
+ //----------------------------------------------------------------------
+ /// Destructor
+ ///
+ /// Releases its ref counts on the mangled and demangled strings that
+ /// live in the global string pool.
+ //----------------------------------------------------------------------
+ ~Mangled ();
+
+ //----------------------------------------------------------------------
+ /// Convert to pointer operator.
+ ///
+ /// This allows code to check a Mangled object to see if it contains
+ /// a valid mangled name using code such as:
+ ///
+ /// @code
+ /// Mangled mangled(...);
+ /// if (mangled)
+ /// { ...
+ /// @endcode
+ ///
+ /// @return
+ /// A pointer to this object if either the mangled or unmangled
+ /// name is set, NULL otherwise.
+ //----------------------------------------------------------------------
+ operator
+ void*() const;
+
+ //----------------------------------------------------------------------
+ /// Logical NOT operator.
+ ///
+ /// This allows code to check a Mangled object to see if it contains
+ /// an empty mangled name using code such as:
+ ///
+ /// @code
+ /// Mangled mangled(...);
+ /// if (!mangled)
+ /// { ...
+ /// @endcode
+ ///
+ /// @return
+ /// Returns \b true if the object has an empty mangled and
+ /// unmangled name, \b false otherwise.
+ //----------------------------------------------------------------------
+ bool
+ operator!() const;
+
+ //----------------------------------------------------------------------
+ /// Clear the mangled and demangled values.
+ //----------------------------------------------------------------------
+ void
+ Clear ();
+
+ //----------------------------------------------------------------------
+ /// Compare the mangled string values
+ ///
+ /// Compares the Mangled::GetName() string in \a lhs and \a rhs.
+ ///
+ /// @param[in] lhs
+ /// A const reference to the Left Hand Side object to compare.
+ ///
+ /// @param[in] rhs
+ /// A const reference to the Right Hand Side object to compare.
+ ///
+ /// @return
+ /// @li -1 if \a lhs is less than \a rhs
+ /// @li 0 if \a lhs is equal to \a rhs
+ /// @li 1 if \a lhs is greater than \a rhs
+ //----------------------------------------------------------------------
+ static int
+ Compare (const Mangled& lhs, const Mangled& rhs);
+
+ //----------------------------------------------------------------------
+ /// Dump a description of this object to a Stream \a s.
+ ///
+ /// Dump a Mangled object to stream \a s. We don't force our
+ /// demangled name to be computed currently (we don't use the accessor).
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //----------------------------------------------------------------------
+ void
+ Dump (Stream *s) const;
+
+ //----------------------------------------------------------------------
+ /// Dump a debug description of this object to a Stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //----------------------------------------------------------------------
+ void
+ DumpDebug (Stream *s) const;
+
+ //----------------------------------------------------------------------
+ /// Demangled name get accessor.
+ ///
+ /// @return
+ /// A const reference to the demangled name string object.
+ //----------------------------------------------------------------------
+ const ConstString&
+ GetDemangledName () const;
+
+ void
+ SetDemangledName (const ConstString &name)
+ {
+ m_demangled = name;
+ }
+
+ void
+ SetMangledName (const ConstString &name)
+ {
+ m_mangled = name;
+ }
+
+ //----------------------------------------------------------------------
+ /// Mangled name get accessor.
+ ///
+ /// @return
+ /// A reference to the mangled name string object.
+ //----------------------------------------------------------------------
+ ConstString&
+ GetMangledName ()
+ {
+ return m_mangled;
+ }
+
+ //----------------------------------------------------------------------
+ /// Mangled name get accessor.
+ ///
+ /// @return
+ /// A const reference to the mangled name string object.
+ //----------------------------------------------------------------------
+ const ConstString&
+ GetMangledName () const
+ {
+ return m_mangled;
+ }
+
+ //----------------------------------------------------------------------
+ /// Best name get accessor.
+ ///
+ /// @param[in] preference
+ /// Which name would you prefer to get?
+ ///
+ /// @return
+ /// A const reference to the the preferred name string object if this
+ /// object has a valid name of that kind, else a const reference to the
+ /// other name is returned.
+ //----------------------------------------------------------------------
+ const ConstString&
+ GetName (NamePreference preference = ePreferDemangled) const;
+
+ //----------------------------------------------------------------------
+ /// Check if "name" matches either the mangled or demangled name.
+ ///
+ /// @param[in] name
+ /// A name to match against both strings.
+ ///
+ /// @return
+ /// \b True if \a name matches either name, \b false otherwise.
+ //----------------------------------------------------------------------
+ bool
+ NameMatches (const ConstString &name) const
+ {
+ if (m_mangled == name)
+ return true;
+ return GetDemangledName () == name;
+ }
+
+ bool
+ NameMatches (const RegularExpression& regex) const;
+
+ //----------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// Return the size in bytes that this object takes in memory. This
+ /// returns the size in bytes of this object, not any shared string
+ /// values it may refer to.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //----------------------------------------------------------------------
+ size_t
+ MemorySize () const;
+
+ //----------------------------------------------------------------------
+ /// Set the string value in this object.
+ ///
+ /// If \a is_mangled is \b true, then the mangled named is set to \a
+ /// name, else the demangled name is set to \a name.
+ ///
+ /// @param[in] name
+ /// The already const version of the name for this object.
+ ///
+ /// @param[in] is_mangled
+ /// If \b true then \a name is a mangled name, if \b false then
+ /// \a name is demangled.
+ //----------------------------------------------------------------------
+ void
+ SetValue (const ConstString &name, bool is_mangled);
+
+ //----------------------------------------------------------------------
+ /// Set the string value in this object.
+ ///
+ /// This version auto detects if the string is mangled by inspecting the
+ /// string value and looking for common mangling prefixes.
+ ///
+ /// @param[in] name
+ /// The already const version of the name for this object.
+ //----------------------------------------------------------------------
+ void
+ SetValue (const ConstString &name);
+
+private:
+ //----------------------------------------------------------------------
+ /// Mangled member variables.
+ //----------------------------------------------------------------------
+ ConstString m_mangled; ///< The mangled version of the name
+ mutable ConstString m_demangled; ///< Mutable so we can get it on demand with a const version of this object
+};
+
+
+Stream& operator << (Stream& s, const Mangled& obj);
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_Mangled_h_
diff --git a/include/lldb/Core/MappedHash.h b/include/lldb/Core/MappedHash.h
new file mode 100644
index 000000000000..80d249d4cc9e
--- /dev/null
+++ b/include/lldb/Core/MappedHash.h
@@ -0,0 +1,552 @@
+//
+// MappedHash.h
+//
+
+#ifndef liblldb_MappedHash_h_
+#define liblldb_MappedHash_h_
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <map>
+#include <vector>
+
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Stream.h"
+
+class MappedHash
+{
+public:
+
+ enum HashFunctionType
+ {
+ eHashFunctionDJB = 0u // Daniel J Bernstein hash function that is also used by the ELF GNU_HASH sections
+ };
+
+
+ static uint32_t
+ HashStringUsingDJB (const char *s)
+ {
+ uint32_t h = 5381;
+
+ for (unsigned char c = *s; c; c = *++s)
+ h = ((h << 5) + h) + c;
+
+ return h;
+ }
+
+ static uint32_t
+ HashString (uint32_t hash_function, const char *s)
+ {
+ switch (hash_function)
+ {
+ case MappedHash::eHashFunctionDJB:
+ return HashStringUsingDJB (s);
+
+ default:
+ break;
+ }
+ assert (!"Invalid hash function index");
+ return 0;
+ }
+
+
+ static const uint32_t HASH_MAGIC = 0x48415348u;
+ static const uint32_t HASH_CIGAM = 0x48534148u;
+
+ template <typename T>
+ struct Header
+ {
+ typedef T HeaderData;
+
+ uint32_t magic; // HASH_MAGIC or HASH_CIGAM magic value to allow endian detection
+ uint16_t version; // Version number
+ uint16_t hash_function; // The hash function enumeration that was used
+ uint32_t bucket_count; // The number of buckets in this hash table
+ uint32_t hashes_count; // The total number of unique hash values and hash data offsets in this table
+ uint32_t header_data_len; // The size in bytes of the "header_data" template member below
+ HeaderData header_data; //
+
+ Header () :
+ magic (HASH_MAGIC),
+ version (1),
+ hash_function (eHashFunctionDJB),
+ bucket_count (0),
+ hashes_count (0),
+ header_data_len (sizeof(T)),
+ header_data ()
+ {
+ }
+
+ virtual
+ ~Header()
+ {
+ }
+
+ size_t
+ GetByteSize() const
+ {
+ return sizeof(magic) +
+ sizeof(version) +
+ sizeof(hash_function) +
+ sizeof(bucket_count) +
+ sizeof(hashes_count) +
+ sizeof(header_data_len) +
+ header_data_len;
+ }
+
+ virtual size_t
+ GetByteSize (const HeaderData &header_data) = 0;
+
+ void
+ SetHeaderDataByteSize (uint32_t header_data_byte_size)
+ {
+ header_data_len = header_data_byte_size;
+ }
+
+ void
+ Dump (lldb_private::Stream &s)
+ {
+ s.Printf ("header.magic = 0x%8.8x\n", magic);
+ s.Printf ("header.version = 0x%4.4x\n", version);
+ s.Printf ("header.hash_function = 0x%4.4x\n", hash_function);
+ s.Printf ("header.bucket_count = 0x%8.8x %u\n", bucket_count, bucket_count);
+ s.Printf ("header.hashes_count = 0x%8.8x %u\n", hashes_count, hashes_count);
+ s.Printf ("header.header_data_len = 0x%8.8x %u\n", header_data_len, header_data_len);
+ }
+
+ virtual lldb::offset_t
+ Read (lldb_private::DataExtractor &data, lldb::offset_t offset)
+ {
+ if (data.ValidOffsetForDataOfSize (offset,
+ sizeof (magic) +
+ sizeof (version) +
+ sizeof (hash_function) +
+ sizeof (bucket_count) +
+ sizeof (hashes_count) +
+ sizeof (header_data_len)))
+ {
+ magic = data.GetU32 (&offset);
+ if (magic != HASH_MAGIC)
+ {
+ if (magic == HASH_CIGAM)
+ {
+ switch (data.GetByteOrder())
+ {
+ case lldb::eByteOrderBig:
+ data.SetByteOrder(lldb::eByteOrderLittle);
+ break;
+ case lldb::eByteOrderLittle:
+ data.SetByteOrder(lldb::eByteOrderBig);
+ break;
+ default:
+ return LLDB_INVALID_OFFSET;
+ }
+ }
+ else
+ {
+ // Magic bytes didn't match
+ version = 0;
+ return LLDB_INVALID_OFFSET;
+ }
+ }
+
+ version = data.GetU16 (&offset);
+ if (version != 1)
+ {
+ // Unsupported version
+ return LLDB_INVALID_OFFSET;
+ }
+ hash_function = data.GetU16 (&offset);
+ if (hash_function == 4)
+ hash_function = 0; // Deal with pre-release version of this table...
+ bucket_count = data.GetU32 (&offset);
+ hashes_count = data.GetU32 (&offset);
+ header_data_len = data.GetU32 (&offset);
+ return offset;
+ }
+ return LLDB_INVALID_OFFSET;
+ }
+//
+// // Returns a buffer that contains a serialized version of this table
+// // that must be freed with free().
+// virtual void *
+// Write (int fd);
+ };
+
+ template <typename __KeyType, class __HeaderDataType, class __ValueType>
+ class ExportTable
+ {
+ public:
+ typedef __HeaderDataType HeaderDataType;
+ typedef Header<HeaderDataType> HeaderType;
+ typedef __KeyType KeyType;
+ typedef __ValueType ValueType;
+
+ struct Entry
+ {
+ uint32_t hash;
+ KeyType key;
+ ValueType value;
+ };
+
+ typedef std::vector<ValueType> ValueArrayType;
+
+ typedef std::map<KeyType, ValueArrayType> HashData;
+ // Map a name hash to one or more name infos
+ typedef std::map<uint32_t, HashData> HashToHashData;
+
+ virtual KeyType
+ GetKeyForStringType (const char *cstr) const = 0;
+
+ virtual size_t
+ GetByteSize (const HashData &key_to_key_values) = 0;
+
+ virtual bool
+ WriteHashData (const HashData &hash_data,
+ lldb_private::Stream &ostrm) = 0;
+//
+ void
+ AddEntry (const char *cstr, const ValueType &value)
+ {
+ Entry entry;
+ entry.hash = MappedHash::HashString (eHashFunctionDJB, cstr);
+ entry.key = GetKeyForStringType (cstr);
+ entry.value = value;
+ m_entries.push_back (entry);
+ }
+
+ void
+ Save (const HeaderDataType &header_data,
+ lldb_private::Stream &ostrm)
+ {
+ if (m_entries.empty())
+ return;
+
+ const uint32_t num_entries = m_entries.size();
+ uint32_t i = 0;
+
+ HeaderType header;
+
+ header.magic = HASH_MAGIC;
+ header.version = 1;
+ header.hash_function = eHashFunctionDJB;
+ header.bucket_count = 0;
+ header.hashes_count = 0;
+ header.prologue_length = header_data.GetByteSize();
+
+ // We need to figure out the number of unique hashes first before we can
+ // calculate the number of buckets we want to use.
+ typedef std::vector<uint32_t> hash_coll;
+ hash_coll unique_hashes;
+ unique_hashes.resize (num_entries);
+ for (i=0; i<num_entries; ++i)
+ unique_hashes[i] = m_entries[i].hash;
+ std::sort (unique_hashes.begin(), unique_hashes.end());
+ hash_coll::iterator pos = std::unique (unique_hashes.begin(), unique_hashes.end());
+ const size_t num_unique_hashes = std::distance (unique_hashes.begin(), pos);
+
+ if (num_unique_hashes > 1024)
+ header.bucket_count = num_unique_hashes/4;
+ else if (num_unique_hashes > 16)
+ header.bucket_count = num_unique_hashes/2;
+ else
+ header.bucket_count = num_unique_hashes;
+ if (header.bucket_count == 0)
+ header.bucket_count = 1;
+
+
+ std::vector<HashToHashData> hash_buckets;
+ std::vector<uint32_t> hash_indexes (header.bucket_count, 0);
+ std::vector<uint32_t> hash_values;
+ std::vector<uint32_t> hash_offsets;
+ hash_buckets.resize (header.bucket_count);
+ uint32_t bucket_entry_empties = 0;
+ //StreamString hash_file_data(Stream::eBinary, dwarf->GetObjectFile()->GetAddressByteSize(), dwarf->GetObjectFile()->GetByteSize());
+
+ // Push all of the hashes into their buckets and create all bucket
+ // entries all populated with data.
+ for (i=0; i<num_entries; ++i)
+ {
+ const uint32_t hash = m_entries[i].hash;
+ const uint32_t bucket_idx = hash % header.bucket_count;
+ const uint32_t strp_offset = m_entries[i].str_offset;
+ const uint32_t die_offset = m_entries[i].die_offset;
+ hash_buckets[bucket_idx][hash][strp_offset].push_back(die_offset);
+ }
+
+ // Now for each bucket we write the bucket value which is the
+ // number of hashes and the hash index encoded into a single
+ // 32 bit unsigned integer.
+ for (i=0; i<header.bucket_count; ++i)
+ {
+ HashToHashData &bucket_entry = hash_buckets[i];
+
+ if (bucket_entry.empty())
+ {
+ // Empty bucket
+ ++bucket_entry_empties;
+ hash_indexes[i] = UINT32_MAX;
+ }
+ else
+ {
+ const uint32_t hash_value_index = hash_values.size();
+ uint32_t hash_count = 0;
+ typename HashToHashData::const_iterator pos, end = bucket_entry.end();
+ for (pos = bucket_entry.begin(); pos != end; ++pos)
+ {
+ hash_values.push_back (pos->first);
+ hash_offsets.push_back (GetByteSize (pos->second));
+ ++hash_count;
+ }
+
+ hash_indexes[i] = hash_value_index;
+ }
+ }
+ header.hashes_count = hash_values.size();
+
+ // Write the header out now that we have the hash_count
+ header.Write (ostrm);
+
+ // Now for each bucket we write the start index of the hashes
+ // for the current bucket, or UINT32_MAX if the bucket is empty
+ for (i=0; i<header.bucket_count; ++i)
+ {
+ ostrm.PutHex32(hash_indexes[i]);
+ }
+
+ // Now we need to write out all of the hash values
+ for (i=0; i<header.hashes_count; ++i)
+ {
+ ostrm.PutHex32(hash_values[i]);
+ }
+
+ // Now we need to write out all of the hash data offsets,
+ // there is an offset for each hash in the hashes array
+ // that was written out above
+ for (i=0; i<header.hashes_count; ++i)
+ {
+ ostrm.PutHex32(hash_offsets[i]);
+ }
+
+ // Now we write the data for each hash and verify we got the offset
+ // correct above...
+ for (i=0; i<header.bucket_count; ++i)
+ {
+ HashToHashData &bucket_entry = hash_buckets[i];
+
+ typename HashToHashData::const_iterator pos, end = bucket_entry.end();
+ for (pos = bucket_entry.begin(); pos != end; ++pos)
+ {
+ if (!bucket_entry.empty())
+ {
+ WriteHashData (pos->second);
+ }
+ }
+ }
+ }
+ protected:
+ typedef std::vector<Entry> collection;
+ collection m_entries;
+ };
+ // A class for reading and using a saved hash table from a block of data
+ // in memory
+ template <typename __KeyType, class __HeaderType, class __HashData>
+ class MemoryTable
+ {
+ public:
+ typedef __HeaderType HeaderType;
+ typedef __KeyType KeyType;
+ typedef __HashData HashData;
+
+ enum Result
+ {
+ eResultKeyMatch = 0u, // The entry was found, key matched and "pair" was filled in successfully
+ eResultKeyMismatch = 1u, // Bucket hash data collision, but key didn't match
+ eResultEndOfHashData = 2u, // The chain of items for this hash data in this bucket is terminated, search no more
+ eResultError = 3u // Error parsing the hash data, abort
+ };
+
+ struct Pair
+ {
+ KeyType key;
+ HashData value;
+ };
+
+ MemoryTable (lldb_private::DataExtractor &data) :
+ m_header (),
+ m_hash_indexes (NULL),
+ m_hash_values (NULL),
+ m_hash_offsets (NULL)
+ {
+ lldb::offset_t offset = m_header.Read (data, 0);
+ if (offset != LLDB_INVALID_OFFSET && IsValid ())
+ {
+ m_hash_indexes = (uint32_t *)data.GetData (&offset, m_header.bucket_count * sizeof(uint32_t));
+ m_hash_values = (uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t));
+ m_hash_offsets = (uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t));
+ }
+ }
+
+ virtual
+ ~MemoryTable ()
+ {
+ }
+
+ bool
+ IsValid () const
+ {
+ return m_header.version == 1 &&
+ m_header.hash_function == eHashFunctionDJB &&
+ m_header.bucket_count > 0 &&
+ m_header.hashes_count > 0;
+ }
+
+ uint32_t
+ GetHashIndex (uint32_t bucket_idx) const
+ {
+ if (m_hash_indexes && bucket_idx < m_header.bucket_count)
+ return m_hash_indexes[bucket_idx];
+ return UINT32_MAX;
+ }
+
+ uint32_t
+ GetHashValue (uint32_t hash_idx) const
+ {
+ if (m_hash_values && hash_idx < m_header.hashes_count)
+ return m_hash_values[hash_idx];
+ return UINT32_MAX;
+ }
+
+ uint32_t
+ GetHashDataOffset (uint32_t hash_idx) const
+ {
+ if (m_hash_offsets && hash_idx < m_header.hashes_count)
+ return m_hash_offsets[hash_idx];
+ return UINT32_MAX;
+ }
+
+ bool
+ Find (const char *name, Pair &pair) const
+ {
+ if (IsValid ())
+ {
+ const uint32_t bucket_count = m_header.bucket_count;
+ const uint32_t hash_count = m_header.hashes_count;
+ const uint32_t hash_value = MappedHash::HashString (m_header.hash_function, name);
+ const uint32_t bucket_idx = hash_value % bucket_count;
+ uint32_t hash_idx = GetHashIndex (bucket_idx);
+ if (hash_idx < hash_count)
+ {
+ for (; hash_idx < hash_count; ++hash_idx)
+ {
+ const uint32_t curr_hash_value = GetHashValue (hash_idx);
+ if (curr_hash_value == hash_value)
+ {
+ lldb::offset_t hash_data_offset = GetHashDataOffset (hash_idx);
+ while (hash_data_offset != UINT32_MAX)
+ {
+ const lldb::offset_t prev_hash_data_offset = hash_data_offset;
+ Result hash_result = GetHashDataForName (name, &hash_data_offset, pair);
+ // Check the result of getting our hash data
+ switch (hash_result)
+ {
+ case eResultKeyMatch:
+ return true;
+
+ case eResultKeyMismatch:
+ if (prev_hash_data_offset == hash_data_offset)
+ return false;
+ break;
+
+ case eResultEndOfHashData:
+ // The last HashData for this key has been reached, stop searching
+ return false;
+ case eResultError:
+ // Error parsing the hash data, abort
+ return false;
+ }
+ }
+ }
+ if ((curr_hash_value % bucket_count) != bucket_idx)
+ break;
+ }
+ }
+ }
+ return false;
+ }
+
+ // This method must be implemented in any subclasses.
+ // The KeyType is user specified and must somehow result in a string
+ // value. For example, the KeyType might be a string offset in a string
+ // table and subclasses can store their string table as a member of the
+ // subclass and return a valie "const char *" given a "key". The value
+ // could also be a C string pointer, in which case just returning "key"
+ // will suffice.
+
+ virtual const char *
+ GetStringForKeyType (KeyType key) const = 0;
+
+ virtual bool
+ ReadHashData (uint32_t hash_data_offset,
+ HashData &hash_data) const = 0;
+
+ // This method must be implemented in any subclasses and it must try to
+ // read one "Pair" at the offset pointed to by the "hash_data_offset_ptr"
+ // parameter. This offset should be updated as bytes are consumed and
+ // a value "Result" enum should be returned. If the "name" matches the
+ // full name for the "pair.key" (which must be filled in by this call),
+ // then the HashData in the pair ("pair.value") should be extracted and
+ // filled in and "eResultKeyMatch" should be returned. If "name" doesn't
+ // match this string for the key, then "eResultKeyMismatch" should be
+ // returned and all data for the current HashData must be consumed or
+ // skipped and the "hash_data_offset_ptr" offset needs to be updated to
+ // point to the next HashData. If the end of the HashData objects for
+ // a given hash value have been reached, then "eResultEndOfHashData"
+ // should be returned. If anything else goes wrong during parsing,
+ // return "eResultError" and the corresponding "Find()" function will
+ // be canceled and return false.
+
+ virtual Result
+ GetHashDataForName (const char *name,
+ lldb::offset_t* hash_data_offset_ptr,
+ Pair &pair) const = 0;
+
+ const HeaderType &
+ GetHeader()
+ {
+ return m_header;
+ }
+
+
+ void
+ ForEach (std::function <bool(const HashData &hash_data)> const &callback) const
+ {
+ const size_t num_hash_offsets = m_header.hashes_count;
+ for (size_t i=0; i<num_hash_offsets; ++i)
+ {
+ uint32_t hash_data_offset = GetHashDataOffset (i);
+ if (hash_data_offset != UINT32_MAX)
+ {
+ HashData hash_data;
+ if (ReadHashData (hash_data_offset, hash_data))
+ {
+ // If the callback returns false, then we are done and should stop
+ if (callback(hash_data) == false)
+ return;
+ }
+ }
+ }
+ }
+
+ protected:
+ // Implementation agnostic information
+ HeaderType m_header;
+ uint32_t *m_hash_indexes;
+ uint32_t *m_hash_values;
+ uint32_t *m_hash_offsets;
+ };
+
+};
+
+#endif // #ifndef liblldb_MappedHash_h_
diff --git a/include/lldb/Core/Module.h b/include/lldb/Core/Module.h
new file mode 100644
index 000000000000..9c135529f453
--- /dev/null
+++ b/include/lldb/Core/Module.h
@@ -0,0 +1,1085 @@
+//===-- Module.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Module_h_
+#define liblldb_Module_h_
+
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Host/TimeValue.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/SymbolContextScope.h"
+#include "lldb/Target/PathMappingList.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Module Module.h "lldb/Core/Module.h"
+/// @brief A class that describes an executable image and its associated
+/// object and symbol files.
+///
+/// The module is designed to be able to select a single slice of an
+/// executable image as it would appear on disk and during program
+/// execution.
+///
+/// Modules control when and if information is parsed according to which
+/// accessors are called. For example the object file (ObjectFile)
+/// representation will only be parsed if the object file is requested
+/// using the Module::GetObjectFile() is called. The debug symbols
+/// will only be parsed if the symbol vendor (SymbolVendor) is
+/// requested using the Module::GetSymbolVendor() is called.
+///
+/// The module will parse more detailed information as more queries are
+/// made.
+//----------------------------------------------------------------------
+class Module :
+ public std::enable_shared_from_this<Module>,
+ public SymbolContextScope
+{
+public:
+ // Static functions that can track the lifetime of module objects.
+ // This is handy because we might have Module objects that are in
+ // shared pointers that aren't in the global module list (from
+ // ModuleList). If this is the case we need to know about it.
+ // The modules in the global list maintained by these functions
+ // can be viewed using the "target modules list" command using the
+ // "--global" (-g for short).
+ static size_t
+ GetNumberAllocatedModules ();
+
+ static Module *
+ GetAllocatedModuleAtIndex (size_t idx);
+
+ static Mutex *
+ GetAllocationModuleCollectionMutex();
+
+ //------------------------------------------------------------------
+ /// Construct with file specification and architecture.
+ ///
+ /// Clients that wish to share modules with other targets should
+ /// use ModuleList::GetSharedModule().
+ ///
+ /// @param[in] file_spec
+ /// The file specification for the on disk repesentation of
+ /// this executable image.
+ ///
+ /// @param[in] arch
+ /// The architecture to set as the current architecture in
+ /// this module.
+ ///
+ /// @param[in] object_name
+ /// The name of an object in a module used to extract a module
+ /// within a module (.a files and modules that contain multiple
+ /// architectures).
+ ///
+ /// @param[in] object_offset
+ /// The offset within an existing module used to extract a
+ /// module within a module (.a files and modules that contain
+ /// multiple architectures).
+ //------------------------------------------------------------------
+ Module (const FileSpec& file_spec,
+ const ArchSpec& arch,
+ const ConstString *object_name = NULL,
+ off_t object_offset = 0,
+ const TimeValue *object_mod_time_ptr = NULL);
+
+ Module (const ModuleSpec &module_spec);
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ virtual
+ ~Module ();
+
+ bool
+ MatchesModuleSpec (const ModuleSpec &module_ref);
+
+ //------------------------------------------------------------------
+ /// Set the load address for all sections in a module to be the
+ /// file address plus \a slide.
+ ///
+ /// Many times a module will be loaded in a target with a constant
+ /// offset applied to all top level sections. This function can
+ /// set the load address for all top level sections to be the
+ /// section file address + offset.
+ ///
+ /// @param[in] target
+ /// The target in which to apply the section load addresses.
+ ///
+ /// @param[in] offset
+ /// The offset to apply to all file addresses for all top
+ /// level sections in the object file as each section load
+ /// address is being set.
+ ///
+ /// @param[out] changed
+ /// If any section load addresses were changed in \a target,
+ /// then \a changed will be set to \b true. Else \a changed
+ /// will be set to false. This allows this function to be
+ /// called multiple times on the same module for the same
+ /// target. If the module hasn't moved, then \a changed will
+ /// be false and no module updated notification will need to
+ /// be sent out.
+ ///
+ /// @return
+ /// /b True if any sections were successfully loaded in \a target,
+ /// /b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ SetLoadAddress (Target &target,
+ lldb::addr_t offset,
+ bool &changed);
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext (SymbolContext* sc);
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ();
+
+ void
+ GetDescription (Stream *s,
+ lldb::DescriptionLevel level = lldb::eDescriptionLevelFull);
+
+ //------------------------------------------------------------------
+ /// Get the module path and object name.
+ ///
+ /// Modules can refer to object files. In this case the specification
+ /// is simple and would return the path to the file:
+ ///
+ /// "/usr/lib/foo.dylib"
+ ///
+ /// Modules can be .o files inside of a BSD archive (.a file). In
+ /// this case, the object specification will look like:
+ ///
+ /// "/usr/lib/foo.a(bar.o)"
+ ///
+ /// There are many places where logging wants to log this fully
+ /// qualified specification, so we centralize this functionality
+ /// here.
+ ///
+ /// @return
+ /// The object path + object name if there is one.
+ //------------------------------------------------------------------
+ std::string
+ GetSpecificationDescription () const;
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s. The dumped content will be only what has
+ /// been loaded or parsed up to this point at which this function
+ /// is called, so this is a good way to see what has been parsed
+ /// in a module.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s);
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext (Stream *s);
+
+
+ //------------------------------------------------------------------
+ /// Find a symbol in the object file's symbol table.
+ ///
+ /// @param[in] name
+ /// The name of the symbol that we are looking for.
+ ///
+ /// @param[in] symbol_type
+ /// If set to eSymbolTypeAny, find a symbol of any type that
+ /// has a name that matches \a name. If set to any other valid
+ /// SymbolType enumeration value, then search only for
+ /// symbols that match \a symbol_type.
+ ///
+ /// @return
+ /// Returns a valid symbol pointer if a symbol was found,
+ /// NULL otherwise.
+ //------------------------------------------------------------------
+ const Symbol *
+ FindFirstSymbolWithNameAndType (const ConstString &name,
+ lldb::SymbolType symbol_type = lldb::eSymbolTypeAny);
+
+ size_t
+ FindSymbolsWithNameAndType (const ConstString &name,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list);
+
+ size_t
+ FindSymbolsMatchingRegExAndType (const RegularExpression &regex,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list);
+
+ //------------------------------------------------------------------
+ /// Find a funciton symbols in the object file's symbol table.
+ ///
+ /// @param[in] name
+ /// The name of the symbol that we are looking for.
+ ///
+ /// @param[in] name_type_mask
+ /// A mask that has one or more bitwise OR'ed values from the
+ /// lldb::FunctionNameType enumeration type that indicate what
+ /// kind of names we are looking for.
+ ///
+ /// @param[out] sc_list
+ /// A list to append any matching symbol contexts to.
+ ///
+ /// @return
+ /// The number of symbol contexts that were added to \a sc_list
+ //------------------------------------------------------------------
+ size_t
+ FindFunctionSymbols (const ConstString &name,
+ uint32_t name_type_mask,
+ SymbolContextList& sc_list);
+
+ //------------------------------------------------------------------
+ /// Find compile units by partial or full path.
+ ///
+ /// Finds all compile units that match \a path in all of the modules
+ /// and returns the results in \a sc_list.
+ ///
+ /// @param[in] path
+ /// The name of the function we are looking for.
+ ///
+ /// @param[in] append
+ /// If \b true, then append any compile units that were found
+ /// to \a sc_list. If \b false, then the \a sc_list is cleared
+ /// and the contents of \a sc_list are replaced.
+ ///
+ /// @param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ ///
+ /// @return
+ /// The number of matches added to \a sc_list.
+ //------------------------------------------------------------------
+ size_t
+ FindCompileUnits (const FileSpec &path,
+ bool append,
+ SymbolContextList &sc_list);
+
+
+ //------------------------------------------------------------------
+ /// Find functions by name.
+ ///
+ /// If the function is an inlined function, it will have a block,
+ /// representing the inlined function, and the function will be the
+ /// containing function. If it is not inlined, then the block will
+ /// be NULL.
+ ///
+ /// @param[in] name
+ /// The name of the compile unit we are looking for.
+ ///
+ /// @param[in] namespace_decl
+ /// If valid, a namespace to search in.
+ ///
+ /// @param[in] name_type_mask
+ /// A bit mask of bits that indicate what kind of names should
+ /// be used when doing the lookup. Bits include fully qualified
+ /// names, base names, C++ methods, or ObjC selectors.
+ /// See FunctionNameType for more details.
+ ///
+ /// @param[in] append
+ /// If \b true, any matches will be appended to \a sc_list, else
+ /// matches replace the contents of \a sc_list.
+ ///
+ /// @param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ ///
+ /// @return
+ /// The number of matches added to \a sc_list.
+ //------------------------------------------------------------------
+ size_t
+ FindFunctions (const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ uint32_t name_type_mask,
+ bool symbols_ok,
+ bool inlines_ok,
+ bool append,
+ SymbolContextList& sc_list);
+
+ //------------------------------------------------------------------
+ /// Find functions by name.
+ ///
+ /// If the function is an inlined function, it will have a block,
+ /// representing the inlined function, and the function will be the
+ /// containing function. If it is not inlined, then the block will
+ /// be NULL.
+ ///
+ /// @param[in] regex
+ /// A regular expression to use when matching the name.
+ ///
+ /// @param[in] append
+ /// If \b true, any matches will be appended to \a sc_list, else
+ /// matches replace the contents of \a sc_list.
+ ///
+ /// @param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ ///
+ /// @return
+ /// The number of matches added to \a sc_list.
+ //------------------------------------------------------------------
+ size_t
+ FindFunctions (const RegularExpression& regex,
+ bool symbols_ok,
+ bool inlines_ok,
+ bool append,
+ SymbolContextList& sc_list);
+
+ //------------------------------------------------------------------
+ /// Find global and static variables by name.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @param[in] namespace_decl
+ /// If valid, a namespace to search in.
+ ///
+ /// @param[in] append
+ /// If \b true, any matches will be appended to \a
+ /// variable_list, else matches replace the contents of
+ /// \a variable_list.
+ ///
+ /// @param[in] max_matches
+ /// Allow the number of matches to be limited to \a
+ /// max_matches. Specify UINT32_MAX to get all possible matches.
+ ///
+ /// @param[in] variable_list
+ /// A list of variables that gets the matches appended to (if
+ /// \a append it \b true), or replace (if \a append is \b false).
+ ///
+ /// @return
+ /// The number of matches added to \a variable_list.
+ //------------------------------------------------------------------
+ size_t
+ FindGlobalVariables (const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ bool append,
+ size_t max_matches,
+ VariableList& variable_list);
+
+ //------------------------------------------------------------------
+ /// Find global and static variables by regular exression.
+ ///
+ /// @param[in] regex
+ /// A regular expression to use when matching the name.
+ ///
+ /// @param[in] append
+ /// If \b true, any matches will be appended to \a
+ /// variable_list, else matches replace the contents of
+ /// \a variable_list.
+ ///
+ /// @param[in] max_matches
+ /// Allow the number of matches to be limited to \a
+ /// max_matches. Specify UINT32_MAX to get all possible matches.
+ ///
+ /// @param[in] variable_list
+ /// A list of variables that gets the matches appended to (if
+ /// \a append it \b true), or replace (if \a append is \b false).
+ ///
+ /// @return
+ /// The number of matches added to \a variable_list.
+ //------------------------------------------------------------------
+ size_t
+ FindGlobalVariables (const RegularExpression& regex,
+ bool append,
+ size_t max_matches,
+ VariableList& variable_list);
+
+ //------------------------------------------------------------------
+ /// Find types by name.
+ ///
+ /// Type lookups in modules go through the SymbolVendor (which will
+ /// use one or more SymbolFile subclasses). The SymbolFile needs to
+ /// be able to lookup types by basename and not the fully qualified
+ /// typename. This allows the type accelerator tables to stay small,
+ /// even with heavily templatized C++. The type search will then
+ /// narrow down the search results. If "exact_match" is true, then
+ /// the type search will only match exact type name matches. If
+ /// "exact_match" is false, the type will match as long as the base
+ /// typename matches and as long as any immediate containing
+ /// namespaces/class scopes that are specified match. So to search
+ /// for a type "d" in "b::c", the name "b::c::d" can be specified
+ /// and it will match any class/namespace "b" which contains a
+ /// class/namespace "c" which contains type "d". We do this to
+ /// allow users to not always have to specify complete scoping on
+ /// all expressions, but it also allows for exact matching when
+ /// required.
+ ///
+ /// @param[in] sc
+ /// A symbol context that scopes where to extract a type list
+ /// from.
+ ///
+ /// @param[in] type_name
+ /// The name of the type we are looking for that is a fully
+ /// or partially qualfieid type name.
+ ///
+ /// @param[in] exact_match
+ /// If \b true, \a type_name is fully qualifed and must match
+ /// exactly. If \b false, \a type_name is a partially qualfied
+ /// name where the leading namespaces or classes can be
+ /// omitted to make finding types that a user may type
+ /// easier.
+ ///
+ /// @param[out] type_list
+ /// A type list gets populated with any matches.
+ ///
+ /// @return
+ /// The number of matches added to \a type_list.
+ //------------------------------------------------------------------
+ size_t
+ FindTypes (const SymbolContext& sc,
+ const ConstString &type_name,
+ bool exact_match,
+ size_t max_matches,
+ TypeList& types);
+
+ lldb::TypeSP
+ FindFirstType (const SymbolContext& sc,
+ const ConstString &type_name,
+ bool exact_match);
+
+ //------------------------------------------------------------------
+ /// Find types by name that are in a namespace. This function is
+ /// used by the expression parser when searches need to happen in
+ /// an exact namespace scope.
+ ///
+ /// @param[in] sc
+ /// A symbol context that scopes where to extract a type list
+ /// from.
+ ///
+ /// @param[in] type_name
+ /// The name of a type within a namespace that should not include
+ /// any qualifying namespaces (just a type basename).
+ ///
+ /// @param[in] namespace_decl
+ /// The namespace declaration that this type must exist in.
+ ///
+ /// @param[out] type_list
+ /// A type list gets populated with any matches.
+ ///
+ /// @return
+ /// The number of matches added to \a type_list.
+ //------------------------------------------------------------------
+ size_t
+ FindTypesInNamespace (const SymbolContext& sc,
+ const ConstString &type_name,
+ const ClangNamespaceDecl *namespace_decl,
+ size_t max_matches,
+ TypeList& type_list);
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the module architecture.
+ ///
+ /// @return
+ /// A const reference to the architecture object.
+ //------------------------------------------------------------------
+ const ArchSpec&
+ GetArchitecture () const;
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the module file specification.
+ ///
+ /// This function returns the file for the module on the host system
+ /// that is running LLDB. This can differ from the path on the
+ /// platform since we might be doing remote debugging.
+ ///
+ /// @return
+ /// A const reference to the file specification object.
+ //------------------------------------------------------------------
+ const FileSpec &
+ GetFileSpec () const
+ {
+ return m_file;
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor for the module platform file specification.
+ ///
+ /// Platform file refers to the path of the module as it is known on
+ /// the remote system on which it is being debugged. For local
+ /// debugging this is always the same as Module::GetFileSpec(). But
+ /// remote debugging might mention a file "/usr/lib/liba.dylib"
+ /// which might be locally downloaded and cached. In this case the
+ /// platform file could be something like:
+ /// "/tmp/lldb/platform-cache/remote.host.computer/usr/lib/liba.dylib"
+ /// The file could also be cached in a local developer kit directory.
+ ///
+ /// @return
+ /// A const reference to the file specification object.
+ //------------------------------------------------------------------
+ const FileSpec &
+ GetPlatformFileSpec () const
+ {
+ if (m_platform_file)
+ return m_platform_file;
+ return m_file;
+ }
+
+ void
+ SetPlatformFileSpec (const FileSpec &file)
+ {
+ m_platform_file = file;
+ }
+
+ const FileSpec &
+ GetSymbolFileFileSpec () const
+ {
+ return m_symfile_spec;
+ }
+
+ void
+ SetSymbolFileFileSpec (const FileSpec &file);
+
+ const TimeValue &
+ GetModificationTime () const
+ {
+ return m_mod_time;
+ }
+
+ const TimeValue &
+ GetObjectModificationTime () const
+ {
+ return m_object_mod_time;
+ }
+
+ void
+ SetObjectModificationTime (const TimeValue &mod_time)
+ {
+ m_mod_time = mod_time;
+ }
+
+ //------------------------------------------------------------------
+ /// Tells whether this module is capable of being the main executable
+ /// for a process.
+ ///
+ /// @return
+ /// \b true if it is, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsExecutable ();
+
+ //------------------------------------------------------------------
+ /// Tells whether this module has been loaded in the target passed in.
+ /// This call doesn't distinguish between whether the module is loaded
+ /// by the dynamic loader, or by a "target module add" type call.
+ ///
+ /// @param[in] target
+ /// The target to check whether this is loaded in.
+ ///
+ /// @return
+ /// \b true if it is, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsLoadedInTarget (Target *target);
+
+ bool
+ LoadScriptingResourceInTarget (Target *target,
+ Error& error,
+ Stream* feedback_stream = NULL);
+
+ //------------------------------------------------------------------
+ /// Get the number of compile units for this module.
+ ///
+ /// @return
+ /// The number of compile units that the symbol vendor plug-in
+ /// finds.
+ //------------------------------------------------------------------
+ size_t
+ GetNumCompileUnits();
+
+ lldb::CompUnitSP
+ GetCompileUnitAtIndex (size_t idx);
+
+ const ConstString &
+ GetObjectName() const;
+
+ uint64_t
+ GetObjectOffset() const
+ {
+ return m_object_offset;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the object file representation for the current architecture.
+ ///
+ /// If the object file has not been located or parsed yet, this
+ /// function will find the best ObjectFile plug-in that can parse
+ /// Module::m_file.
+ ///
+ /// @return
+ /// If Module::m_file does not exist, or no plug-in was found
+ /// that can parse the file, or the object file doesn't contain
+ /// the current architecture in Module::m_arch, NULL will be
+ /// returned, else a valid object file interface will be
+ /// returned. The returned pointer is owned by this object and
+ /// remains valid as long as the object is around.
+ //------------------------------------------------------------------
+ virtual ObjectFile *
+ GetObjectFile ();
+
+ //------------------------------------------------------------------
+ /// Get the unified section list for the module. This is the section
+ /// list created by the module's object file and any debug info and
+ /// symbol files created by the symbol vendor.
+ ///
+ /// If the symbol vendor has not been loaded yet, this function
+ /// will return the section list for the object file.
+ ///
+ /// @return
+ /// Unified module section list.
+ //------------------------------------------------------------------
+ virtual SectionList *
+ GetSectionList ();
+
+ uint32_t
+ GetVersion (uint32_t *versions, uint32_t num_versions);
+
+ // Load an object file from memory.
+ ObjectFile *
+ GetMemoryObjectFile (const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr,
+ Error &error);
+ //------------------------------------------------------------------
+ /// Get the symbol vendor interface for the current architecture.
+ ///
+ /// If the symbol vendor file has not been located yet, this
+ /// function will find the best SymbolVendor plug-in that can
+ /// use the current object file.
+ ///
+ /// @return
+ /// If this module does not have a valid object file, or no
+ /// plug-in can be found that can use the object file, NULL will
+ /// be returned, else a valid symbol vendor plug-in interface
+ /// will be returned. The returned pointer is owned by this
+ /// object and remains valid as long as the object is around.
+ //------------------------------------------------------------------
+ virtual SymbolVendor*
+ GetSymbolVendor(bool can_create = true,
+ lldb_private::Stream *feedback_strm = NULL);
+
+ //------------------------------------------------------------------
+ /// Get accessor the type list for this module.
+ ///
+ /// @return
+ /// A valid type list pointer, or NULL if there is no valid
+ /// symbol vendor for this module.
+ //------------------------------------------------------------------
+ TypeList*
+ GetTypeList ();
+
+ //------------------------------------------------------------------
+ /// Get a pointer to the UUID value contained in this object.
+ ///
+ /// If the executable image file doesn't not have a UUID value built
+ /// into the file format, an MD5 checksum of the entire file, or
+ /// slice of the file for the current architecture should be used.
+ ///
+ /// @return
+ /// A const pointer to the internal copy of the UUID value in
+ /// this module if this module has a valid UUID value, NULL
+ /// otherwise.
+ //------------------------------------------------------------------
+ const lldb_private::UUID &
+ GetUUID ();
+
+ //------------------------------------------------------------------
+ /// A debugging function that will cause everything in a module to
+ /// be parsed.
+ ///
+ /// All compile units will be pasred, along with all globals and
+ /// static variables and all functions for those compile units.
+ /// All types, scopes, local variables, static variables, global
+ /// variables, and line tables will be parsed. This can be used
+ /// prior to dumping a module to see a complete list of the
+ /// resuling debug information that gets parsed, or as a debug
+ /// function to ensure that the module can consume all of the
+ /// debug data the symbol vendor provides.
+ //------------------------------------------------------------------
+ void
+ ParseAllDebugSymbols();
+
+ bool
+ ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr);
+
+ uint32_t
+ ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc);
+
+ //------------------------------------------------------------------
+ /// Resolve items in the symbol context for a given file and line.
+ ///
+ /// Tries to resolve \a file_path and \a line to a list of matching
+ /// symbol contexts.
+ ///
+ /// The line table entries contains addresses that can be used to
+ /// further resolve the values in each match: the function, block,
+ /// symbol. Care should be taken to minimize the amount of
+ /// information that is requested to only what is needed --
+ /// typically the module, compile unit, line table and line table
+ /// entry are sufficient.
+ ///
+ /// @param[in] file_path
+ /// A path to a source file to match. If \a file_path does not
+ /// specify a directory, then this query will match all files
+ /// whose base filename matches. If \a file_path does specify
+ /// a directory, the fullpath to the file must match.
+ ///
+ /// @param[in] line
+ /// The source line to match, or zero if just the compile unit
+ /// should be resolved.
+ ///
+ /// @param[in] check_inlines
+ /// Check for inline file and line number matches. This option
+ /// should be used sparingly as it will cause all line tables
+ /// for every compile unit to be parsed and searched for
+ /// matching inline file entries.
+ ///
+ /// @param[in] resolve_scope
+ /// The scope that should be resolved (see
+ /// SymbolContext::Scope).
+ ///
+ /// @param[out] sc_list
+ /// A symbol context list that gets matching symbols contexts
+ /// appended to.
+ ///
+ /// @return
+ /// The number of matches that were added to \a sc_list.
+ ///
+ /// @see SymbolContext::Scope
+ //------------------------------------------------------------------
+ uint32_t
+ ResolveSymbolContextForFilePath (const char *file_path, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list);
+
+ //------------------------------------------------------------------
+ /// Resolve items in the symbol context for a given file and line.
+ ///
+ /// Tries to resolve \a file_spec and \a line to a list of matching
+ /// symbol contexts.
+ ///
+ /// The line table entries contains addresses that can be used to
+ /// further resolve the values in each match: the function, block,
+ /// symbol. Care should be taken to minimize the amount of
+ /// information that is requested to only what is needed --
+ /// typically the module, compile unit, line table and line table
+ /// entry are sufficient.
+ ///
+ /// @param[in] file_spec
+ /// A file spec to a source file to match. If \a file_path does
+ /// not specify a directory, then this query will match all
+ /// files whose base filename matches. If \a file_path does
+ /// specify a directory, the fullpath to the file must match.
+ ///
+ /// @param[in] line
+ /// The source line to match, or zero if just the compile unit
+ /// should be resolved.
+ ///
+ /// @param[in] check_inlines
+ /// Check for inline file and line number matches. This option
+ /// should be used sparingly as it will cause all line tables
+ /// for every compile unit to be parsed and searched for
+ /// matching inline file entries.
+ ///
+ /// @param[in] resolve_scope
+ /// The scope that should be resolved (see
+ /// SymbolContext::Scope).
+ ///
+ /// @param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ ///
+ /// @return
+ /// A integer that contains SymbolContext::Scope bits set for
+ /// each item that was successfully resolved.
+ ///
+ /// @see SymbolContext::Scope
+ //------------------------------------------------------------------
+ uint32_t
+ ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list);
+
+
+ void
+ SetFileSpecAndObjectName (const FileSpec &file,
+ const ConstString &object_name);
+
+ bool
+ GetIsDynamicLinkEditor () const
+ {
+ return m_is_dynamic_loader_module;
+ }
+
+ void
+ SetIsDynamicLinkEditor (bool b)
+ {
+ m_is_dynamic_loader_module = b;
+ }
+
+ ClangASTContext &
+ GetClangASTContext ();
+
+ // Special error functions that can do printf style formatting that will prepend the message with
+ // something appropriate for this module (like the architecture, path and object name (if any)).
+ // This centralizes code so that everyone doesn't need to format their error and log messages on
+ // their own and keeps the output a bit more consistent.
+ void
+ LogMessage (Log *log, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
+
+ void
+ LogMessageVerboseBacktrace (Log *log, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
+
+ void
+ ReportWarning (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ ReportError (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ // Only report an error once when the module is first detected to be modified
+ // so we don't spam the console with many messages.
+ void
+ ReportErrorIfModifyDetected (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ //------------------------------------------------------------------
+ // Return true if the file backing this module has changed since the
+ // module was originally created since we saved the intial file
+ // modification time when the module first gets created.
+ //------------------------------------------------------------------
+ bool
+ FileHasChanged () const;
+
+ //------------------------------------------------------------------
+ // SymbolVendor, SymbolFile and ObjectFile member objects should
+ // lock the module mutex to avoid deadlocks.
+ //------------------------------------------------------------------
+ Mutex &
+ GetMutex () const
+ {
+ return m_mutex;
+ }
+
+ PathMappingList &
+ GetSourceMappingList ()
+ {
+ return m_source_mappings;
+ }
+
+ const PathMappingList &
+ GetSourceMappingList () const
+ {
+ return m_source_mappings;
+ }
+
+ //------------------------------------------------------------------
+ /// Finds a source file given a file spec using the module source
+ /// path remappings (if any).
+ ///
+ /// Tries to resolve \a orig_spec by checking the module source path
+ /// remappings. It makes sure the file exists, so this call can be
+ /// expensive if the remappings are on a network file system, so
+ /// use this function sparingly (not in a tight debug info parsing
+ /// loop).
+ ///
+ /// @param[in] orig_spec
+ /// The original source file path to try and remap.
+ ///
+ /// @param[out] new_spec
+ /// The newly remapped filespec that is guaranteed to exist.
+ ///
+ /// @return
+ /// /b true if \a orig_spec was successfully located and
+ /// \a new_spec is filled in with an existing file spec,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ FindSourceFile (const FileSpec &orig_spec, FileSpec &new_spec) const;
+
+ //------------------------------------------------------------------
+ /// Remaps a source file given \a path into \a new_path.
+ ///
+ /// Remaps \a path if any source remappings match. This function
+ /// does NOT stat the file system so it can be used in tight loops
+ /// where debug info is being parsed.
+ ///
+ /// @param[in] path
+ /// The original source file path to try and remap.
+ ///
+ /// @param[out] new_path
+ /// The newly remapped filespec that is may or may not exist.
+ ///
+ /// @return
+ /// /b true if \a path was successfully located and \a new_path
+ /// is filled in with a new source path, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ RemapSourceFile (const char *path, std::string &new_path) const;
+
+
+ //------------------------------------------------------------------
+ /// Prepare to do a function name lookup.
+ ///
+ /// Looking up functions by name can be a tricky thing. LLDB requires
+ /// that accelerator tables contain full names for functions as well
+ /// as function basenames which include functions, class methods and
+ /// class functions. When the user requests that an action use a
+ /// function by name, we are sometimes asked to automatically figure
+ /// out what a name could possibly map to. A user might request a
+ /// breakpoint be set on "count". If no options are supplied to limit
+ /// the scope of where to search for count, we will by default match
+ /// any function names named "count", all class and instance methods
+ /// named "count" (no matter what the namespace or contained context)
+ /// and any selectors named "count". If a user specifies "a::b" we
+ /// will search for the basename "b", and then prune the results that
+ /// don't match "a::b" (note that "c::a::b" and "d::e::a::b" will
+ /// match a query of "a::b".
+ ///
+ /// @param[in] name
+ /// The user supplied name to use in the lookup
+ ///
+ /// @param[in] name_type_mask
+ /// The mask of bits from lldb::FunctionNameType enumerations
+ /// that tell us what kind of name we are looking for.
+ ///
+ /// @param[out] lookup_name
+ /// The actual name that will be used when calling
+ /// SymbolVendor::FindFunctions() or Symtab::FindFunctionSymbols()
+ ///
+ /// @param[out] lookup_name_type_mask
+ /// The actual name mask that should be used in the calls to
+ /// SymbolVendor::FindFunctions() or Symtab::FindFunctionSymbols()
+ ///
+ /// @param[out] match_name_after_lookup
+ /// A boolean that indicates if we need to iterate through any
+ /// match results obtained from SymbolVendor::FindFunctions() or
+ /// Symtab::FindFunctionSymbols() to see if the name contains
+ /// \a name. For example if \a name is "a::b", this function will
+ /// return a \a lookup_name of "b", with \a match_name_after_lookup
+ /// set to true to indicate any matches will need to be checked
+ /// to make sure they contain \a name.
+ //------------------------------------------------------------------
+ static void
+ PrepareForFunctionNameLookup (const ConstString &name,
+ uint32_t name_type_mask,
+ ConstString &lookup_name,
+ uint32_t &lookup_name_type_mask,
+ bool &match_name_after_lookup);
+
+protected:
+ //------------------------------------------------------------------
+ // Member Variables
+ //------------------------------------------------------------------
+ mutable Mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments.
+ TimeValue m_mod_time; ///< The modification time for this module when it was created.
+ ArchSpec m_arch; ///< The architecture for this module.
+ lldb_private::UUID m_uuid; ///< Each module is assumed to have a unique identifier to help match it up to debug symbols.
+ FileSpec m_file; ///< The file representation on disk for this module (if there is one).
+ FileSpec m_platform_file;///< The path to the module on the platform on which it is being debugged
+ FileSpec m_symfile_spec; ///< If this path is valid, then this is the file that _will_ be used as the symbol file for this module
+ ConstString m_object_name; ///< The name an object within this module that is selected, or empty of the module is represented by \a m_file.
+ uint64_t m_object_offset;
+ TimeValue m_object_mod_time;
+ lldb::ObjectFileSP m_objfile_sp; ///< A shared pointer to the object file parser for this module as it may or may not be shared with the SymbolFile
+ std::unique_ptr<SymbolVendor> m_symfile_ap; ///< A pointer to the symbol vendor for this module.
+ ClangASTContext m_ast; ///< The AST context for this module.
+ PathMappingList m_source_mappings; ///< Module specific source remappings for when you have debug info for a module that doesn't match where the sources currently are
+ std::unique_ptr<lldb_private::SectionList> m_sections_ap; ///< Unified section list for module that is used by the ObjectFile and and ObjectFile instances for the debug info
+
+ bool m_did_load_objfile:1,
+ m_did_load_symbol_vendor:1,
+ m_did_parse_uuid:1,
+ m_did_init_ast:1,
+ m_is_dynamic_loader_module:1;
+ mutable bool m_file_has_changed:1,
+ m_first_file_changed_log:1; /// See if the module was modified after it was initially opened.
+
+ //------------------------------------------------------------------
+ /// Resolve a file or load virtual address.
+ ///
+ /// Tries to resolve \a vm_addr as a file address (if \a
+ /// vm_addr_is_file_addr is true) or as a load address if \a
+ /// vm_addr_is_file_addr is false) in the symbol vendor.
+ /// \a resolve_scope indicates what clients wish to resolve
+ /// and can be used to limit the scope of what is parsed.
+ ///
+ /// @param[in] vm_addr
+ /// The load virtual address to resolve.
+ ///
+ /// @param[in] vm_addr_is_file_addr
+ /// If \b true, \a vm_addr is a file address, else \a vm_addr
+ /// if a load address.
+ ///
+ /// @param[in] resolve_scope
+ /// The scope that should be resolved (see
+ /// SymbolContext::Scope).
+ ///
+ /// @param[out] so_addr
+ /// The section offset based address that got resolved if
+ /// any bits are returned.
+ ///
+ /// @param[out] sc
+ // The symbol context that has objects filled in. Each bit
+ /// in the \a resolve_scope pertains to a member in the \a sc.
+ ///
+ /// @return
+ /// A integer that contains SymbolContext::Scope bits set for
+ /// each item that was successfully resolved.
+ ///
+ /// @see SymbolContext::Scope
+ //------------------------------------------------------------------
+ uint32_t
+ ResolveSymbolContextForAddress (lldb::addr_t vm_addr,
+ bool vm_addr_is_file_addr,
+ uint32_t resolve_scope,
+ Address& so_addr,
+ SymbolContext& sc);
+
+ void
+ SymbolIndicesToSymbolContextList (Symtab *symtab,
+ std::vector<uint32_t> &symbol_indexes,
+ SymbolContextList &sc_list);
+
+ bool
+ SetArchitecture (const ArchSpec &new_arch);
+
+ SectionList *
+ GetUnifiedSectionList();
+
+ friend class ModuleList;
+ friend class ObjectFile;
+ friend class SymbolFile;
+
+private:
+
+ size_t
+ FindTypes_Impl (const SymbolContext& sc,
+ const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ bool append,
+ size_t max_matches,
+ TypeList& types);
+
+
+ DISALLOW_COPY_AND_ASSIGN (Module);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Module_h_
diff --git a/include/lldb/Core/ModuleChild.h b/include/lldb/Core/ModuleChild.h
new file mode 100644
index 000000000000..d2a6fb0c3bc1
--- /dev/null
+++ b/include/lldb/Core/ModuleChild.h
@@ -0,0 +1,90 @@
+//===-- ModuleChild.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ModuleChild_h_
+#define liblldb_ModuleChild_h_
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ModuleChild ModuleChild.h "lldb/Core/ModuleChild.h"
+/// @brief A mix in class that contains a pointer back to the module
+/// that owns the object which inherits from it.
+//----------------------------------------------------------------------
+class ModuleChild
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with owning module.
+ ///
+ /// @param[in] module
+ /// The module that owns the object that inherits from this
+ /// class.
+ //------------------------------------------------------------------
+ ModuleChild (const lldb::ModuleSP &module_sp);
+
+ //------------------------------------------------------------------
+ /// Copy constructor.
+ ///
+ /// @param[in] rhs
+ /// A const ModuleChild class reference to copy.
+ //------------------------------------------------------------------
+ ModuleChild (const ModuleChild& rhs);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~ModuleChild();
+
+ //------------------------------------------------------------------
+ /// Assignment operator.
+ ///
+ /// @param[in] rhs
+ /// A const ModuleChild class reference to copy.
+ ///
+ /// @return
+ /// A const reference to this object.
+ //------------------------------------------------------------------
+ const ModuleChild&
+ operator= (const ModuleChild& rhs);
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the module pointer.
+ ///
+ /// @return
+ /// A const pointer to the module that owns the object that
+ /// inherits from this class.
+ //------------------------------------------------------------------
+ lldb::ModuleSP
+ GetModule () const;
+
+ //------------------------------------------------------------------
+ /// Set accessor for the module pointer.
+ ///
+ /// @param[in] module
+ /// A new module that owns the object that inherits from this
+ /// class.
+ //------------------------------------------------------------------
+ void
+ SetModule (const lldb::ModuleSP &module_sp);
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ lldb::ModuleWP m_module_wp; ///< The Module that owns the object that inherits
+ ///< from this class.
+};
+
+} // namespace lldb_private
+
+
+#endif // liblldb_ModuleChild_h_
diff --git a/include/lldb/Core/ModuleList.h b/include/lldb/Core/ModuleList.h
new file mode 100644
index 000000000000..1198e4196481
--- /dev/null
+++ b/include/lldb/Core/ModuleList.h
@@ -0,0 +1,556 @@
+//===-- ModuleList.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ModuleList_h_
+#define liblldb_ModuleList_h_
+
+#include <vector>
+#include <list>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ModuleList ModuleList.h "lldb/Core/ModuleList.h"
+/// @brief A collection class for Module objects.
+///
+/// Modules in the module collection class are stored as reference
+/// counted shared pointers to Module objects.
+//----------------------------------------------------------------------
+class ModuleList
+{
+public:
+
+ class Notifier
+ {
+ public:
+ virtual void
+ ModuleAdded (const ModuleList& module_list, const lldb::ModuleSP& module_sp) = 0;
+ virtual void
+ ModuleRemoved (const ModuleList& module_list, const lldb::ModuleSP& module_sp) = 0;
+ virtual void
+ ModuleUpdated (const ModuleList& module_list, const lldb::ModuleSP& old_module_sp,
+ const lldb::ModuleSP& new_module_sp) = 0;
+ virtual void
+ WillClearList (const ModuleList& module_list) = 0;
+
+ virtual
+ ~Notifier ()
+ {}
+ };
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Creates an empty list of Module objects.
+ //------------------------------------------------------------------
+ ModuleList ();
+
+ //------------------------------------------------------------------
+ /// Copy Constructor.
+ ///
+ /// Creates a new module list object with a copy of the modules from
+ /// \a rhs.
+ ///
+ /// @param[in] rhs
+ /// Another module list object.
+ //------------------------------------------------------------------
+ ModuleList (const ModuleList& rhs);
+
+ ModuleList (ModuleList::Notifier* notifier);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~ModuleList ();
+
+ //------------------------------------------------------------------
+ /// Assignment operator.
+ ///
+ /// Copies the module list from \a rhs into this list.
+ ///
+ /// @param[in] rhs
+ /// Another module list object.
+ ///
+ /// @return
+ /// A const reference to this object.
+ //------------------------------------------------------------------
+ const ModuleList&
+ operator= (const ModuleList& rhs);
+
+ //------------------------------------------------------------------
+ /// Append a module to the module list.
+ ///
+ /// Appends the module to the collection.
+ ///
+ /// @param[in] module_sp
+ /// A shared pointer to a module to add to this collection.
+ //------------------------------------------------------------------
+ void
+ Append (const lldb::ModuleSP &module_sp);
+
+ //------------------------------------------------------------------
+ /// Append a module to the module list and remove any equivalent
+ /// modules. Equivalent modules are ones whose file, platform file
+ /// and architecture matches.
+ ///
+ /// Replaces the module to the collection.
+ ///
+ /// @param[in] module_sp
+ /// A shared pointer to a module to replace in this collection.
+ //------------------------------------------------------------------
+ void
+ ReplaceEquivalent (const lldb::ModuleSP &module_sp);
+
+ bool
+ AppendIfNeeded (const lldb::ModuleSP &module_sp);
+
+ void
+ Append (const ModuleList& module_list);
+
+ bool
+ AppendIfNeeded (const ModuleList& module_list);
+
+ bool
+ ReplaceModule (const lldb::ModuleSP &old_module_sp, const lldb::ModuleSP &new_module_sp);
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Clears the list of modules and releases a reference to each
+ /// module object and if the reference count goes to zero, the
+ /// module will be deleted.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Clears the list of modules and releases a reference to each
+ /// module object and if the reference count goes to zero, the
+ /// module will be deleted. Also relese all memory that might be
+ /// held by any collection classes (like std::vector)
+ //------------------------------------------------------------------
+ void
+ Destroy();
+ //------------------------------------------------------------------
+ /// Dump the description of each module contained in this list.
+ ///
+ /// Dump the description of each module contained in this list to
+ /// the supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @see Module::Dump(Stream *) const
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s) const;
+
+ void
+ LogUUIDAndPaths (Log *log, const char *prefix_cstr);
+
+ Mutex &
+ GetMutex () const
+ {
+ return m_modules_mutex;
+ }
+
+ size_t
+ GetIndexForModule (const Module *module) const;
+
+ //------------------------------------------------------------------
+ /// Get the module shared pointer for the module at index \a idx.
+ ///
+ /// @param[in] idx
+ /// An index into this module collection.
+ ///
+ /// @return
+ /// A shared pointer to a Module which can contain NULL if
+ /// \a idx is out of range.
+ ///
+ /// @see ModuleList::GetSize()
+ //------------------------------------------------------------------
+ lldb::ModuleSP
+ GetModuleAtIndex (size_t idx) const;
+
+ //------------------------------------------------------------------
+ /// Get the module shared pointer for the module at index \a idx without
+ /// acquiring the ModuleList mutex. This MUST already have been
+ /// acquired with ModuleList::GetMutex and locked for this call to be safe.
+ ///
+ /// @param[in] idx
+ /// An index into this module collection.
+ ///
+ /// @return
+ /// A shared pointer to a Module which can contain NULL if
+ /// \a idx is out of range.
+ ///
+ /// @see ModuleList::GetSize()
+ //------------------------------------------------------------------
+ lldb::ModuleSP
+ GetModuleAtIndexUnlocked (size_t idx) const;
+
+ //------------------------------------------------------------------
+ /// Get the module pointer for the module at index \a idx.
+ ///
+ /// @param[in] idx
+ /// An index into this module collection.
+ ///
+ /// @return
+ /// A pointer to a Module which can by NULL if \a idx is out
+ /// of range.
+ ///
+ /// @see ModuleList::GetSize()
+ //------------------------------------------------------------------
+ Module*
+ GetModulePointerAtIndex (size_t idx) const;
+
+ //------------------------------------------------------------------
+ /// Get the module pointer for the module at index \a idx without
+ /// acquiring the ModuleList mutex. This MUST already have been
+ /// acquired with ModuleList::GetMutex and locked for this call to be safe.
+ ///
+ /// @param[in] idx
+ /// An index into this module collection.
+ ///
+ /// @return
+ /// A pointer to a Module which can by NULL if \a idx is out
+ /// of range.
+ ///
+ /// @see ModuleList::GetSize()
+ //------------------------------------------------------------------
+ Module*
+ GetModulePointerAtIndexUnlocked (size_t idx) const;
+
+ //------------------------------------------------------------------
+ /// Find compile units by partial or full path.
+ ///
+ /// Finds all compile units that match \a path in all of the modules
+ /// and returns the results in \a sc_list.
+ ///
+ /// @param[in] path
+ /// The name of the compile unit we are looking for.
+ ///
+ /// @param[in] append
+ /// If \b true, then append any compile units that were found
+ /// to \a sc_list. If \b false, then the \a sc_list is cleared
+ /// and the contents of \a sc_list are replaced.
+ ///
+ /// @param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ ///
+ /// @return
+ /// The number of matches added to \a sc_list.
+ //------------------------------------------------------------------
+ size_t
+ FindCompileUnits (const FileSpec &path,
+ bool append,
+ SymbolContextList &sc_list) const;
+
+ //------------------------------------------------------------------
+ /// @see Module::FindFunctions ()
+ //------------------------------------------------------------------
+ size_t
+ FindFunctions (const ConstString &name,
+ uint32_t name_type_mask,
+ bool include_symbols,
+ bool include_inlines,
+ bool append,
+ SymbolContextList &sc_list) const;
+
+ //------------------------------------------------------------------
+ /// @see Module::FindFunctionSymbols ()
+ //------------------------------------------------------------------
+ size_t
+ FindFunctionSymbols (const ConstString &name,
+ uint32_t name_type_mask,
+ SymbolContextList& sc_list);
+
+ //------------------------------------------------------------------
+ /// Find global and static variables by name.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @param[in] append
+ /// If \b true, any matches will be appended to \a
+ /// variable_list, else matches replace the contents of
+ /// \a variable_list.
+ ///
+ /// @param[in] max_matches
+ /// Allow the number of matches to be limited to \a
+ /// max_matches. Specify UINT32_MAX to get all possible matches.
+ ///
+ /// @param[in] variable_list
+ /// A list of variables that gets the matches appended to (if
+ /// \a append it \b true), or replace (if \a append is \b false).
+ ///
+ /// @return
+ /// The number of matches added to \a variable_list.
+ //------------------------------------------------------------------
+ size_t
+ FindGlobalVariables (const ConstString &name,
+ bool append,
+ size_t max_matches,
+ VariableList& variable_list) const;
+
+ //------------------------------------------------------------------
+ /// Find global and static variables by regular exression.
+ ///
+ /// @param[in] regex
+ /// A regular expression to use when matching the name.
+ ///
+ /// @param[in] append
+ /// If \b true, any matches will be appended to \a
+ /// variable_list, else matches replace the contents of
+ /// \a variable_list.
+ ///
+ /// @param[in] max_matches
+ /// Allow the number of matches to be limited to \a
+ /// max_matches. Specify UINT32_MAX to get all possible matches.
+ ///
+ /// @param[in] variable_list
+ /// A list of variables that gets the matches appended to (if
+ /// \a append it \b true), or replace (if \a append is \b false).
+ ///
+ /// @return
+ /// The number of matches added to \a variable_list.
+ //------------------------------------------------------------------
+ size_t
+ FindGlobalVariables (const RegularExpression& regex,
+ bool append,
+ size_t max_matches,
+ VariableList& variable_list) const;
+
+ //------------------------------------------------------------------
+ /// Finds the first module whose file specification matches \a
+ /// file_spec.
+ ///
+ /// @param[in] file_spec_ptr
+ /// A file specification object to match against the Module's
+ /// file specifications. If \a file_spec does not have
+ /// directory information, matches will occur by matching only
+ /// the basename of any modules in this list. If this value is
+ /// NULL, then file specifications won't be compared when
+ /// searching for matching modules.
+ ///
+ /// @param[in] arch_ptr
+ /// The architecture to search for if non-NULL. If this value
+ /// is NULL no architecture matching will be performed.
+ ///
+ /// @param[in] uuid_ptr
+ /// The uuid to search for if non-NULL. If this value is NULL
+ /// no uuid matching will be performed.
+ ///
+ /// @param[in] object_name
+ /// An optional object name that must match as well. This value
+ /// can be NULL.
+ ///
+ /// @param[out] matching_module_list
+ /// A module list that gets filled in with any modules that
+ /// match the search criteria.
+ ///
+ /// @return
+ /// The number of matching modules found by the search.
+ //------------------------------------------------------------------
+ size_t
+ FindModules (const ModuleSpec &module_spec,
+ ModuleList& matching_module_list) const;
+
+ lldb::ModuleSP
+ FindModule (const Module *module_ptr) const;
+
+ //------------------------------------------------------------------
+ // Find a module by UUID
+ //
+ // The UUID value for a module is extracted from the ObjectFile and
+ // is the MD5 checksum, or a smarter object file equivalent, so
+ // finding modules by UUID values is very efficient and accurate.
+ //------------------------------------------------------------------
+ lldb::ModuleSP
+ FindModule (const UUID &uuid) const;
+
+ lldb::ModuleSP
+ FindFirstModule (const ModuleSpec &module_spec) const;
+
+ size_t
+ FindSymbolsWithNameAndType (const ConstString &name,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list,
+ bool append = false) const;
+
+ size_t
+ FindSymbolsMatchingRegExAndType (const RegularExpression &regex,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list,
+ bool append = false) const;
+
+ //------------------------------------------------------------------
+ /// Find types by name.
+ ///
+ /// @param[in] sc
+ /// A symbol context that scopes where to extract a type list
+ /// from.
+ ///
+ /// @param[in] name
+ /// The name of the type we are looking for.
+ ///
+ /// @param[in] append
+ /// If \b true, any matches will be appended to \a
+ /// variable_list, else matches replace the contents of
+ /// \a variable_list.
+ ///
+ /// @param[in] max_matches
+ /// Allow the number of matches to be limited to \a
+ /// max_matches. Specify UINT32_MAX to get all possible matches.
+ ///
+ /// @param[in] encoding
+ /// Limit the search to specific types, or get all types if
+ /// set to Type::invalid.
+ ///
+ /// @param[in] udt_name
+ /// If the encoding is a user defined type, specify the name
+ /// of the user defined type ("struct", "union", "class", etc).
+ ///
+ /// @param[out] type_list
+ /// A type list gets populated with any matches.
+ ///
+ /// @return
+ /// The number of matches added to \a type_list.
+ //------------------------------------------------------------------
+ size_t
+ FindTypes (const SymbolContext& sc,
+ const ConstString &name,
+ bool name_is_fully_qualified,
+ size_t max_matches,
+ TypeList& types) const;
+
+ bool
+ FindSourceFile (const FileSpec &orig_spec, FileSpec &new_spec) const;
+
+ bool
+ Remove (const lldb::ModuleSP &module_sp);
+
+ size_t
+ Remove (ModuleList &module_list);
+
+ bool
+ RemoveIfOrphaned (const Module *module_ptr);
+
+ size_t
+ RemoveOrphans (bool mandatory);
+
+ bool
+ ResolveFileAddress (lldb::addr_t vm_addr,
+ Address& so_addr) const;
+
+ //------------------------------------------------------------------
+ /// @copydoc Module::ResolveSymbolContextForAddress (const Address &,uint32_t,SymbolContext&)
+ //------------------------------------------------------------------
+ uint32_t
+ ResolveSymbolContextForAddress (const Address& so_addr,
+ uint32_t resolve_scope,
+ SymbolContext& sc) const;
+
+ //------------------------------------------------------------------
+ /// @copydoc Module::ResolveSymbolContextForFilePath (const char *,uint32_t,bool,uint32_t,SymbolContextList&)
+ //------------------------------------------------------------------
+ uint32_t
+ ResolveSymbolContextForFilePath (const char *file_path,
+ uint32_t line,
+ bool check_inlines,
+ uint32_t resolve_scope,
+ SymbolContextList& sc_list) const;
+
+ //------------------------------------------------------------------
+ /// @copydoc Module::ResolveSymbolContextsForFileSpec (const FileSpec &,uint32_t,bool,uint32_t,SymbolContextList&)
+ //------------------------------------------------------------------
+ uint32_t
+ ResolveSymbolContextsForFileSpec (const FileSpec &file_spec,
+ uint32_t line,
+ bool check_inlines,
+ uint32_t resolve_scope,
+ SymbolContextList& sc_list) const;
+
+ //------------------------------------------------------------------
+ /// Gets the size of the module list.
+ ///
+ /// @return
+ /// The number of modules in the module list.
+ //------------------------------------------------------------------
+ size_t
+ GetSize () const;
+
+ bool
+ LoadScriptingResourcesInTarget (Target *target,
+ std::list<Error>& errors,
+ Stream* feedback_stream = NULL,
+ bool continue_on_error = true);
+
+ static bool
+ ModuleIsInCache (const Module *module_ptr);
+
+ static Error
+ GetSharedModule (const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr,
+ bool always_create = false);
+
+ static bool
+ RemoveSharedModule (lldb::ModuleSP &module_sp);
+
+ static size_t
+ FindSharedModules (const ModuleSpec &module_spec,
+ ModuleList &matching_module_list);
+
+ static size_t
+ RemoveOrphanSharedModules (bool mandatory);
+
+ static bool
+ RemoveSharedModuleIfOrphaned (const Module *module_ptr);
+
+protected:
+ //------------------------------------------------------------------
+ // Class typedefs.
+ //------------------------------------------------------------------
+ typedef std::vector<lldb::ModuleSP> collection; ///< The module collection type.
+
+ void
+ AppendImpl (const lldb::ModuleSP &module_sp, bool use_notifier = true);
+
+ bool
+ RemoveImpl (const lldb::ModuleSP &module_sp, bool use_notifier = true);
+
+ collection::iterator
+ RemoveImpl (collection::iterator pos, bool use_notifier = true);
+
+ void
+ ClearImpl (bool use_notifier = true);
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ collection m_modules; ///< The collection of modules.
+ mutable Mutex m_modules_mutex;
+
+ Notifier* m_notifier;
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ModuleList_h_
diff --git a/include/lldb/Core/ModuleSpec.h b/include/lldb/Core/ModuleSpec.h
new file mode 100644
index 000000000000..10e1ea9f17a9
--- /dev/null
+++ b/include/lldb/Core/ModuleSpec.h
@@ -0,0 +1,594 @@
+//===-- ModuleSpec.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ModuleSpec_h_
+#define liblldb_ModuleSpec_h_
+
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/PathMappingList.h"
+
+namespace lldb_private {
+
+class ModuleSpec
+{
+public:
+ ModuleSpec () :
+ m_file (),
+ m_platform_file (),
+ m_symbol_file (),
+ m_arch (),
+ m_uuid (),
+ m_object_name (),
+ m_object_offset (0),
+ m_object_mod_time (),
+ m_source_mappings ()
+ {
+ }
+
+ ModuleSpec (const FileSpec &file_spec) :
+ m_file (file_spec),
+ m_platform_file (),
+ m_symbol_file (),
+ m_arch (),
+ m_uuid (),
+ m_object_name (),
+ m_object_offset (0),
+ m_object_mod_time (),
+ m_source_mappings ()
+ {
+ }
+
+ ModuleSpec (const FileSpec &file_spec, const ArchSpec &arch) :
+ m_file (file_spec),
+ m_platform_file (),
+ m_symbol_file (),
+ m_arch (arch),
+ m_uuid (),
+ m_object_name (),
+ m_object_offset (0),
+ m_object_mod_time (),
+ m_source_mappings ()
+ {
+ }
+
+ ModuleSpec (const ModuleSpec &rhs) :
+ m_file (rhs.m_file),
+ m_platform_file (rhs.m_platform_file),
+ m_symbol_file (rhs.m_symbol_file),
+ m_arch (rhs.m_arch),
+ m_uuid (rhs.m_uuid),
+ m_object_name (rhs.m_object_name),
+ m_object_offset (rhs.m_object_offset),
+ m_object_mod_time (rhs.m_object_mod_time),
+ m_source_mappings (rhs.m_source_mappings)
+ {
+ }
+
+ ModuleSpec &
+ operator = (const ModuleSpec &rhs)
+ {
+ if (this != &rhs)
+ {
+ m_file = rhs.m_file;
+ m_platform_file = rhs.m_platform_file;
+ m_symbol_file = rhs.m_symbol_file;
+ m_arch = rhs.m_arch;
+ m_uuid = rhs.m_uuid;
+ m_object_name = rhs.m_object_name;
+ m_object_offset = rhs.m_object_offset;
+ m_object_mod_time = rhs.m_object_mod_time;
+ m_source_mappings = rhs.m_source_mappings;
+ }
+ return *this;
+ }
+
+ FileSpec *
+ GetFileSpecPtr ()
+ {
+ if (m_file)
+ return &m_file;
+ return NULL;
+ }
+
+ const FileSpec *
+ GetFileSpecPtr () const
+ {
+ if (m_file)
+ return &m_file;
+ return NULL;
+ }
+
+ FileSpec &
+ GetFileSpec ()
+ {
+ return m_file;
+ }
+ const FileSpec &
+ GetFileSpec () const
+ {
+ return m_file;
+ }
+
+ FileSpec *
+ GetPlatformFileSpecPtr ()
+ {
+ if (m_platform_file)
+ return &m_platform_file;
+ return NULL;
+ }
+
+ const FileSpec *
+ GetPlatformFileSpecPtr () const
+ {
+ if (m_platform_file)
+ return &m_platform_file;
+ return NULL;
+ }
+
+ FileSpec &
+ GetPlatformFileSpec ()
+ {
+ return m_platform_file;
+ }
+
+ const FileSpec &
+ GetPlatformFileSpec () const
+ {
+ return m_platform_file;
+ }
+
+ FileSpec *
+ GetSymbolFileSpecPtr ()
+ {
+ if (m_symbol_file)
+ return &m_symbol_file;
+ return NULL;
+ }
+
+ const FileSpec *
+ GetSymbolFileSpecPtr () const
+ {
+ if (m_symbol_file)
+ return &m_symbol_file;
+ return NULL;
+ }
+
+ FileSpec &
+ GetSymbolFileSpec ()
+ {
+ return m_symbol_file;
+ }
+
+ const FileSpec &
+ GetSymbolFileSpec () const
+ {
+ return m_symbol_file;
+ }
+
+
+ ArchSpec *
+ GetArchitecturePtr ()
+ {
+ if (m_arch.IsValid())
+ return &m_arch;
+ return NULL;
+ }
+
+ const ArchSpec *
+ GetArchitecturePtr () const
+ {
+ if (m_arch.IsValid())
+ return &m_arch;
+ return NULL;
+ }
+
+ ArchSpec &
+ GetArchitecture ()
+ {
+ return m_arch;
+ }
+
+ const ArchSpec &
+ GetArchitecture () const
+ {
+ return m_arch;
+ }
+
+ UUID *
+ GetUUIDPtr ()
+ {
+ if (m_uuid.IsValid())
+ return &m_uuid;
+ return NULL;
+ }
+
+ const UUID *
+ GetUUIDPtr () const
+ {
+ if (m_uuid.IsValid())
+ return &m_uuid;
+ return NULL;
+ }
+
+ UUID &
+ GetUUID ()
+ {
+ return m_uuid;
+ }
+
+ const UUID &
+ GetUUID () const
+ {
+ return m_uuid;
+ }
+
+ ConstString &
+ GetObjectName ()
+ {
+ return m_object_name;
+ }
+
+ const ConstString &
+ GetObjectName () const
+ {
+ return m_object_name;
+ }
+
+ uint64_t
+ GetObjectOffset () const
+ {
+ return m_object_offset;
+ }
+
+ void
+ SetObjectOffset (uint64_t object_offset)
+ {
+ m_object_offset = object_offset;
+ }
+
+ TimeValue &
+ GetObjectModificationTime ()
+ {
+ return m_object_mod_time;
+ }
+
+ const TimeValue &
+ GetObjectModificationTime () const
+ {
+ return m_object_mod_time;
+ }
+
+ PathMappingList &
+ GetSourceMappingList () const
+ {
+ return m_source_mappings;
+ }
+
+ void
+ Clear ()
+ {
+ m_file.Clear();
+ m_platform_file.Clear();
+ m_symbol_file.Clear();
+ m_arch.Clear();
+ m_uuid.Clear();
+ m_object_name.Clear();
+ m_object_offset = 0;
+ m_source_mappings.Clear(false);
+ m_object_mod_time.Clear();
+ }
+
+
+ operator bool () const
+ {
+ if (m_file)
+ return true;
+ if (m_platform_file)
+ return true;
+ if (m_symbol_file)
+ return true;
+ if (m_arch.IsValid())
+ return true;
+ if (m_uuid.IsValid())
+ return true;
+ if (m_object_name)
+ return true;
+ if (m_object_mod_time.IsValid())
+ return true;
+ return false;
+ }
+
+ void
+ Dump (Stream &strm)
+ {
+ bool dumped_something = false;
+ if (m_file)
+ {
+ strm.PutCString("file = '");
+ strm << m_file;
+ strm.PutCString("'");
+ dumped_something = true;
+ }
+ if (m_platform_file)
+ {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.PutCString("platform_file = '");
+ strm << m_platform_file;
+ strm.PutCString("'");
+ dumped_something = true;
+ }
+ if (m_symbol_file)
+ {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.PutCString("symbol_file = '");
+ strm << m_symbol_file;
+ strm.PutCString("'");
+ dumped_something = true;
+ }
+ if (m_arch.IsValid())
+ {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.Printf("arch = %s", m_arch.GetTriple().str().c_str());
+ dumped_something = true;
+ }
+ if (m_uuid.IsValid())
+ {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.PutCString("uuid = ");
+ m_uuid.Dump(&strm);
+ dumped_something = true;
+ }
+ if (m_object_name)
+ {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.Printf("object_name = %s", m_object_name.GetCString());
+ dumped_something = true;
+ }
+ if (m_object_offset > 0)
+ {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.Printf("object_offset = 0x%" PRIx64, m_object_offset);
+ dumped_something = true;
+ }
+ if (m_object_mod_time.IsValid())
+ {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.Printf("object_mod_time = 0x%" PRIx64, m_object_mod_time.GetAsSecondsSinceJan1_1970());
+ dumped_something = true;
+ }
+ }
+
+ bool
+ Matches (const ModuleSpec &match_module_spec, bool exact_arch_match) const
+ {
+ if (match_module_spec.GetUUIDPtr() && match_module_spec.GetUUID() != GetUUID())
+ return false;
+ if (match_module_spec.GetObjectName() && match_module_spec.GetObjectName() != GetObjectName())
+ return false;
+ if (match_module_spec.GetFileSpecPtr())
+ {
+ const FileSpec &fspec = match_module_spec.GetFileSpec();
+ if (!FileSpec::Equal(fspec, GetFileSpec(), fspec.GetDirectory().IsEmpty() == false))
+ return false;
+ }
+ if (match_module_spec.GetPlatformFileSpecPtr())
+ {
+ const FileSpec &fspec = match_module_spec.GetPlatformFileSpec();
+ if (!FileSpec::Equal(fspec, GetPlatformFileSpec(), fspec.GetDirectory().IsEmpty() == false))
+ return false;
+
+ }
+ if (match_module_spec.GetSymbolFileSpecPtr())
+ {
+ const FileSpec &fspec = match_module_spec.GetSymbolFileSpec();
+ if (!FileSpec::Equal(fspec, GetSymbolFileSpec(), fspec.GetDirectory().IsEmpty() == false))
+ return false;
+
+ }
+ if (match_module_spec.GetArchitecturePtr())
+ {
+ if (exact_arch_match)
+ {
+ if (!GetArchitecture().IsExactMatch(match_module_spec.GetArchitecture()))
+ return false;
+ }
+ else
+ {
+ if (!GetArchitecture().IsCompatibleMatch(match_module_spec.GetArchitecture()))
+ return false;
+ }
+ }
+ return true;
+ }
+
+protected:
+ FileSpec m_file;
+ FileSpec m_platform_file;
+ FileSpec m_symbol_file;
+ ArchSpec m_arch;
+ UUID m_uuid;
+ ConstString m_object_name;
+ uint64_t m_object_offset;
+ TimeValue m_object_mod_time;
+ mutable PathMappingList m_source_mappings;
+};
+
+class ModuleSpecList
+{
+public:
+ ModuleSpecList () :
+ m_specs(),
+ m_mutex(Mutex::eMutexTypeRecursive)
+ {
+ }
+
+ ModuleSpecList (const ModuleSpecList &rhs) :
+ m_specs(),
+ m_mutex(Mutex::eMutexTypeRecursive)
+ {
+ Mutex::Locker lhs_locker(m_mutex);
+ Mutex::Locker rhs_locker(rhs.m_mutex);
+ m_specs = rhs.m_specs;
+ }
+
+ ~ModuleSpecList ()
+ {
+ }
+
+ ModuleSpecList &
+ operator = (const ModuleSpecList &rhs)
+ {
+ if (this != &rhs)
+ {
+ Mutex::Locker lhs_locker(m_mutex);
+ Mutex::Locker rhs_locker(rhs.m_mutex);
+ m_specs = rhs.m_specs;
+ }
+ return *this;
+ }
+
+ size_t
+ GetSize() const
+ {
+ Mutex::Locker locker(m_mutex);
+ return m_specs.size();
+ }
+
+ void
+ Clear ()
+ {
+ Mutex::Locker locker(m_mutex);
+ m_specs.clear();
+ }
+
+ void
+ Append (const ModuleSpec &spec)
+ {
+ Mutex::Locker locker(m_mutex);
+ m_specs.push_back (spec);
+ }
+
+ void
+ Append (const ModuleSpecList &rhs)
+ {
+ Mutex::Locker lhs_locker(m_mutex);
+ Mutex::Locker rhs_locker(rhs.m_mutex);
+ m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end());
+ }
+
+ // The index "i" must be valid and this can't be used in
+ // multi-threaded code as no mutex lock is taken.
+ ModuleSpec &
+ GetModuleSpecRefAtIndex (size_t i)
+ {
+ return m_specs[i];
+ }
+ bool
+ GetModuleSpecAtIndex (size_t i, ModuleSpec &module_spec) const
+ {
+ Mutex::Locker locker(m_mutex);
+ if (i < m_specs.size())
+ {
+ module_spec = m_specs[i];
+ return true;
+ }
+ module_spec.Clear();
+ return false;
+ }
+
+
+ bool
+ FindMatchingModuleSpec (const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
+ {
+ Mutex::Locker locker(m_mutex);
+ bool exact_arch_match = true;
+ for (auto spec: m_specs)
+ {
+ if (spec.Matches(module_spec, exact_arch_match))
+ {
+ match_module_spec = spec;
+ return true;
+ }
+ }
+
+ // If there was an architecture, retry with a compatible arch
+ if (module_spec.GetArchitecturePtr())
+ {
+ exact_arch_match = false;
+ for (auto spec: m_specs)
+ {
+ if (spec.Matches(module_spec, exact_arch_match))
+ {
+ match_module_spec = spec;
+ return true;
+ }
+ }
+ }
+ match_module_spec.Clear();
+ return false;
+ }
+
+ size_t
+ FindMatchingModuleSpecs (const ModuleSpec &module_spec, ModuleSpecList &matching_list) const
+ {
+ Mutex::Locker locker(m_mutex);
+ bool exact_arch_match = true;
+ const size_t initial_match_count = matching_list.GetSize();
+ for (auto spec: m_specs)
+ {
+ if (spec.Matches(module_spec, exact_arch_match))
+ matching_list.Append (spec);
+ }
+
+ // If there was an architecture, retry with a compatible arch if no matches were found
+ if (module_spec.GetArchitecturePtr() && (initial_match_count == matching_list.GetSize()))
+ {
+ exact_arch_match = false;
+ for (auto spec: m_specs)
+ {
+ if (spec.Matches(module_spec, exact_arch_match))
+ matching_list.Append (spec);
+ }
+ }
+ return matching_list.GetSize() - initial_match_count;
+ }
+
+ void
+ Dump (Stream &strm)
+ {
+ Mutex::Locker locker(m_mutex);
+ uint32_t idx = 0;
+ for (auto spec: m_specs)
+ {
+ strm.Printf("[%u] ", idx);
+ spec.Dump (strm);
+ strm.EOL();
+ ++idx;
+ }
+ }
+
+protected:
+ typedef std::vector<ModuleSpec> collection; ///< The module collection type.
+ collection m_specs; ///< The collection of modules.
+ mutable Mutex m_mutex;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ModuleSpec_h_
diff --git a/include/lldb/Core/Opcode.h b/include/lldb/Core/Opcode.h
new file mode 100644
index 000000000000..c07193b62059
--- /dev/null
+++ b/include/lldb/Core/Opcode.h
@@ -0,0 +1,270 @@
+//===-- Opcode.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Opcode_h
+#define lldb_Opcode_h
+
+// C Includes
+#include <string.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+
+namespace lldb
+{
+ class SBInstruction;
+}
+
+namespace lldb_private {
+
+ class Opcode
+ {
+ public:
+ enum Type
+ {
+ eTypeInvalid,
+ eType8,
+ eType16,
+ eType16_2, // a 32-bit Thumb instruction, made up of two words
+ eType32,
+ eType64,
+ eTypeBytes
+ };
+
+ Opcode () : m_type (eTypeInvalid)
+ {
+ }
+
+ Opcode (uint8_t inst) : m_type (eType8)
+ {
+ m_data.inst8 = inst;
+ }
+
+ Opcode (uint16_t inst) : m_type (eType16)
+ {
+ m_data.inst16 = inst;
+ }
+
+ Opcode (uint32_t inst) : m_type (eType32)
+ {
+ m_data.inst32 = inst;
+ }
+
+ Opcode (uint64_t inst) : m_type (eType64)
+ {
+ m_data.inst64 = inst;
+ }
+
+ Opcode (uint8_t *bytes, size_t length)
+ {
+ SetOpcodeBytes (bytes, length);
+ }
+
+ void
+ Clear()
+ {
+ m_type = Opcode::eTypeInvalid;
+ }
+ Opcode::Type
+ GetType () const
+ {
+ return m_type;
+ }
+
+ uint8_t
+ GetOpcode8 (uint8_t invalid_opcode = UINT8_MAX) const
+ {
+ switch (m_type)
+ {
+ case Opcode::eTypeInvalid: break;
+ case Opcode::eType8: return m_data.inst8;
+ case Opcode::eType16: break;
+ case Opcode::eType16_2: break;
+ case Opcode::eType32: break;
+ case Opcode::eType64: break;
+ case Opcode::eTypeBytes: break;
+ break;
+ }
+ return invalid_opcode;
+ }
+
+ uint16_t
+ GetOpcode16 (uint16_t invalid_opcode = UINT16_MAX) const
+ {
+ switch (m_type)
+ {
+ case Opcode::eTypeInvalid: break;
+ case Opcode::eType8: return m_data.inst8;
+ case Opcode::eType16: return m_data.inst16;
+ case Opcode::eType16_2: break;
+ case Opcode::eType32: break;
+ case Opcode::eType64: break;
+ case Opcode::eTypeBytes: break;
+ }
+ return invalid_opcode;
+ }
+
+ uint32_t
+ GetOpcode32 (uint32_t invalid_opcode = UINT32_MAX) const
+ {
+ switch (m_type)
+ {
+ case Opcode::eTypeInvalid: break;
+ case Opcode::eType8: return m_data.inst8;
+ case Opcode::eType16: return m_data.inst16;
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32: return m_data.inst32;
+ case Opcode::eType64: break;
+ case Opcode::eTypeBytes: break;
+ }
+ return invalid_opcode;
+ }
+
+ uint64_t
+ GetOpcode64 (uint64_t invalid_opcode = UINT64_MAX) const
+ {
+ switch (m_type)
+ {
+ case Opcode::eTypeInvalid: break;
+ case Opcode::eType8: return m_data.inst8;
+ case Opcode::eType16: return m_data.inst16;
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32: return m_data.inst32;
+ case Opcode::eType64: return m_data.inst64;
+ case Opcode::eTypeBytes: break;
+ }
+ return invalid_opcode;
+ }
+
+ void
+ SetOpcode8 (uint8_t inst)
+ {
+ m_type = eType8;
+ m_data.inst8 = inst;
+ }
+
+ void
+ SetOpcode16 (uint16_t inst)
+ {
+ m_type = eType16;
+ m_data.inst16 = inst;
+ }
+
+ void
+ SetOpcode16_2 (uint32_t inst)
+ {
+ m_type = eType16_2;
+ m_data.inst32 = inst;
+ }
+
+ void
+ SetOpcode32 (uint32_t inst)
+ {
+ m_type = eType32;
+ m_data.inst32 = inst;
+ }
+
+ void
+ SetOpcode64 (uint64_t inst)
+ {
+ m_type = eType64;
+ m_data.inst64 = inst;
+ }
+
+ void
+ SetOpcodeBytes (const void *bytes, size_t length)
+ {
+ if (bytes && length > 0)
+ {
+ m_type = eTypeBytes;
+ m_data.inst.length = length;
+ assert (length < sizeof (m_data.inst.bytes));
+ memcpy (m_data.inst.bytes, bytes, length);
+ }
+ else
+ {
+ m_type = eTypeInvalid;
+ m_data.inst.length = 0;
+ }
+ }
+
+ int
+ Dump (Stream *s, uint32_t min_byte_width);
+
+ const void *
+ GetOpcodeBytes () const
+ {
+ if (m_type == Opcode::eTypeBytes)
+ return m_data.inst.bytes;
+ return NULL;
+ }
+
+ uint32_t
+ GetByteSize () const
+ {
+ switch (m_type)
+ {
+ case Opcode::eTypeInvalid: break;
+ case Opcode::eType8: return sizeof(m_data.inst8);
+ case Opcode::eType16: return sizeof(m_data.inst16);
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32: return sizeof(m_data.inst32);
+ case Opcode::eType64: return sizeof(m_data.inst64);
+ case Opcode::eTypeBytes: return m_data.inst.length;
+ }
+ return 0;
+ }
+
+ // Get the opcode exactly as it would be laid out in memory.
+ uint32_t
+ GetData (DataExtractor &data) const;
+
+ protected:
+
+ friend class lldb::SBInstruction;
+
+ const void *
+ GetOpcodeDataBytes () const
+ {
+ switch (m_type)
+ {
+ case Opcode::eTypeInvalid: break;
+ case Opcode::eType8: return &m_data.inst8;
+ case Opcode::eType16: return &m_data.inst16;
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32: return &m_data.inst32;
+ case Opcode::eType64: return &m_data.inst64;
+ case Opcode::eTypeBytes: return m_data.inst.bytes;
+ }
+ return NULL;
+ }
+
+ lldb::ByteOrder
+ GetDataByteOrder () const;
+
+ Opcode::Type m_type;
+ union
+ {
+ uint8_t inst8;
+ uint16_t inst16;
+ uint32_t inst32;
+ uint64_t inst64;
+ struct
+ {
+ uint8_t bytes[16]; // This must be big enough to handle any opcode for any supported target.
+ uint8_t length;
+ } inst;
+ } m_data;
+ };
+
+} // namespace lldb_private
+
+#endif // lldb_Opcode_h
diff --git a/include/lldb/Core/PluginInterface.h b/include/lldb/Core/PluginInterface.h
new file mode 100644
index 000000000000..19371ca98601
--- /dev/null
+++ b/include/lldb/Core/PluginInterface.h
@@ -0,0 +1,37 @@
+//===-- PluginInterface.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_PluginInterface_h_
+#define liblldb_PluginInterface_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class PluginInterface
+{
+public:
+ virtual
+ ~PluginInterface () {}
+
+ virtual ConstString
+ GetPluginName() = 0;
+
+ virtual uint32_t
+ GetPluginVersion() = 0;
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_PluginInterface_h_
diff --git a/include/lldb/Core/PluginManager.h b/include/lldb/Core/PluginManager.h
new file mode 100644
index 000000000000..91f8fbb997f9
--- /dev/null
+++ b/include/lldb/Core/PluginManager.h
@@ -0,0 +1,352 @@
+//===-- PluginManager.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef liblldb_PluginManager_h_
+#define liblldb_PluginManager_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Host/FileSpec.h"
+
+namespace lldb_private {
+
+class PluginManager
+{
+public:
+ static void
+ Initialize ();
+
+ static void
+ Terminate ();
+
+ //------------------------------------------------------------------
+ // ABI
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ ABICreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin (ABICreateInstance create_callback);
+
+ static ABICreateInstance
+ GetABICreateCallbackAtIndex (uint32_t idx);
+
+ static ABICreateInstance
+ GetABICreateCallbackForPluginName (const ConstString &name);
+
+
+ //------------------------------------------------------------------
+ // Disassembler
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ DisassemblerCreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin (DisassemblerCreateInstance create_callback);
+
+ static DisassemblerCreateInstance
+ GetDisassemblerCreateCallbackAtIndex (uint32_t idx);
+
+ static DisassemblerCreateInstance
+ GetDisassemblerCreateCallbackForPluginName (const ConstString &name);
+
+
+ //------------------------------------------------------------------
+ // DynamicLoader
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ DynamicLoaderCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback = NULL);
+
+ static bool
+ UnregisterPlugin (DynamicLoaderCreateInstance create_callback);
+
+ static DynamicLoaderCreateInstance
+ GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx);
+
+ static DynamicLoaderCreateInstance
+ GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name);
+
+ //------------------------------------------------------------------
+ // EmulateInstruction
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ EmulateInstructionCreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin (EmulateInstructionCreateInstance create_callback);
+
+ static EmulateInstructionCreateInstance
+ GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx);
+
+ static EmulateInstructionCreateInstance
+ GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name);
+
+ //------------------------------------------------------------------
+ // OperatingSystem
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ OperatingSystemCreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin (OperatingSystemCreateInstance create_callback);
+
+ static OperatingSystemCreateInstance
+ GetOperatingSystemCreateCallbackAtIndex (uint32_t idx);
+
+ static OperatingSystemCreateInstance
+ GetOperatingSystemCreateCallbackForPluginName (const ConstString &name);
+
+ //------------------------------------------------------------------
+ // LanguageRuntime
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ LanguageRuntimeCreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin (LanguageRuntimeCreateInstance create_callback);
+
+ static LanguageRuntimeCreateInstance
+ GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx);
+
+ static LanguageRuntimeCreateInstance
+ GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name);
+
+
+ //------------------------------------------------------------------
+ // ObjectFile
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ ObjectFileCreateInstance create_callback,
+ ObjectFileCreateMemoryInstance create_memory_callback,
+ ObjectFileGetModuleSpecifications get_module_specifications);
+
+ static bool
+ UnregisterPlugin (ObjectFileCreateInstance create_callback);
+
+ static ObjectFileCreateInstance
+ GetObjectFileCreateCallbackAtIndex (uint32_t idx);
+
+ static ObjectFileCreateMemoryInstance
+ GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx);
+
+ static ObjectFileGetModuleSpecifications
+ GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx);
+
+ static ObjectFileCreateInstance
+ GetObjectFileCreateCallbackForPluginName (const ConstString &name);
+
+ static ObjectFileCreateMemoryInstance
+ GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name);
+
+
+ //------------------------------------------------------------------
+ // ObjectContainer
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ ObjectContainerCreateInstance create_callback,
+ ObjectFileGetModuleSpecifications get_module_specifications);
+
+ static bool
+ UnregisterPlugin (ObjectContainerCreateInstance create_callback);
+
+ static ObjectContainerCreateInstance
+ GetObjectContainerCreateCallbackAtIndex (uint32_t idx);
+
+ static ObjectContainerCreateInstance
+ GetObjectContainerCreateCallbackForPluginName (const ConstString &name);
+
+ static ObjectFileGetModuleSpecifications
+ GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx);
+
+ //------------------------------------------------------------------
+ // LogChannel
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ LogChannelCreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin (LogChannelCreateInstance create_callback);
+
+ static LogChannelCreateInstance
+ GetLogChannelCreateCallbackAtIndex (uint32_t idx);
+
+ static LogChannelCreateInstance
+ GetLogChannelCreateCallbackForPluginName (const ConstString &name);
+
+ static const char *
+ GetLogChannelCreateNameAtIndex (uint32_t idx);
+
+ //------------------------------------------------------------------
+ // Platform
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ PlatformCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback = NULL);
+
+ static bool
+ UnregisterPlugin (PlatformCreateInstance create_callback);
+
+ static PlatformCreateInstance
+ GetPlatformCreateCallbackAtIndex (uint32_t idx);
+
+ static PlatformCreateInstance
+ GetPlatformCreateCallbackForPluginName (const ConstString &name);
+
+ static const char *
+ GetPlatformPluginNameAtIndex (uint32_t idx);
+
+ static const char *
+ GetPlatformPluginDescriptionAtIndex (uint32_t idx);
+
+ static size_t
+ AutoCompletePlatformName (const char *partial_name,
+ StringList &matches);
+ //------------------------------------------------------------------
+ // Process
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ ProcessCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback = NULL);
+
+ static bool
+ UnregisterPlugin (ProcessCreateInstance create_callback);
+
+ static ProcessCreateInstance
+ GetProcessCreateCallbackAtIndex (uint32_t idx);
+
+ static ProcessCreateInstance
+ GetProcessCreateCallbackForPluginName (const ConstString &name);
+
+ static const char *
+ GetProcessPluginNameAtIndex (uint32_t idx);
+
+ static const char *
+ GetProcessPluginDescriptionAtIndex (uint32_t idx);
+
+ //------------------------------------------------------------------
+ // SymbolFile
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ SymbolFileCreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin (SymbolFileCreateInstance create_callback);
+
+ static SymbolFileCreateInstance
+ GetSymbolFileCreateCallbackAtIndex (uint32_t idx);
+
+ static SymbolFileCreateInstance
+ GetSymbolFileCreateCallbackForPluginName (const ConstString &name);
+
+
+ //------------------------------------------------------------------
+ // SymbolVendor
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ SymbolVendorCreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin (SymbolVendorCreateInstance create_callback);
+
+ static SymbolVendorCreateInstance
+ GetSymbolVendorCreateCallbackAtIndex (uint32_t idx);
+
+ static SymbolVendorCreateInstance
+ GetSymbolVendorCreateCallbackForPluginName (const ConstString &name);
+
+ //------------------------------------------------------------------
+ // UnwindAssembly
+ //------------------------------------------------------------------
+ static bool
+ RegisterPlugin (const ConstString &name,
+ const char *description,
+ UnwindAssemblyCreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin (UnwindAssemblyCreateInstance create_callback);
+
+ static UnwindAssemblyCreateInstance
+ GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx);
+
+ static UnwindAssemblyCreateInstance
+ GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name);
+
+ //------------------------------------------------------------------
+ // Some plug-ins might register a DebuggerInitializeCallback
+ // callback when registering the plug-in. After a new Debugger
+ // instance is created, this DebuggerInitialize function will get
+ // called. This allows plug-ins to install Properties and do any
+ // other initialization that requires a debugger instance.
+ //------------------------------------------------------------------
+ static void
+ DebuggerInitialize (Debugger &debugger);
+
+ static lldb::OptionValuePropertiesSP
+ GetSettingForDynamicLoaderPlugin (Debugger &debugger,
+ const ConstString &setting_name);
+
+ static bool
+ CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
+ const lldb::OptionValuePropertiesSP &properties_sp,
+ const ConstString &description,
+ bool is_global_property);
+
+ static lldb::OptionValuePropertiesSP
+ GetSettingForPlatformPlugin (Debugger &debugger,
+ const ConstString &setting_name);
+
+ static bool
+ CreateSettingForPlatformPlugin (Debugger &debugger,
+ const lldb::OptionValuePropertiesSP &properties_sp,
+ const ConstString &description,
+ bool is_global_property);
+
+ static lldb::OptionValuePropertiesSP
+ GetSettingForProcessPlugin (Debugger &debugger,
+ const ConstString &setting_name);
+
+ static bool
+ CreateSettingForProcessPlugin (Debugger &debugger,
+ const lldb::OptionValuePropertiesSP &properties_sp,
+ const ConstString &description,
+ bool is_global_property);
+
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_PluginManager_h_
diff --git a/include/lldb/Core/RangeMap.h b/include/lldb/Core/RangeMap.h
new file mode 100644
index 000000000000..ee42467c18bf
--- /dev/null
+++ b/include/lldb/Core/RangeMap.h
@@ -0,0 +1,1543 @@
+//===-- RangeMap.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RangeMap_h_
+#define liblldb_RangeMap_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "llvm/ADT/SmallVector.h"
+
+// Uncomment to make sure all Range objects are sorted when needed
+//#define ASSERT_RANGEMAP_ARE_SORTED
+
+namespace lldb_private {
+
+
+ //----------------------------------------------------------------------
+ // Templatized classes for dealing with generic ranges and also
+ // collections of ranges, or collections of ranges that have associated
+ // data.
+ //----------------------------------------------------------------------
+
+ //----------------------------------------------------------------------
+ // A simple range class where you get to define the type of the range
+ // base "B", and the type used for the range byte size "S".
+ //----------------------------------------------------------------------
+ template <typename B, typename S>
+ struct Range
+ {
+ typedef B BaseType;
+ typedef S SizeType;
+
+ BaseType base;
+ SizeType size;
+
+ Range () :
+ base (0),
+ size (0)
+ {
+ }
+
+ Range (BaseType b, SizeType s) :
+ base (b),
+ size (s)
+ {
+ }
+
+ void
+ Clear (BaseType b = 0)
+ {
+ base = b;
+ size = 0;
+ }
+
+ // Set the start value for the range, and keep the same size
+ BaseType
+ GetRangeBase () const
+ {
+ return base;
+ }
+
+ void
+ SetRangeBase (BaseType b)
+ {
+ base = b;
+ }
+
+ void
+ Slide (BaseType slide)
+ {
+ base += slide;
+ }
+
+ BaseType
+ GetRangeEnd () const
+ {
+ return base + size;
+ }
+
+ void
+ SetRangeEnd (BaseType end)
+ {
+ if (end > base)
+ size = end - base;
+ else
+ size = 0;
+ }
+
+ SizeType
+ GetByteSize () const
+ {
+ return size;
+ }
+
+ void
+ SetByteSize (SizeType s)
+ {
+ size = s;
+ }
+
+ bool
+ IsValid() const
+ {
+ return size > 0;
+ }
+
+ bool
+ Contains (BaseType r) const
+ {
+ return (GetRangeBase() <= r) && (r < GetRangeEnd());
+ }
+
+ bool
+ ContainsEndInclusive (BaseType r) const
+ {
+ return (GetRangeBase() <= r) && (r <= GetRangeEnd());
+ }
+
+ bool
+ Contains (const Range& range) const
+ {
+ return Contains(range.GetRangeBase()) && ContainsEndInclusive(range.GetRangeEnd());
+ }
+
+ bool
+ Overlap (const Range &rhs) const
+ {
+ const BaseType lhs_base = this->GetRangeBase();
+ const BaseType rhs_base = rhs.GetRangeBase();
+ const BaseType lhs_end = this->GetRangeEnd();
+ const BaseType rhs_end = rhs.GetRangeEnd();
+ bool result = (lhs_base <= rhs_end) && (lhs_end >= rhs_base);
+ return result;
+ }
+
+ bool
+ operator < (const Range &rhs) const
+ {
+ if (base == rhs.base)
+ return size < rhs.size;
+ return base < rhs.base;
+ }
+
+ bool
+ operator == (const Range &rhs) const
+ {
+ return base == rhs.base && size == rhs.size;
+ }
+
+ bool
+ operator != (const Range &rhs) const
+ {
+ return base != rhs.base || size != rhs.size;
+ }
+ };
+
+ //----------------------------------------------------------------------
+ // A range array class where you get to define the type of the ranges
+ // that the collection contains.
+ //----------------------------------------------------------------------
+
+ template <typename B, typename S, unsigned N>
+ class RangeArray
+ {
+ public:
+ typedef B BaseType;
+ typedef S SizeType;
+ typedef Range<B,S> Entry;
+ typedef llvm::SmallVector<Entry, N> Collection;
+
+ RangeArray () :
+ m_entries ()
+ {
+ }
+
+ ~RangeArray()
+ {
+ }
+
+ void
+ Append (const Entry &entry)
+ {
+ m_entries.push_back (entry);
+ }
+
+ bool
+ RemoveEntrtAtIndex (uint32_t idx)
+ {
+ if (idx < m_entries.size())
+ {
+ m_entries.erase (m_entries.begin() + idx);
+ return true;
+ }
+ return false;
+ }
+
+ void
+ Sort ()
+ {
+ if (m_entries.size() > 1)
+ std::stable_sort (m_entries.begin(), m_entries.end());
+ }
+
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ bool
+ IsSorted () const
+ {
+ typename Collection::const_iterator pos, end, prev;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && *pos < *prev)
+ return false;
+ }
+ return true;
+ }
+#endif
+ void
+ CombineConsecutiveRanges ()
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ // Can't combine if ranges if we have zero or one range
+ if (m_entries.size() > 1)
+ {
+ // The list should be sorted prior to calling this function
+ typename Collection::iterator pos;
+ typename Collection::iterator end;
+ typename Collection::iterator prev;
+ bool can_combine = false;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->Overlap(*pos))
+ {
+ can_combine = true;
+ break;
+ }
+ }
+
+ // We we can combine at least one entry, then we make a new collection
+ // and populate it accordingly, and then swap it into place.
+ if (can_combine)
+ {
+ Collection minimal_ranges;
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->Overlap(*pos))
+ minimal_ranges.back().SetRangeEnd (std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd()));
+ else
+ minimal_ranges.push_back (*pos);
+ }
+ // Use the swap technique in case our new vector is much smaller.
+ // We must swap when using the STL because std::vector objects never
+ // release or reduce the memory once it has been allocated/reserved.
+ m_entries.swap (minimal_ranges);
+ }
+ }
+ }
+
+
+ BaseType
+ GetMinRangeBase (BaseType fail_value) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (m_entries.empty())
+ return fail_value;
+ // m_entries must be sorted, so if we aren't empty, we grab the
+ // first range's base
+ return m_entries.front().GetRangeBase();
+ }
+
+ BaseType
+ GetMaxRangeEnd (BaseType fail_value) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (m_entries.empty())
+ return fail_value;
+ // m_entries must be sorted, so if we aren't empty, we grab the
+ // last range's end
+ return m_entries.back().GetRangeEnd();
+ }
+
+ void
+ Slide (BaseType slide)
+ {
+ typename Collection::iterator pos, end;
+ for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos)
+ pos->Slide (slide);
+ }
+
+ void
+ Clear ()
+ {
+ m_entries.clear();
+ }
+
+ bool
+ IsEmpty () const
+ {
+ return m_entries.empty();
+ }
+
+ size_t
+ GetSize () const
+ {
+ return m_entries.size();
+ }
+
+ const Entry *
+ GetEntryAtIndex (size_t i) const
+ {
+ if (i<m_entries.size())
+ return &m_entries[i];
+ return NULL;
+ }
+
+ // Clients must ensure that "i" is a valid index prior to calling this function
+ const Entry &
+ GetEntryRef (size_t i) const
+ {
+ return m_entries[i];
+ }
+
+ Entry *
+ Back()
+ {
+ if (m_entries.empty())
+ return NULL;
+ return &m_entries.back();
+ }
+
+ const Entry *
+ Back() const
+ {
+ if (m_entries.empty())
+ return NULL;
+ return &m_entries.back();
+ }
+
+ static bool
+ BaseLessThan (const Entry& lhs, const Entry& rhs)
+ {
+ return lhs.GetRangeBase() < rhs.GetRangeBase();
+ }
+
+ uint32_t
+ FindEntryIndexThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (!m_entries.empty())
+ {
+ Entry entry (addr, 1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return std::distance (begin, pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ return std::distance (begin, pos);
+ }
+ }
+ return UINT32_MAX;
+ }
+
+ const Entry *
+ FindEntryThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (!m_entries.empty())
+ {
+ Entry entry (addr, 1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ const Entry *
+ FindEntryThatContains (const Entry &range) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (!m_entries.empty())
+ {
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, range, BaseLessThan);
+
+ if (pos != end && pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ protected:
+ Collection m_entries;
+ };
+
+ template <typename B, typename S>
+ class RangeVector
+ {
+ public:
+ typedef B BaseType;
+ typedef S SizeType;
+ typedef Range<B,S> Entry;
+ typedef std::vector<Entry> Collection;
+
+ RangeVector () :
+ m_entries ()
+ {
+ }
+
+ ~RangeVector()
+ {
+ }
+
+ void
+ Append (const Entry &entry)
+ {
+ m_entries.push_back (entry);
+ }
+
+ bool
+ RemoveEntrtAtIndex (uint32_t idx)
+ {
+ if (idx < m_entries.size())
+ {
+ m_entries.erase (m_entries.begin() + idx);
+ return true;
+ }
+ return false;
+ }
+
+ void
+ Sort ()
+ {
+ if (m_entries.size() > 1)
+ std::stable_sort (m_entries.begin(), m_entries.end());
+ }
+
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ bool
+ IsSorted () const
+ {
+ typename Collection::const_iterator pos, end, prev;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && *pos < *prev)
+ return false;
+ }
+ return true;
+ }
+#endif
+ void
+ CombineConsecutiveRanges ()
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ // Can't combine if ranges if we have zero or one range
+ if (m_entries.size() > 1)
+ {
+ // The list should be sorted prior to calling this function
+ typename Collection::iterator pos;
+ typename Collection::iterator end;
+ typename Collection::iterator prev;
+ bool can_combine = false;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->Overlap(*pos))
+ {
+ can_combine = true;
+ break;
+ }
+ }
+
+ // We we can combine at least one entry, then we make a new collection
+ // and populate it accordingly, and then swap it into place.
+ if (can_combine)
+ {
+ Collection minimal_ranges;
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->Overlap(*pos))
+ minimal_ranges.back().SetRangeEnd (std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd()));
+ else
+ minimal_ranges.push_back (*pos);
+ }
+ // Use the swap technique in case our new vector is much smaller.
+ // We must swap when using the STL because std::vector objects never
+ // release or reduce the memory once it has been allocated/reserved.
+ m_entries.swap (minimal_ranges);
+ }
+ }
+ }
+
+
+ BaseType
+ GetMinRangeBase (BaseType fail_value) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (m_entries.empty())
+ return fail_value;
+ // m_entries must be sorted, so if we aren't empty, we grab the
+ // first range's base
+ return m_entries.front().GetRangeBase();
+ }
+
+ BaseType
+ GetMaxRangeEnd (BaseType fail_value) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (m_entries.empty())
+ return fail_value;
+ // m_entries must be sorted, so if we aren't empty, we grab the
+ // last range's end
+ return m_entries.back().GetRangeEnd();
+ }
+
+ void
+ Slide (BaseType slide)
+ {
+ typename Collection::iterator pos, end;
+ for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos)
+ pos->Slide (slide);
+ }
+
+ void
+ Clear ()
+ {
+ m_entries.clear();
+ }
+
+ void
+ Reserve (typename Collection::size_type size)
+ {
+ m_entries.resize (size);
+ }
+
+ bool
+ IsEmpty () const
+ {
+ return m_entries.empty();
+ }
+
+ size_t
+ GetSize () const
+ {
+ return m_entries.size();
+ }
+
+ const Entry *
+ GetEntryAtIndex (size_t i) const
+ {
+ if (i<m_entries.size())
+ return &m_entries[i];
+ return NULL;
+ }
+
+ // Clients must ensure that "i" is a valid index prior to calling this function
+ const Entry &
+ GetEntryRef (size_t i) const
+ {
+ return m_entries[i];
+ }
+
+ Entry *
+ Back()
+ {
+ if (m_entries.empty())
+ return NULL;
+ return &m_entries.back();
+ }
+
+ const Entry *
+ Back() const
+ {
+ if (m_entries.empty())
+ return NULL;
+ return &m_entries.back();
+ }
+
+ static bool
+ BaseLessThan (const Entry& lhs, const Entry& rhs)
+ {
+ return lhs.GetRangeBase() < rhs.GetRangeBase();
+ }
+
+ uint32_t
+ FindEntryIndexThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (!m_entries.empty())
+ {
+ Entry entry (addr, 1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return std::distance (begin, pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ return std::distance (begin, pos);
+ }
+ }
+ return UINT32_MAX;
+ }
+
+ const Entry *
+ FindEntryThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (!m_entries.empty())
+ {
+ Entry entry (addr, 1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ const Entry *
+ FindEntryThatContains (const Entry &range) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (!m_entries.empty())
+ {
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, range, BaseLessThan);
+
+ if (pos != end && pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ protected:
+ Collection m_entries;
+ };
+
+ //----------------------------------------------------------------------
+ // A simple range with data class where you get to define the type of
+ // the range base "B", the type used for the range byte size "S", and
+ // the type for the associated data "T".
+ //----------------------------------------------------------------------
+ template <typename B, typename S, typename T>
+ struct RangeData : public Range<B,S>
+ {
+ typedef T DataType;
+
+ DataType data;
+
+ RangeData () :
+ Range<B,S> (),
+ data ()
+ {
+ }
+
+ RangeData (B base, S size) :
+ Range<B,S> (base, size),
+ data ()
+ {
+ }
+
+ RangeData (B base, S size, DataType d) :
+ Range<B,S> (base, size),
+ data (d)
+ {
+ }
+
+ bool
+ operator < (const RangeData &rhs) const
+ {
+ if (this->base == rhs.base)
+ {
+ if (this->size == rhs.size)
+ return this->data < rhs.data;
+ else
+ return this->size < rhs.size;
+ }
+ return this->base < rhs.base;
+ }
+
+ bool
+ operator == (const RangeData &rhs) const
+ {
+ return this->GetRangeBase() == rhs.GetRangeBase() &&
+ this->GetByteSize() == rhs.GetByteSize() &&
+ this->data == rhs.data;
+ }
+
+ bool
+ operator != (const RangeData &rhs) const
+ {
+ return this->GetRangeBase() != rhs.GetRangeBase() ||
+ this->GetByteSize() != rhs.GetByteSize() ||
+ this->data != rhs.data;
+ }
+ };
+
+ template <typename B, typename S, typename T, unsigned N>
+ class RangeDataArray
+ {
+ public:
+ typedef RangeData<B,S,T> Entry;
+ typedef llvm::SmallVector<Entry, N> Collection;
+
+
+ RangeDataArray ()
+ {
+ }
+
+ ~RangeDataArray()
+ {
+ }
+
+ void
+ Append (const Entry &entry)
+ {
+ m_entries.push_back (entry);
+ }
+
+ void
+ Sort ()
+ {
+ if (m_entries.size() > 1)
+ std::stable_sort (m_entries.begin(), m_entries.end());
+ }
+
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ bool
+ IsSorted () const
+ {
+ typename Collection::const_iterator pos, end, prev;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && *pos < *prev)
+ return false;
+ }
+ return true;
+ }
+#endif
+
+ void
+ CombineConsecutiveEntriesWithEqualData ()
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ typename Collection::iterator pos;
+ typename Collection::iterator end;
+ typename Collection::iterator prev;
+ bool can_combine = false;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->data == pos->data)
+ {
+ can_combine = true;
+ break;
+ }
+ }
+
+ // We we can combine at least one entry, then we make a new collection
+ // and populate it accordingly, and then swap it into place.
+ if (can_combine)
+ {
+ Collection minimal_ranges;
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->data == pos->data)
+ minimal_ranges.back().SetRangeEnd (pos->GetRangeEnd());
+ else
+ minimal_ranges.push_back (*pos);
+ }
+ // Use the swap technique in case our new vector is much smaller.
+ // We must swap when using the STL because std::vector objects never
+ // release or reduce the memory once it has been allocated/reserved.
+ m_entries.swap (minimal_ranges);
+ }
+ }
+
+ void
+ Clear ()
+ {
+ m_entries.clear();
+ }
+
+ bool
+ IsEmpty () const
+ {
+ return m_entries.empty();
+ }
+
+ size_t
+ GetSize () const
+ {
+ return m_entries.size();
+ }
+
+ const Entry *
+ GetEntryAtIndex (size_t i) const
+ {
+ if (i<m_entries.size())
+ return &m_entries[i];
+ return NULL;
+ }
+
+ // Clients must ensure that "i" is a valid index prior to calling this function
+ const Entry &
+ GetEntryRef (size_t i) const
+ {
+ return m_entries[i];
+ }
+
+ static bool
+ BaseLessThan (const Entry& lhs, const Entry& rhs)
+ {
+ return lhs.GetRangeBase() < rhs.GetRangeBase();
+ }
+
+ uint32_t
+ FindEntryIndexThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry (addr, 1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return std::distance (begin, pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ return std::distance (begin, pos);
+ }
+ }
+ return UINT32_MAX;
+ }
+
+ Entry *
+ FindEntryThatContains (B addr)
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry;
+ entry.SetRangeBase(addr);
+ entry.SetByteSize(1);
+ typename Collection::iterator begin = m_entries.begin();
+ typename Collection::iterator end = m_entries.end();
+ typename Collection::iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+ const Entry *
+ FindEntryThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry;
+ entry.SetRangeBase(addr);
+ entry.SetByteSize(1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ const Entry *
+ FindEntryThatContains (const Entry &range) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, range, BaseLessThan);
+
+ if (pos != end && pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ Entry *
+ Back()
+ {
+ if (!m_entries.empty())
+ return &m_entries.back();
+ return NULL;
+ }
+
+ const Entry *
+ Back() const
+ {
+ if (!m_entries.empty())
+ return &m_entries.back();
+ return NULL;
+ }
+
+ protected:
+ Collection m_entries;
+ };
+
+ // Same as RangeDataArray, but uses std::vector as to not
+ // require static storage of N items in the class itself
+ template <typename B, typename S, typename T>
+ class RangeDataVector
+ {
+ public:
+ typedef RangeData<B,S,T> Entry;
+ typedef std::vector<Entry> Collection;
+
+ RangeDataVector ()
+ {
+ }
+
+ ~RangeDataVector()
+ {
+ }
+
+ void
+ Append (const Entry &entry)
+ {
+ m_entries.push_back (entry);
+ }
+
+ void
+ Sort ()
+ {
+ if (m_entries.size() > 1)
+ std::stable_sort (m_entries.begin(), m_entries.end());
+ }
+
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ bool
+ IsSorted () const
+ {
+ typename Collection::const_iterator pos, end, prev;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && *pos < *prev)
+ return false;
+ }
+ return true;
+ }
+#endif
+
+ void
+ CombineConsecutiveEntriesWithEqualData ()
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ typename Collection::iterator pos;
+ typename Collection::iterator end;
+ typename Collection::iterator prev;
+ bool can_combine = false;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->data == pos->data)
+ {
+ can_combine = true;
+ break;
+ }
+ }
+
+ // We we can combine at least one entry, then we make a new collection
+ // and populate it accordingly, and then swap it into place.
+ if (can_combine)
+ {
+ Collection minimal_ranges;
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->data == pos->data)
+ minimal_ranges.back().SetRangeEnd (pos->GetRangeEnd());
+ else
+ minimal_ranges.push_back (*pos);
+ }
+ // Use the swap technique in case our new vector is much smaller.
+ // We must swap when using the STL because std::vector objects never
+ // release or reduce the memory once it has been allocated/reserved.
+ m_entries.swap (minimal_ranges);
+ }
+ }
+
+ // Calculate the byte size of ranges with zero byte sizes by finding
+ // the next entry with a base address > the current base address
+ void
+ CalculateSizesOfZeroByteSizeRanges ()
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ typename Collection::iterator pos;
+ typename Collection::iterator end;
+ typename Collection::iterator next;
+ for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos)
+ {
+ if (pos->GetByteSize() == 0)
+ {
+ // Watch out for multiple entries with same address and make sure
+ // we find an entry that is greater than the current base address
+ // before we use that for the size
+ auto curr_base = pos->GetRangeBase();
+ for (next = pos + 1; next != end; ++next)
+ {
+ auto next_base = next->GetRangeBase();
+ if (next_base > curr_base)
+ {
+ pos->SetByteSize (next_base - curr_base);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ void
+ Clear ()
+ {
+ m_entries.clear();
+ }
+
+ void
+ Reserve (typename Collection::size_type size)
+ {
+ m_entries.resize (size);
+ }
+
+ bool
+ IsEmpty () const
+ {
+ return m_entries.empty();
+ }
+
+ size_t
+ GetSize () const
+ {
+ return m_entries.size();
+ }
+
+ const Entry *
+ GetEntryAtIndex (size_t i) const
+ {
+ if (i<m_entries.size())
+ return &m_entries[i];
+ return NULL;
+ }
+
+ // Clients must ensure that "i" is a valid index prior to calling this function
+ const Entry &
+ GetEntryRef (size_t i) const
+ {
+ return m_entries[i];
+ }
+
+ static bool
+ BaseLessThan (const Entry& lhs, const Entry& rhs)
+ {
+ return lhs.GetRangeBase() < rhs.GetRangeBase();
+ }
+
+ uint32_t
+ FindEntryIndexThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry (addr, 1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return std::distance (begin, pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ return std::distance (begin, pos);
+ }
+ }
+ return UINT32_MAX;
+ }
+
+ Entry *
+ FindEntryThatContains (B addr)
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry;
+ entry.SetRangeBase(addr);
+ entry.SetByteSize(1);
+ typename Collection::iterator begin = m_entries.begin();
+ typename Collection::iterator end = m_entries.end();
+ typename Collection::iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+ const Entry *
+ FindEntryThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry;
+ entry.SetRangeBase(addr);
+ entry.SetByteSize(1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ const Entry *
+ FindEntryThatContains (const Entry &range) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, range, BaseLessThan);
+
+ if (pos != end && pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ Entry *
+ Back()
+ {
+ if (!m_entries.empty())
+ return &m_entries.back();
+ return NULL;
+ }
+
+ const Entry *
+ Back() const
+ {
+ if (!m_entries.empty())
+ return &m_entries.back();
+ return NULL;
+ }
+
+ protected:
+ Collection m_entries;
+ };
+
+
+ //----------------------------------------------------------------------
+ // A simple range with data class where you get to define the type of
+ // the range base "B", the type used for the range byte size "S", and
+ // the type for the associated data "T".
+ //----------------------------------------------------------------------
+ template <typename B, typename T>
+ struct AddressData
+ {
+ typedef B BaseType;
+ typedef T DataType;
+
+ BaseType addr;
+ DataType data;
+
+ AddressData () :
+ addr (),
+ data ()
+ {
+ }
+
+ AddressData (B a, DataType d) :
+ addr (a),
+ data (d)
+ {
+ }
+
+ bool
+ operator < (const AddressData &rhs) const
+ {
+ if (this->addr == rhs.addr)
+ return this->data < rhs.data;
+ return this->addr < rhs.addr;
+ }
+
+ bool
+ operator == (const AddressData &rhs) const
+ {
+ return this->addr == rhs.addr &&
+ this->data == rhs.data;
+ }
+
+ bool
+ operator != (const AddressData &rhs) const
+ {
+ return this->addr != rhs.addr ||
+ this->data == rhs.data;
+ }
+ };
+
+
+ template <typename B, typename T, unsigned N>
+ class AddressDataArray
+ {
+ public:
+ typedef AddressData<B,T> Entry;
+ typedef llvm::SmallVector<Entry, N> Collection;
+
+
+ AddressDataArray ()
+ {
+ }
+
+ ~AddressDataArray()
+ {
+ }
+
+ void
+ Append (const Entry &entry)
+ {
+ m_entries.push_back (entry);
+ }
+
+ void
+ Sort ()
+ {
+ if (m_entries.size() > 1)
+ std::stable_sort (m_entries.begin(), m_entries.end());
+ }
+
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ bool
+ IsSorted () const
+ {
+ typename Collection::const_iterator pos, end, prev;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && *pos < *prev)
+ return false;
+ }
+ return true;
+ }
+#endif
+
+ void
+ Clear ()
+ {
+ m_entries.clear();
+ }
+
+ bool
+ IsEmpty () const
+ {
+ return m_entries.empty();
+ }
+
+ size_t
+ GetSize () const
+ {
+ return m_entries.size();
+ }
+
+ const Entry *
+ GetEntryAtIndex (size_t i) const
+ {
+ if (i<m_entries.size())
+ return &m_entries[i];
+ return NULL;
+ }
+
+ // Clients must ensure that "i" is a valid index prior to calling this function
+ const Entry &
+ GetEntryRef (size_t i) const
+ {
+ return m_entries[i];
+ }
+
+ static bool
+ BaseLessThan (const Entry& lhs, const Entry& rhs)
+ {
+ return lhs.addr < rhs.addr;
+ }
+
+ Entry *
+ FindEntry (B addr, bool exact_match_only)
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry;
+ entry.addr = addr;
+ typename Collection::iterator begin = m_entries.begin();
+ typename Collection::iterator end = m_entries.end();
+ typename Collection::iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end)
+ {
+ if (pos->addr == addr || !exact_match_only)
+ return &(*pos);
+ }
+ }
+ return NULL;
+ }
+
+ const Entry *
+ FindNextEntry (const Entry *entry)
+ {
+ if (entry >= &*m_entries.begin() && entry + 1 < &*m_entries.end())
+ return entry + 1;
+ return NULL;
+ }
+
+ Entry *
+ Back()
+ {
+ if (!m_entries.empty())
+ return &m_entries.back();
+ return NULL;
+ }
+
+ const Entry *
+ Back() const
+ {
+ if (!m_entries.empty())
+ return &m_entries.back();
+ return NULL;
+ }
+
+ protected:
+ Collection m_entries;
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_RangeMap_h_
diff --git a/include/lldb/Core/RegisterValue.h b/include/lldb/Core/RegisterValue.h
new file mode 100644
index 000000000000..cf29cea46d36
--- /dev/null
+++ b/include/lldb/Core/RegisterValue.h
@@ -0,0 +1,406 @@
+//===-- RegisterValue.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_RegisterValue_h
+#define lldb_RegisterValue_h
+
+// C Includes
+#include <string.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Host/Endian.h"
+
+//#define ENABLE_128_BIT_SUPPORT 1
+namespace lldb_private {
+
+ class RegisterValue
+ {
+ public:
+ enum
+ {
+ kMaxRegisterByteSize = 32u
+ };
+ enum Type
+ {
+ eTypeInvalid,
+ eTypeUInt8,
+ eTypeUInt16,
+ eTypeUInt32,
+ eTypeUInt64,
+#if defined (ENABLE_128_BIT_SUPPORT)
+ eTypeUInt128,
+#endif
+ eTypeFloat,
+ eTypeDouble,
+ eTypeLongDouble,
+ eTypeBytes
+ };
+
+ RegisterValue () :
+ m_type (eTypeInvalid)
+ {
+ }
+
+ explicit
+ RegisterValue (uint8_t inst) :
+ m_type (eTypeUInt8)
+ {
+ m_data.uint8 = inst;
+ }
+
+ explicit
+ RegisterValue (uint16_t inst) :
+ m_type (eTypeUInt16)
+ {
+ m_data.uint16 = inst;
+ }
+
+ explicit
+ RegisterValue (uint32_t inst) :
+ m_type (eTypeUInt32)
+ {
+ m_data.uint32 = inst;
+ }
+
+ explicit
+ RegisterValue (uint64_t inst) :
+ m_type (eTypeUInt64)
+ {
+ m_data.uint64 = inst;
+ }
+
+#if defined (ENABLE_128_BIT_SUPPORT)
+ explicit
+ RegisterValue (__uint128_t inst) :
+ m_type (eTypeUInt128)
+ {
+ m_data.uint128 = inst;
+ }
+#endif
+ explicit
+ RegisterValue (float value) :
+ m_type (eTypeFloat)
+ {
+ m_data.ieee_float = value;
+ }
+
+ explicit
+ RegisterValue (double value) :
+ m_type (eTypeDouble)
+ {
+ m_data.ieee_double = value;
+ }
+
+ explicit
+ RegisterValue (long double value) :
+ m_type (eTypeLongDouble)
+ {
+ m_data.ieee_long_double = value;
+ }
+
+ explicit
+ RegisterValue (uint8_t *bytes, size_t length, lldb::ByteOrder byte_order)
+ {
+ SetBytes (bytes, length, byte_order);
+ }
+
+ RegisterValue::Type
+ GetType () const
+ {
+ return m_type;
+ }
+
+ bool
+ CopyValue (const RegisterValue &rhs);
+
+ void
+ SetType (RegisterValue::Type type)
+ {
+ m_type = type;
+ }
+
+ RegisterValue::Type
+ SetType (const RegisterInfo *reg_info);
+
+ bool
+ GetData (DataExtractor &data) const;
+
+ // Copy the register value from this object into a buffer in "dst"
+ // and obey the "dst_byte_order" when copying the data. Also watch out
+ // in case "dst_len" is longer or shorter than the register value
+ // described by "reg_info" and only copy the least significant bytes
+ // of the register value, or pad the destination with zeroes if the
+ // register byte size is shorter that "dst_len" (all while correctly
+ // abiding the "dst_byte_order"). Returns the number of bytes copied
+ // into "dst".
+ uint32_t
+ GetAsMemoryData (const RegisterInfo *reg_info,
+ void *dst,
+ uint32_t dst_len,
+ lldb::ByteOrder dst_byte_order,
+ Error &error) const;
+
+ uint32_t
+ SetFromMemoryData (const RegisterInfo *reg_info,
+ const void *src,
+ uint32_t src_len,
+ lldb::ByteOrder src_byte_order,
+ Error &error);
+
+ bool
+ GetScalarValue (Scalar &scalar) const;
+
+ uint8_t
+ GetAsUInt8 (uint8_t fail_value = UINT8_MAX, bool *success_ptr = NULL) const
+ {
+ if (m_type == eTypeUInt8)
+ {
+ if (success_ptr)
+ *success_ptr = true;
+ return m_data.uint8;
+ }
+ if (success_ptr)
+ *success_ptr = true;
+ return fail_value;
+ }
+
+ uint16_t
+ GetAsUInt16 (uint16_t fail_value = UINT16_MAX, bool *success_ptr = NULL) const;
+
+ uint32_t
+ GetAsUInt32 (uint32_t fail_value = UINT32_MAX, bool *success_ptr = NULL) const;
+
+ uint64_t
+ GetAsUInt64 (uint64_t fail_value = UINT64_MAX, bool *success_ptr = NULL) const;
+
+#if defined (ENABLE_128_BIT_SUPPORT)
+ __uint128_t
+ GetAsUInt128 (__uint128_t fail_value = ~((__uint128_t)0), bool *success_ptr = NULL) const;
+#endif
+
+ float
+ GetAsFloat (float fail_value = 0.0f, bool *success_ptr = NULL) const;
+
+ double
+ GetAsDouble (double fail_value = 0.0, bool *success_ptr = NULL) const;
+
+ long double
+ GetAsLongDouble (long double fail_value = 0.0, bool *success_ptr = NULL) const;
+
+ void
+ SetValueToInvalid ()
+ {
+ m_type = eTypeInvalid;
+ }
+
+ bool
+ ClearBit (uint32_t bit);
+
+ bool
+ SetBit (uint32_t bit);
+
+ bool
+ operator == (const RegisterValue &rhs) const;
+
+ bool
+ operator != (const RegisterValue &rhs) const;
+
+ void
+ operator = (uint8_t uint)
+ {
+ m_type = eTypeUInt8;
+ m_data.uint8 = uint;
+ }
+
+ void
+ operator = (uint16_t uint)
+ {
+ m_type = eTypeUInt16;
+ m_data.uint16 = uint;
+ }
+
+ void
+ operator = (uint32_t uint)
+ {
+ m_type = eTypeUInt32;
+ m_data.uint32 = uint;
+ }
+
+ void
+ operator = (uint64_t uint)
+ {
+ m_type = eTypeUInt64;
+ m_data.uint64 = uint;
+ }
+
+#if defined (ENABLE_128_BIT_SUPPORT)
+ void
+ operator = (__uint128_t uint)
+ {
+ m_type = eTypeUInt128;
+ m_data.uint128 = uint;
+ }
+#endif
+ void
+ operator = (float f)
+ {
+ m_type = eTypeFloat;
+ m_data.ieee_float = f;
+ }
+
+ void
+ operator = (double f)
+ {
+ m_type = eTypeDouble;
+ m_data.ieee_double = f;
+ }
+
+ void
+ operator = (long double f)
+ {
+ m_type = eTypeLongDouble;
+ m_data.ieee_long_double = f;
+ }
+
+ void
+ SetUInt8 (uint8_t uint)
+ {
+ m_type = eTypeUInt8;
+ m_data.uint8 = uint;
+ }
+
+ void
+ SetUInt16 (uint16_t uint)
+ {
+ m_type = eTypeUInt16;
+ m_data.uint16 = uint;
+ }
+
+ void
+ SetUInt32 (uint32_t uint, Type t = eTypeUInt32)
+ {
+ m_type = t;
+ m_data.uint32 = uint;
+ }
+
+ void
+ SetUInt64 (uint64_t uint, Type t = eTypeUInt64)
+ {
+ m_type = t;
+ m_data.uint64 = uint;
+ }
+
+#if defined (ENABLE_128_BIT_SUPPORT)
+ void
+ SetUInt128 (__uint128_t uint)
+ {
+ m_type = eTypeUInt128;
+ m_data.uint128 = uint;
+ }
+#endif
+ bool
+ SetUInt (uint64_t uint, uint32_t byte_size);
+
+ void
+ SetFloat (float f)
+ {
+ m_type = eTypeFloat;
+ m_data.ieee_float = f;
+ }
+
+ void
+ SetDouble (double f)
+ {
+ m_type = eTypeDouble;
+ m_data.ieee_double = f;
+ }
+
+ void
+ SetLongDouble (long double f)
+ {
+ m_type = eTypeLongDouble;
+ m_data.ieee_long_double = f;
+ }
+
+ void
+ SetBytes (const void *bytes, size_t length, lldb::ByteOrder byte_order);
+
+ bool
+ SignExtend (uint32_t sign_bitpos);
+
+ Error
+ SetValueFromCString (const RegisterInfo *reg_info,
+ const char *value_str);
+
+ Error
+ SetValueFromData (const RegisterInfo *reg_info,
+ DataExtractor &data,
+ lldb::offset_t offset,
+ bool partial_data_ok);
+
+ // The default value of 0 for reg_name_right_align_at means no alignment at all.
+ bool
+ Dump (Stream *s,
+ const RegisterInfo *reg_info,
+ bool prefix_with_name,
+ bool prefix_with_alt_name,
+ lldb::Format format,
+ uint32_t reg_name_right_align_at = 0) const;
+
+ void *
+ GetBytes ();
+
+ const void *
+ GetBytes () const;
+
+ lldb::ByteOrder
+ GetByteOrder () const
+ {
+ if (m_type == eTypeBytes)
+ return m_data.buffer.byte_order;
+ return lldb::endian::InlHostByteOrder();
+ }
+
+ uint32_t
+ GetByteSize () const;
+
+ void
+ Clear();
+
+ protected:
+
+ RegisterValue::Type m_type;
+ union
+ {
+ uint8_t uint8;
+ uint16_t uint16;
+ uint32_t uint32;
+ uint64_t uint64;
+#if defined (ENABLE_128_BIT_SUPPORT)
+ __uint128_t uint128;
+#endif
+ float ieee_float;
+ double ieee_double;
+ long double ieee_long_double;
+ struct
+ {
+ uint8_t bytes[kMaxRegisterByteSize]; // This must be big enough to hold any register for any supported target.
+ uint8_t length;
+ lldb::ByteOrder byte_order;
+ } buffer;
+ } m_data;
+ };
+
+} // namespace lldb_private
+
+#endif // lldb_RegisterValue_h
diff --git a/include/lldb/Core/RegularExpression.h b/include/lldb/Core/RegularExpression.h
new file mode 100644
index 000000000000..eeeb914bfa90
--- /dev/null
+++ b/include/lldb/Core/RegularExpression.h
@@ -0,0 +1,253 @@
+//===-- RegularExpression.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DBRegex_h_
+#define liblldb_DBRegex_h_
+#if defined(__cplusplus)
+
+#include <regex.h>
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+namespace llvm
+{
+ class StringRef;
+}
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class RegularExpression RegularExpression.h "lldb/Core/RegularExpression.h"
+/// @brief A C++ wrapper class for regex.
+///
+/// This regular expression class wraps the posix regex functions
+/// \c regcomp(), \c regerror(), \c regexec(), and \c regfree() from
+/// the header file in \c /usr/include/regex\.h.
+//----------------------------------------------------------------------
+class RegularExpression
+{
+public:
+ class Match
+ {
+ public:
+ Match (uint32_t max_matches) :
+ m_matches ()
+ {
+ if (max_matches > 0)
+ m_matches.resize(max_matches + 1);
+ }
+
+ void
+ Clear()
+ {
+ const size_t num_matches = m_matches.size();
+ regmatch_t invalid_match = { -1, -1 };
+ for (size_t i=0; i<num_matches; ++i)
+ m_matches[i] = invalid_match;
+ }
+
+ size_t
+ GetSize () const
+ {
+ return m_matches.size();
+ }
+
+ regmatch_t *
+ GetData ()
+ {
+ if (m_matches.empty())
+ return NULL;
+ return m_matches.data();
+ }
+
+ bool
+ GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const;
+
+ bool
+ GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const;
+
+ bool
+ GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const;
+
+ protected:
+
+ std::vector<regmatch_t> m_matches; ///< Where parenthesized subexpressions results are stored
+ };
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// The default constructor that initializes the object state such
+ /// that it contains no compiled regular expression.
+ //------------------------------------------------------------------
+ RegularExpression ();
+
+ //------------------------------------------------------------------
+ /// Constructor that takes a regulare expression with flags.
+ ///
+ /// Constructor that compiles \a re using \a flags and stores the
+ /// resulting compiled regular expression into this object.
+ ///
+ /// @param[in] re
+ /// A c string that represents the regular expression to
+ /// compile.
+ ///
+ /// @param[in] flags
+ /// Flags that are passed the the \c regcomp() function.
+ //------------------------------------------------------------------
+ explicit
+ RegularExpression (const char* re, int flags);
+
+ // This one uses flags = REG_EXTENDED.
+ explicit
+ RegularExpression (const char* re);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// Any previosuly compiled regular expression contained in this
+ /// object will be freed.
+ //------------------------------------------------------------------
+ ~RegularExpression ();
+
+ RegularExpression (const RegularExpression &rhs);
+
+ const RegularExpression & operator=(const RegularExpression &rhs);
+
+ //------------------------------------------------------------------
+ /// Compile a regular expression.
+ ///
+ /// Compile a regular expression using the supplied regular
+ /// expression text and flags. The compied regular expression lives
+ /// in this object so that it can be readily used for regular
+ /// expression matches. Execute() can be called after the regular
+ /// expression is compiled. Any previosuly compiled regular
+ /// expression contained in this object will be freed.
+ ///
+ /// @param[in] re
+ /// A NULL terminated C string that represents the regular
+ /// expression to compile.
+ ///
+ /// @param[in] flags
+ /// Flags that are passed the the \c regcomp() function.
+ ///
+ /// @return
+ /// \b true if the regular expression compiles successfully,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Compile (const char* re);
+
+ bool
+ Compile (const char* re, int flags);
+
+ //------------------------------------------------------------------
+ /// Executes a regular expression.
+ ///
+ /// Execute a regular expression match using the compiled regular
+ /// expression that is already in this object against the match
+ /// string \a s. If any parens are used for regular expression
+ /// matches \a match_count should indicate the number of regmatch_t
+ /// values that are present in \a match_ptr. The regular expression
+ /// will be executed using the \a execute_flags
+ ///
+ /// @param[in] string
+ /// The string to match against the compile regular expression.
+ ///
+ /// @param[in] match
+ /// A pointer to a RegularExpression::Match structure that was
+ /// properly initialized with the desired number of maximum
+ /// matches, or NULL if no parenthesized matching is needed.
+ ///
+ /// @param[in] execute_flags
+ /// Flags to pass to the \c regexec() function.
+ ///
+ /// @return
+ /// \b true if \a string matches the compiled regular
+ /// expression, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Execute (const char* string, Match *match = NULL, int execute_flags = 0) const;
+
+ size_t
+ GetErrorAsCString (char *err_str, size_t err_str_max_len) const;
+
+ //------------------------------------------------------------------
+ /// Free the compiled regular expression.
+ ///
+ /// If this object contains a valid compiled regular expression,
+ /// this function will free any resources it was consuming.
+ //------------------------------------------------------------------
+ void
+ Free ();
+
+ //------------------------------------------------------------------
+ /// Access the regular expression text.
+ ///
+ /// Returns the text that was used to compile the current regular
+ /// expression.
+ ///
+ /// @return
+ /// The NULL terminated C string that was used to compile the
+ /// current regular expression
+ //------------------------------------------------------------------
+ const char*
+ GetText () const;
+
+ int
+ GetCompileFlags () const
+ {
+ return m_compile_flags;
+ }
+
+ //------------------------------------------------------------------
+ /// Test if valid.
+ ///
+ /// Test if this object contains a valid regular expression.
+ ///
+ /// @return
+ /// \b true if the regular expression compiled and is ready
+ /// for execution, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsValid () const;
+
+ void
+ Clear ()
+ {
+ Free();
+ m_re.clear();
+ m_compile_flags = 0;
+ m_comp_err = 1;
+ }
+
+ int
+ GetErrorCode() const
+ {
+ return m_comp_err;
+ }
+
+ bool
+ operator < (const RegularExpression& rhs) const;
+
+private:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ std::string m_re; ///< A copy of the original regular expression text
+ int m_comp_err; ///< Error code for the regular expression compilation
+ regex_t m_preg; ///< The compiled regular expression
+ int m_compile_flags; ///< Stores the flags from the last compile.
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_DBRegex_h_
diff --git a/include/lldb/Core/STLUtils.h b/include/lldb/Core/STLUtils.h
new file mode 100644
index 000000000000..9321e057a397
--- /dev/null
+++ b/include/lldb/Core/STLUtils.h
@@ -0,0 +1,94 @@
+//===-- STLUtils.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_STLUtils_h_
+#define liblldb_STLUtils_h_
+#if defined(__cplusplus)
+
+#include <string.h>
+
+#include <map>
+#include <ostream>
+#include <vector>
+
+//----------------------------------------------------------------------
+// C string less than compare function object
+//----------------------------------------------------------------------
+struct CStringCompareFunctionObject
+{
+ bool operator() (const char* s1, const char* s2) const
+ {
+ return strcmp(s1, s2) < 0;
+ }
+};
+
+
+//----------------------------------------------------------------------
+// C string equality function object (binary predicate).
+//----------------------------------------------------------------------
+struct CStringEqualBinaryPredicate
+{
+ bool operator()(const char* s1, const char* s2) const
+ {
+ return strcmp(s1, s2) == 0;
+ }
+};
+
+
+//----------------------------------------------------------------------
+// Templated type for finding an entry in a std::map<F,S> whose value
+// is equal to something
+//----------------------------------------------------------------------
+template <class F, class S>
+class ValueEquals
+{
+private:
+ S second_value;
+
+public:
+ ValueEquals (const S& val) : second_value(val)
+ {}
+ // Compare the second item
+ bool operator() (std::pair<const F, S> elem)
+ {
+ return elem.second == second_value;
+ }
+};
+
+template <class T>
+inline void PrintAllCollectionElements (std::ostream &s, const T& coll, const char* header_cstr=NULL, const char* separator_cstr=" ")
+{
+ typename T::const_iterator pos;
+
+ if (header_cstr)
+ s << header_cstr;
+ for (pos=coll.begin(); pos!=coll.end(); ++pos) {
+ s << *pos << separator_cstr;
+ }
+ s << std::endl;
+}
+
+// The function object below can be used to delete a STL container that
+// contains C++ object pointers.
+//
+// Usage: std::for_each(vector.begin(), vector.end(), for_each_delete());
+
+struct for_each_cplusplus_delete
+{
+ template <typename T>
+ void operator()(T *ptr){ delete ptr;}
+};
+
+typedef std::vector<std::string> STLStringArray;
+typedef std::vector<const char *> CStringArray;
+
+
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_STLUtils_h_
diff --git a/include/lldb/Core/Scalar.h b/include/lldb/Core/Scalar.h
new file mode 100644
index 000000000000..821a0fb1ae21
--- /dev/null
+++ b/include/lldb/Core/Scalar.h
@@ -0,0 +1,341 @@
+//===-- Scalar.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Scalar_h_
+#define liblldb_Scalar_h_
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A class designed to hold onto values and their corresponding types.
+// Operators are defined and Scalar objects will correctly promote
+// their types and values before performing these operations. Type
+// promotion currently follows the ANSI C type promotion rules.
+//----------------------------------------------------------------------
+class Scalar
+{
+public:
+ enum Type
+ {
+ e_void = 0,
+ e_sint,
+ e_uint,
+ e_slong,
+ e_ulong,
+ e_slonglong,
+ e_ulonglong,
+ e_float,
+ e_double,
+ e_long_double
+ };
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ Scalar();
+ Scalar(int v) : m_type(e_sint), m_data() { m_data.sint = v; }
+ Scalar(unsigned int v) : m_type(e_uint), m_data() { m_data.uint = v; }
+ Scalar(long v) : m_type(e_slong), m_data() { m_data.slong = v; }
+ Scalar(unsigned long v) : m_type(e_ulong), m_data() { m_data.ulong = v; }
+ Scalar(long long v) : m_type(e_slonglong), m_data() { m_data.slonglong = v; }
+ Scalar(unsigned long long v): m_type(e_ulonglong), m_data() { m_data.ulonglong = v; }
+ Scalar(float v) : m_type(e_float), m_data() { m_data.flt = v; }
+ Scalar(double v) : m_type(e_double), m_data() { m_data.dbl = v; }
+ Scalar(long double v) : m_type(e_long_double), m_data() { m_data.ldbl = v; }
+ Scalar(const Scalar& rhs);
+ //Scalar(const RegisterValue& reg_value);
+ virtual ~Scalar();
+
+ bool
+ SignExtend (uint32_t bit_pos);
+
+ bool
+ ExtractBitfield (uint32_t bit_size,
+ uint32_t bit_offset);
+
+ size_t
+ GetByteSize() const;
+
+ static size_t
+ GetMaxByteSize()
+ {
+ return sizeof(ValueData);
+ }
+
+ bool
+ GetData (DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const;
+
+ size_t
+ GetAsMemoryData (void *dst,
+ size_t dst_len,
+ lldb::ByteOrder dst_byte_order,
+ Error &error) const;
+
+ bool
+ IsZero() const;
+
+ void
+ Clear() { m_type = e_void; m_data.ulonglong = 0; }
+
+ const char *
+ GetTypeAsCString() const;
+
+ void
+ GetValue (Stream *s, bool show_type) const;
+
+ bool
+ IsValid() const
+ {
+ return (m_type >= e_sint) && (m_type <= e_long_double);
+ }
+
+ bool
+ Promote(Scalar::Type type);
+
+ bool
+ Cast (Scalar::Type type);
+
+ bool
+ MakeSigned ();
+
+ static const char *
+ GetValueTypeAsCString (Scalar::Type value_type);
+
+ static Scalar::Type
+ GetValueTypeForSignedIntegerWithByteSize (size_t byte_size);
+
+ static Scalar::Type
+ GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size);
+
+ static Scalar::Type
+ GetValueTypeForFloatWithByteSize (size_t byte_size);
+
+ //----------------------------------------------------------------------
+ // All operators can benefits from the implicit conversions that will
+ // happen automagically by the compiler, so no temporary objects will
+ // need to be created. As a result, we currently don't need a variety of
+ // overloaded set value accessors.
+ //----------------------------------------------------------------------
+ Scalar& operator= (const int i);
+ Scalar& operator= (unsigned int v);
+ Scalar& operator= (long v);
+ Scalar& operator= (unsigned long v);
+ Scalar& operator= (long long v);
+ Scalar& operator= (unsigned long long v);
+ Scalar& operator= (float v);
+ Scalar& operator= (double v);
+ Scalar& operator= (long double v);
+ Scalar& operator= (const Scalar& rhs); // Assignment operator
+ Scalar& operator+= (const Scalar& rhs);
+ Scalar& operator<<= (const Scalar& rhs); // Shift left
+ Scalar& operator>>= (const Scalar& rhs); // Shift right (arithmetic)
+ Scalar& operator&= (const Scalar& rhs);
+
+ //----------------------------------------------------------------------
+ // Shifts the current value to the right without maintaining the current
+ // sign of the value (if it is signed).
+ //----------------------------------------------------------------------
+ bool
+ ShiftRightLogical(const Scalar& rhs); // Returns true on success
+
+ //----------------------------------------------------------------------
+ // Takes the absolute value of the current value if it is signed, else
+ // the value remains unchanged.
+ // Returns false if the contained value has a void type.
+ //----------------------------------------------------------------------
+ bool
+ AbsoluteValue(); // Returns true on success
+ //----------------------------------------------------------------------
+ // Negates the current value (even for unsigned values).
+ // Returns false if the contained value has a void type.
+ //----------------------------------------------------------------------
+ bool
+ UnaryNegate(); // Returns true on success
+ //----------------------------------------------------------------------
+ // Inverts all bits in the current value as long as it isn't void or
+ // a float/double/long double type.
+ // Returns false if the contained value has a void/float/double/long
+ // double type, else the value is inverted and true is returned.
+ //----------------------------------------------------------------------
+ bool
+ OnesComplement(); // Returns true on success
+
+ //----------------------------------------------------------------------
+ // Access the type of the current value.
+ //----------------------------------------------------------------------
+ Scalar::Type
+ GetType() const { return m_type; }
+
+ //----------------------------------------------------------------------
+ // Returns a casted value of the current contained data without
+ // modifying the current value. FAIL_VALUE will be returned if the type
+ // of the value is void or invalid.
+ //----------------------------------------------------------------------
+ int
+ SInt(int fail_value = 0) const;
+
+ // Return the raw unsigned integer without any casting or conversion
+ unsigned int
+ RawUInt () const;
+
+ // Return the raw unsigned long without any casting or conversion
+ unsigned long
+ RawULong () const;
+
+ // Return the raw unsigned long long without any casting or conversion
+ unsigned long long
+ RawULongLong () const;
+
+ unsigned int
+ UInt(unsigned int fail_value = 0) const;
+
+ long
+ SLong(long fail_value = 0) const;
+
+ unsigned long
+ ULong(unsigned long fail_value = 0) const;
+
+ long long
+ SLongLong(long long fail_value = 0) const;
+
+ unsigned long long
+ ULongLong(unsigned long long fail_value = 0) const;
+
+ float
+ Float(float fail_value = 0.0f) const;
+
+ double
+ Double(double fail_value = 0.0) const;
+
+ long double
+ LongDouble(long double fail_value = 0.0) const;
+
+ uint64_t
+ GetRawBits64 (uint64_t fail_value) const;
+
+ Error
+ SetValueFromCString (const char *s, lldb::Encoding encoding, size_t byte_size);
+
+ Error
+ SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t byte_size);
+
+ static bool
+ UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
+ {
+ if (total_byte_size > 8)
+ return false;
+
+ if (total_byte_size == 8)
+ return true;
+
+ const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
+ return uval64 <= max;
+ }
+
+ static bool
+ SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
+ {
+ if (total_byte_size > 8)
+ return false;
+
+ if (total_byte_size == 8)
+ return true;
+
+ const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
+ const int64_t min = ~(max);
+ return min <= sval64 && sval64 <= max;
+ }
+
+protected:
+ typedef int sint_t;
+ typedef unsigned int uint_t;
+ typedef long slong_t;
+ typedef unsigned long ulong_t;
+ typedef long long slonglong_t;
+ typedef unsigned long long ulonglong_t;
+ typedef float float_t;
+ typedef double double_t;
+ typedef long double long_double_t;
+
+ union ValueData
+ {
+ int sint;
+ unsigned int uint;
+ long slong;
+ unsigned long ulong;
+ long long slonglong;
+ unsigned long long ulonglong;
+ float flt;
+ double dbl;
+ long double ldbl;
+ };
+
+ //------------------------------------------------------------------
+ // Classes that inherit from Scalar can see and modify these
+ //------------------------------------------------------------------
+ Scalar::Type m_type;
+ ValueData m_data;
+
+private:
+ friend const Scalar operator+ (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator- (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator/ (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator* (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator& (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator| (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator% (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator^ (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator<< (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator>> (const Scalar& lhs, const Scalar& rhs);
+ friend bool operator== (const Scalar& lhs, const Scalar& rhs);
+ friend bool operator!= (const Scalar& lhs, const Scalar& rhs);
+ friend bool operator< (const Scalar& lhs, const Scalar& rhs);
+ friend bool operator<= (const Scalar& lhs, const Scalar& rhs);
+ friend bool operator> (const Scalar& lhs, const Scalar& rhs);
+ friend bool operator>= (const Scalar& lhs, const Scalar& rhs);
+
+};
+
+//----------------------------------------------------------------------
+// Split out the operators into a format where the compiler will be able
+// to implicitly convert numbers into Scalar objects.
+//
+// This allows code like:
+// Scalar two(2);
+// Scalar four = two * 2;
+// Scalar eight = 2 * four; // This would cause an error if the
+// // operator* was implemented as a
+// // member function.
+// SEE:
+// Item 19 of "Effective C++ Second Edition" by Scott Meyers
+// Differentiate among members functions, non-member functions, and
+// friend functions
+//----------------------------------------------------------------------
+const Scalar operator+ (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator- (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator/ (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator* (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator& (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator| (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator% (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator^ (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator<< (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator>> (const Scalar& lhs, const Scalar& rhs);
+bool operator== (const Scalar& lhs, const Scalar& rhs);
+bool operator!= (const Scalar& lhs, const Scalar& rhs);
+bool operator< (const Scalar& lhs, const Scalar& rhs);
+bool operator<= (const Scalar& lhs, const Scalar& rhs);
+bool operator> (const Scalar& lhs, const Scalar& rhs);
+bool operator>= (const Scalar& lhs, const Scalar& rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_Scalar_h_
diff --git a/include/lldb/Core/SearchFilter.h b/include/lldb/Core/SearchFilter.h
new file mode 100644
index 000000000000..57f1b9c1a0a5
--- /dev/null
+++ b/include/lldb/Core/SearchFilter.h
@@ -0,0 +1,447 @@
+//===-- SearchFilter.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SearchFilter_h_
+#define liblldb_SearchFilter_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/FileSpecList.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Searcher SearchFilter.h "lldb/Core/SearchFilter.h"
+/// @brief Class that is driven by the SearchFilter to search the
+/// SymbolContext space of the target program.
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+/// General Outline:
+/// Provides the callback and search depth for the SearchFilter search.
+//----------------------------------------------------------------------
+
+class Searcher
+{
+public:
+ typedef enum {
+ eCallbackReturnStop = 0, // Stop the iteration
+ eCallbackReturnContinue, // Continue the iteration
+ eCallbackReturnPop // Pop one level up and continue iterating
+ } CallbackReturn;
+
+ typedef enum {
+ eDepthTarget,
+ eDepthModule,
+ eDepthCompUnit,
+ eDepthFunction,
+ eDepthBlock,
+ eDepthAddress
+ } Depth;
+
+ Searcher ();
+
+ virtual ~Searcher ();
+
+ virtual CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool complete) = 0;
+
+ virtual Depth
+ GetDepth () = 0;
+
+ //------------------------------------------------------------------
+ /// Prints a canonical description for the searcher to the stream \a s.
+ ///
+ /// @param[in] s
+ /// Stream to which the output is copied.
+ //------------------------------------------------------------------
+ virtual void
+ GetDescription(Stream *s);
+};
+
+//----------------------------------------------------------------------
+/// @class SearchFilter SearchFilter.h "lldb/Core/SearchFilter.h"
+/// @brief Class descends through the SymbolContext space of the target,
+/// applying a filter at each stage till it reaches the depth specified by
+/// the GetDepth method of the searcher, and calls its callback at that point.
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+/// General Outline:
+/// Provides the callback and search depth for the SearchFilter search.
+///
+/// The search is done by cooperation between the search filter and the searcher.
+/// The search filter does the heavy work of recursing through the SymbolContext
+/// space of the target program's symbol space. The Searcher specifies the depth
+/// at which it wants its callback to be invoked. Note that since the resolution
+/// of the Searcher may be greater than that of the SearchFilter, before the
+/// Searcher qualifies an address it should pass it to "AddressPasses."
+/// The default implementation is "Everything Passes."
+//----------------------------------------------------------------------
+
+class SearchFilter
+{
+public:
+
+ //------------------------------------------------------------------
+ /// The basic constructor takes a Target, which gives the space to search.
+ ///
+ /// @param[in] target
+ /// The Target that provides the module list to search.
+ //------------------------------------------------------------------
+ SearchFilter (const lldb::TargetSP &target_sp);
+
+ SearchFilter (const SearchFilter& rhs);
+
+ virtual
+ ~SearchFilter ();
+
+ const SearchFilter&
+ operator=(const SearchFilter& rhs);
+
+ //------------------------------------------------------------------
+ /// Call this method with a file spec to see if that spec passes the filter.
+ ///
+ /// @param[in] spec
+ /// The file spec to check against the filter.
+ /// @return
+ /// \b true if \a spec passes, and \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ ModulePasses (const FileSpec &spec);
+
+ //------------------------------------------------------------------
+ /// Call this method with a Module to see if that module passes the filter.
+ ///
+ /// @param[in] module
+ /// The Module to check against the filter.
+ ///
+ /// @return
+ /// \b true if \a module passes, and \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ ModulePasses (const lldb::ModuleSP &module_sp);
+
+ //------------------------------------------------------------------
+ /// Call this method with a Address to see if \a address passes the filter.
+ ///
+ /// @param[in] addr
+ /// The address to check against the filter.
+ ///
+ /// @return
+ /// \b true if \a address passes, and \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ AddressPasses (Address &addr);
+
+ //------------------------------------------------------------------
+ /// Call this method with a FileSpec to see if \a file spec passes the filter
+ /// as the name of a compilation unit.
+ ///
+ /// @param[in] fileSpec
+ /// The file spec to check against the filter.
+ ///
+ /// @return
+ /// \b true if \a file spec passes, and \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ CompUnitPasses (FileSpec &fileSpec);
+
+ //------------------------------------------------------------------
+ /// Call this method with a CompileUnit to see if \a comp unit passes the filter.
+ ///
+ /// @param[in] compUnit
+ /// The CompileUnit to check against the filter.
+ ///
+ /// @return
+ /// \b true if \a Comp Unit passes, and \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ CompUnitPasses (CompileUnit &compUnit);
+
+ //------------------------------------------------------------------
+ /// Call this method to do the search using the Searcher.
+ ///
+ /// @param[in] searcher
+ /// The searcher to drive with this search.
+ ///
+ //------------------------------------------------------------------
+ virtual void
+ Search (Searcher &searcher);
+
+ //------------------------------------------------------------------
+ /// Call this method to do the search using the Searcher in the module list
+ /// \a modules.
+ ///
+ /// @param[in] searcher
+ /// The searcher to drive with this search.
+ ///
+ /// @param[in] modules
+ /// The module list within which to restrict the search.
+ ///
+ //------------------------------------------------------------------
+ virtual void
+ SearchInModuleList (Searcher &searcher, ModuleList &modules);
+
+ //------------------------------------------------------------------
+ /// This determines which items are REQUIRED for the filter to pass.
+ /// For instance, if you are filtering by Compilation Unit, obviously
+ /// symbols that have no compilation unit can't pass So return eSymbolContextCU
+ /// and search callbacks can then short cut the search to avoid looking at
+ /// things that obviously won't pass.
+ ///
+ /// @return
+ /// The required elements for the search, which is an or'ed together
+ /// set of lldb:SearchContextItem enum's.
+ ///
+ //------------------------------------------------------------------
+ virtual uint32_t
+ GetFilterRequiredItems ();
+
+ //------------------------------------------------------------------
+ /// Prints a canonical description for the search filter to the stream \a s.
+ ///
+ /// @param[in] s
+ /// Stream to which the output is copied.
+ //------------------------------------------------------------------
+ virtual void
+ GetDescription(Stream *s);
+
+ //------------------------------------------------------------------
+ /// Standard "Dump" method. At present it does nothing.
+ //------------------------------------------------------------------
+ virtual void
+ Dump (Stream *s) const;
+
+protected:
+
+ // These are utility functions to assist with the search iteration. They are used by the
+ // default Search method.
+
+ Searcher::CallbackReturn
+ DoModuleIteration (const SymbolContext &context,
+ Searcher &searcher);
+
+ Searcher::CallbackReturn
+ DoModuleIteration (const lldb::ModuleSP& module_sp,
+ Searcher &searcher);
+
+ Searcher::CallbackReturn
+ DoCUIteration (const lldb::ModuleSP& module_sp,
+ const SymbolContext &context,
+ Searcher &searcher);
+
+ Searcher::CallbackReturn
+ DoFunctionIteration (Function *function,
+ const SymbolContext &context,
+ Searcher &searcher);
+
+ lldb::TargetSP m_target_sp; // Every filter has to be associated with a target for
+ // now since you need a starting place for the search.
+};
+
+//----------------------------------------------------------------------
+/// @class SearchFilterForNonModuleSpecificSearches SearchFilter.h "lldb/Core/SearchFilter.h"
+/// @brief This is a SearchFilter that searches through all modules. It also consults the Target::ModuleIsExcludedForNonModuleSpecificSearches.
+//----------------------------------------------------------------------
+class SearchFilterForNonModuleSpecificSearches :
+ public SearchFilter
+{
+public:
+ SearchFilterForNonModuleSpecificSearches (const lldb::TargetSP &targetSP) : SearchFilter(targetSP) {}
+ ~SearchFilterForNonModuleSpecificSearches () {}
+
+ virtual bool
+ ModulePasses (const FileSpec &module_spec);
+
+ virtual bool
+ ModulePasses (const lldb::ModuleSP &module_sp);
+};
+
+//----------------------------------------------------------------------
+/// @class SearchFilterByModule SearchFilter.h "lldb/Core/SearchFilter.h"
+/// @brief This is a SearchFilter that restricts the search to a given module.
+//----------------------------------------------------------------------
+
+class SearchFilterByModule :
+ public SearchFilter
+{
+public:
+
+ //------------------------------------------------------------------
+ /// The basic constructor takes a Target, which gives the space to search,
+ /// and the module to restrict the search to.
+ ///
+ /// @param[in] target
+ /// The Target that provides the module list to search.
+ ///
+ /// @param[in] module
+ /// The Module that limits the search.
+ //------------------------------------------------------------------
+ SearchFilterByModule (const lldb::TargetSP &targetSP,
+ const FileSpec &module);
+
+ SearchFilterByModule (const SearchFilterByModule& rhs);
+
+ virtual
+ ~SearchFilterByModule ();
+
+ const SearchFilterByModule&
+ operator=(const SearchFilterByModule& rhs);
+
+ virtual bool
+ ModulePasses (const lldb::ModuleSP &module_sp);
+
+ virtual bool
+ ModulePasses (const FileSpec &spec);
+
+ virtual bool
+ AddressPasses (Address &address);
+
+ virtual bool
+ CompUnitPasses (FileSpec &fileSpec);
+
+ virtual bool
+ CompUnitPasses (CompileUnit &compUnit);
+
+ virtual void
+ GetDescription(Stream *s);
+
+ virtual uint32_t
+ GetFilterRequiredItems ();
+
+ virtual void
+ Dump (Stream *s) const;
+
+ virtual void
+ Search (Searcher &searcher);
+
+private:
+ FileSpec m_module_spec;
+};
+
+class SearchFilterByModuleList :
+ public SearchFilter
+{
+public:
+
+ //------------------------------------------------------------------
+ /// The basic constructor takes a Target, which gives the space to search,
+ /// and the module list to restrict the search to.
+ ///
+ /// @param[in] target
+ /// The Target that provides the module list to search.
+ ///
+ /// @param[in] module
+ /// The Module that limits the search.
+ //------------------------------------------------------------------
+ SearchFilterByModuleList (const lldb::TargetSP &targetSP,
+ const FileSpecList &module_list);
+
+ SearchFilterByModuleList (const SearchFilterByModuleList& rhs);
+
+ virtual
+ ~SearchFilterByModuleList ();
+
+ const SearchFilterByModuleList&
+ operator=(const SearchFilterByModuleList& rhs);
+
+ virtual bool
+ ModulePasses (const lldb::ModuleSP &module_sp);
+
+ virtual bool
+ ModulePasses (const FileSpec &spec);
+
+ virtual bool
+ AddressPasses (Address &address);
+
+ virtual bool
+ CompUnitPasses (FileSpec &fileSpec);
+
+ virtual bool
+ CompUnitPasses (CompileUnit &compUnit);
+
+ virtual void
+ GetDescription(Stream *s);
+
+ virtual uint32_t
+ GetFilterRequiredItems ();
+
+ virtual void
+ Dump (Stream *s) const;
+
+ virtual void
+ Search (Searcher &searcher);
+
+private:
+ FileSpecList m_module_spec_list;
+};
+
+class SearchFilterByModuleListAndCU :
+ public SearchFilterByModuleList
+{
+public:
+
+ //------------------------------------------------------------------
+ /// The basic constructor takes a Target, which gives the space to search,
+ /// and the module list to restrict the search to.
+ ///
+ /// @param[in] target
+ /// The Target that provides the module list to search.
+ ///
+ /// @param[in] module
+ /// The Module that limits the search.
+ //------------------------------------------------------------------
+ SearchFilterByModuleListAndCU (const lldb::TargetSP &targetSP,
+ const FileSpecList &module_list,
+ const FileSpecList &cu_list);
+
+ SearchFilterByModuleListAndCU (const SearchFilterByModuleListAndCU& rhs);
+
+ virtual
+ ~SearchFilterByModuleListAndCU ();
+
+ const SearchFilterByModuleListAndCU&
+ operator=(const SearchFilterByModuleListAndCU& rhs);
+
+ virtual bool
+ AddressPasses (Address &address);
+
+ virtual bool
+ CompUnitPasses (FileSpec &fileSpec);
+
+ virtual bool
+ CompUnitPasses (CompileUnit &compUnit);
+
+ virtual void
+ GetDescription(Stream *s);
+
+ virtual uint32_t
+ GetFilterRequiredItems ();
+
+ virtual void
+ Dump (Stream *s) const;
+
+ virtual void
+ Search (Searcher &searcher);
+
+private:
+ FileSpecList m_module_spec_list;
+ FileSpecList m_cu_spec_list;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_SearchFilter_h_
diff --git a/include/lldb/Core/Section.h b/include/lldb/Core/Section.h
new file mode 100644
index 000000000000..437eaf59b9c4
--- /dev/null
+++ b/include/lldb/Core/Section.h
@@ -0,0 +1,313 @@
+//===-- Section.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Section_h_
+#define liblldb_Section_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Core/VMRange.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include <limits.h>
+
+namespace lldb_private {
+
+class SectionList
+{
+public:
+ typedef std::vector<lldb::SectionSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ SectionList();
+
+ ~SectionList();
+
+ SectionList &
+ operator =(const SectionList& rhs);
+
+ size_t
+ AddSection (const lldb::SectionSP& section_sp);
+
+ size_t
+ AddUniqueSection (const lldb::SectionSP& section_sp);
+
+ size_t
+ FindSectionIndex (const Section* sect);
+
+ bool
+ ContainsSection(lldb::user_id_t sect_id) const;
+
+ void
+ Dump (Stream *s, Target *target, bool show_header, uint32_t depth) const;
+
+ lldb::SectionSP
+ FindSectionByName (const ConstString &section_dstr) const;
+
+ lldb::SectionSP
+ FindSectionByID (lldb::user_id_t sect_id) const;
+
+ lldb::SectionSP
+ FindSectionByType (lldb::SectionType sect_type, bool check_children, size_t start_idx = 0) const;
+
+ lldb::SectionSP
+ FindSectionContainingFileAddress (lldb::addr_t addr, uint32_t depth = UINT32_MAX) const;
+
+ bool
+ GetSectionData (const DataExtractor& module_data, DataExtractor& section_data) const;
+
+ // Get the number of sections in this list only
+ size_t
+ GetSize () const
+ {
+ return m_sections.size();
+ }
+
+ // Get the number of sections in this list, and any contained child sections
+ size_t
+ GetNumSections (uint32_t depth) const;
+
+ bool
+ ReplaceSection (lldb::user_id_t sect_id, const lldb::SectionSP& section_sp, uint32_t depth = UINT32_MAX);
+
+ // Warning, this can be slow as it's removing items from a std::vector.
+ bool
+ DeleteSection (size_t idx);
+
+ lldb::SectionSP
+ GetSectionAtIndex (size_t idx) const;
+
+ size_t
+ Slide (lldb::addr_t slide_amount, bool slide_children);
+
+ void
+ Clear ()
+ {
+ m_sections.clear();
+ }
+
+protected:
+ collection m_sections;
+};
+
+
+class Section :
+ public std::enable_shared_from_this<Section>,
+ public ModuleChild,
+ public UserID,
+ public Flags
+{
+public:
+ // Create a root section (one that has no parent)
+ Section (const lldb::ModuleSP &module_sp,
+ ObjectFile *obj_file,
+ lldb::user_id_t sect_id,
+ const ConstString &name,
+ lldb::SectionType sect_type,
+ lldb::addr_t file_vm_addr,
+ lldb::addr_t vm_size,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ uint32_t flags);
+
+ // Create a section that is a child of parent_section_sp
+ Section (const lldb::SectionSP &parent_section_sp, // NULL for top level sections, non-NULL for child sections
+ const lldb::ModuleSP &module_sp,
+ ObjectFile *obj_file,
+ lldb::user_id_t sect_id,
+ const ConstString &name,
+ lldb::SectionType sect_type,
+ lldb::addr_t file_vm_addr,
+ lldb::addr_t vm_size,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ uint32_t flags);
+
+ ~Section ();
+
+ static int
+ Compare (const Section& a, const Section& b);
+
+ bool
+ ContainsFileAddress (lldb::addr_t vm_addr) const;
+
+ SectionList&
+ GetChildren ()
+ {
+ return m_children;
+ }
+
+ const SectionList&
+ GetChildren () const
+ {
+ return m_children;
+ }
+
+ void
+ Dump (Stream *s, Target *target, uint32_t depth) const;
+
+ void
+ DumpName (Stream *s) const;
+
+ lldb::addr_t
+ GetLoadBaseAddress (Target *target) const;
+
+ bool
+ ResolveContainedAddress (lldb::addr_t offset, Address &so_addr) const;
+
+ lldb::offset_t
+ GetFileOffset () const
+ {
+ return m_file_offset;
+ }
+
+ void
+ SetFileOffset (lldb::offset_t file_offset)
+ {
+ m_file_offset = file_offset;
+ }
+
+ lldb::offset_t
+ GetFileSize () const
+ {
+ return m_file_size;
+ }
+
+ void
+ SetFileSize (lldb::offset_t file_size)
+ {
+ m_file_size = file_size;
+ }
+
+ lldb::addr_t
+ GetFileAddress () const;
+
+ bool
+ SetFileAddress (lldb::addr_t file_addr);
+
+ lldb::addr_t
+ GetOffset () const;
+
+
+ lldb::addr_t
+ GetByteSize () const
+ {
+ return m_byte_size;
+ }
+
+ void
+ SetByteSize (lldb::addr_t byte_size)
+ {
+ m_byte_size = byte_size;
+ }
+
+ bool
+ IsFake() const
+ {
+ return m_fake;
+ }
+
+ void
+ SetIsFake(bool fake)
+ {
+ m_fake = fake;
+ }
+
+ bool
+ IsEncrypted () const
+ {
+ return m_encrypted;
+ }
+
+ void
+ SetIsEncrypted (bool b)
+ {
+ m_encrypted = b;
+ }
+
+ bool
+ IsDescendant (const Section *section);
+
+ const ConstString&
+ GetName () const
+ {
+ return m_name;
+ }
+
+ bool
+ Slide (lldb::addr_t slide_amount, bool slide_children);
+
+
+ lldb::SectionType
+ GetType () const
+ {
+ return m_type;
+ }
+
+ lldb::SectionSP
+ GetParent () const
+ {
+ return m_parent_wp.lock();
+ }
+
+ bool
+ IsThreadSpecific () const
+ {
+ return m_thread_specific;
+ }
+
+ void
+ SetIsThreadSpecific (bool b)
+ {
+ m_thread_specific = b;
+ }
+
+ ObjectFile *
+ GetObjectFile ()
+ {
+ return m_obj_file;
+ }
+ const ObjectFile *
+ GetObjectFile () const
+ {
+ return m_obj_file;
+ }
+
+
+protected:
+
+ ObjectFile *m_obj_file; // The object file that data for this section should be read from
+ lldb::SectionType m_type; // The type of this section
+ lldb::SectionWP m_parent_wp; // Weak pointer to parent section
+ ConstString m_name; // Name of this section
+ lldb::addr_t m_file_addr; // The absolute file virtual address range of this section if m_parent == NULL,
+ // offset from parent file virtual address if m_parent != NULL
+ lldb::addr_t m_byte_size; // Size in bytes that this section will occupy in memory at runtime
+ lldb::offset_t m_file_offset; // Object file offset (if any)
+ lldb::offset_t m_file_size; // Object file size (can be smaller than m_byte_size for zero filled sections...)
+ SectionList m_children; // Child sections
+ bool m_fake:1, // If true, then this section only can contain the address if one of its
+ // children contains an address. This allows for gaps between the children
+ // that are contained in the address range for this section, but do not produce
+ // hits unless the children contain the address.
+ m_encrypted:1, // Set to true if the contents are encrypted
+ m_thread_specific:1;// This section is thread specific
+private:
+ DISALLOW_COPY_AND_ASSIGN (Section);
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_Section_h_
diff --git a/include/lldb/Core/SourceManager.h b/include/lldb/Core/SourceManager.h
new file mode 100644
index 000000000000..b850df774bac
--- /dev/null
+++ b/include/lldb/Core/SourceManager.h
@@ -0,0 +1,196 @@
+//===-- SourceManager.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SourceManager_h_
+#define liblldb_SourceManager_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Host/FileSpec.h"
+
+namespace lldb_private {
+
+class SourceManager
+{
+public:
+#ifndef SWIG
+
+ class File
+ {
+ friend bool operator== (const SourceManager::File &lhs, const SourceManager::File &rhs);
+ public:
+
+ File (const FileSpec &file_spec, Target *target);
+ ~File();
+
+ size_t
+ DisplaySourceLines (uint32_t line,
+ uint32_t context_before,
+ uint32_t context_after,
+ Stream *s);
+ void
+ FindLinesMatchingRegex (RegularExpression& regex,
+ uint32_t start_line,
+ uint32_t end_line,
+ std::vector<uint32_t> &match_lines);
+
+ bool
+ GetLine (uint32_t line_no, std::string &buffer);
+
+ uint32_t
+ GetLineOffset (uint32_t line);
+
+ bool
+ LineIsValid (uint32_t line);
+
+ bool
+ FileSpecMatches (const FileSpec &file_spec);
+
+ const FileSpec &
+ GetFileSpec ()
+ {
+ return m_file_spec;
+ }
+
+ uint32_t
+ GetSourceMapModificationID() const
+ {
+ return m_source_map_mod_id;
+ }
+
+ protected:
+
+ bool
+ CalculateLineOffsets (uint32_t line = UINT32_MAX);
+
+ FileSpec m_file_spec_orig; // The original file spec that was used (can be different from m_file_spec)
+ FileSpec m_file_spec; // The actualy file spec being used (if the target has source mappings, this might be different from m_file_spec_orig)
+ TimeValue m_mod_time; // Keep the modification time that this file data is valid for
+ uint32_t m_source_map_mod_id; // If the target uses path remappings, be sure to clear our notion of a source file if the path modification ID changes
+ lldb::DataBufferSP m_data_sp;
+ typedef std::vector<uint32_t> LineOffsets;
+ LineOffsets m_offsets;
+ };
+
+#endif // SWIG
+
+ typedef std::shared_ptr<File> FileSP;
+
+#ifndef SWIG
+
+ // The SourceFileCache class separates the source manager from the cache of source files, so the
+ // cache can be stored in the Debugger, but the source managers can be per target.
+ class SourceFileCache
+ {
+ public:
+ SourceFileCache () {}
+ ~SourceFileCache() {}
+
+ void AddSourceFile (const FileSP &file_sp);
+ FileSP FindSourceFile (const FileSpec &file_spec) const;
+
+ protected:
+ typedef std::map <FileSpec, FileSP> FileCache;
+ FileCache m_file_cache;
+ };
+#endif
+
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ // A source manager can be made with a non-null target, in which case it can use the path remappings to find
+ // source files that are not in their build locations. With no target it won't be able to do this.
+ SourceManager (const lldb::DebuggerSP &debugger_sp);
+ SourceManager (const lldb::TargetSP &target_sp);
+
+ ~SourceManager();
+
+
+ FileSP
+ GetLastFile ()
+ {
+ return m_last_file_sp;
+ }
+
+ size_t
+ DisplaySourceLinesWithLineNumbers (const FileSpec &file,
+ uint32_t line,
+ uint32_t context_before,
+ uint32_t context_after,
+ const char* current_line_cstr,
+ Stream *s,
+ const SymbolContextList *bp_locs = NULL);
+
+ // This variant uses the last file we visited.
+ size_t
+ DisplaySourceLinesWithLineNumbersUsingLastFile (uint32_t start_line,
+ uint32_t count,
+ uint32_t curr_line,
+ const char* current_line_cstr,
+ Stream *s,
+ const SymbolContextList *bp_locs = NULL);
+
+ size_t
+ DisplayMoreWithLineNumbers (Stream *s,
+ uint32_t count,
+ bool reverse,
+ const SymbolContextList *bp_locs = NULL);
+
+ bool
+ SetDefaultFileAndLine (const FileSpec &file_spec, uint32_t line);
+
+ bool
+ GetDefaultFileAndLine (FileSpec &file_spec, uint32_t &line);
+
+ bool
+ DefaultFileAndLineSet ()
+ {
+ return (m_last_file_sp.get() != NULL);
+ }
+
+ void
+ FindLinesMatchingRegex (FileSpec &file_spec,
+ RegularExpression& regex,
+ uint32_t start_line,
+ uint32_t end_line,
+ std::vector<uint32_t> &match_lines);
+
+protected:
+
+ FileSP
+ GetFile (const FileSpec &file_spec);
+
+ //------------------------------------------------------------------
+ // Classes that inherit from SourceManager can see and modify these
+ //------------------------------------------------------------------
+ FileSP m_last_file_sp;
+ uint32_t m_last_line;
+ uint32_t m_last_count;
+ bool m_default_set;
+ lldb::TargetWP m_target_wp;
+ lldb::DebuggerWP m_debugger_wp;
+
+private:
+ //------------------------------------------------------------------
+ // For SourceManager only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (SourceManager);
+};
+
+bool operator== (const SourceManager::File &lhs, const SourceManager::File &rhs);
+} // namespace lldb_private
+
+#endif // liblldb_SourceManager_h_
diff --git a/include/lldb/Core/State.h b/include/lldb/Core/State.h
new file mode 100644
index 000000000000..8057b3e0584c
--- /dev/null
+++ b/include/lldb/Core/State.h
@@ -0,0 +1,78 @@
+//===-- State.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_State_h_
+#define liblldb_State_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//------------------------------------------------------------------
+/// Converts a StateType to a C string.
+///
+/// @param[in] state
+/// The StateType object to convert.
+///
+/// @return
+/// A NULL terminated C string that describes \a state. The
+/// returned string comes from constant string buffers and does
+/// not need to be freed.
+//------------------------------------------------------------------
+const char *
+StateAsCString (lldb::StateType state);
+
+//------------------------------------------------------------------
+/// Check if a state represents a state where the process or thread
+/// is running.
+///
+/// @param[in] state
+/// The StateType enumeration value
+///
+/// @return
+/// \b true if the state represents a process or thread state
+/// where the process or thread is running, \b false otherwise.
+//------------------------------------------------------------------
+bool
+StateIsRunningState (lldb::StateType state);
+
+//------------------------------------------------------------------
+/// Check if a state represents a state where the process or thread
+/// is stopped. Stopped can mean stopped when the process is still
+/// around, or stopped when the process has exited or doesn't exist
+/// yet. The \a must_exist argument tells us which of these cases is
+/// desired.
+///
+/// @param[in] state
+/// The StateType enumeration value
+///
+/// @param[in] must_exist
+/// A boolean that indicates the thread must also be alive
+/// so states like unloaded or exited won't return true.
+///
+/// @return
+/// \b true if the state represents a process or thread state
+/// where the process or thread is stopped. If \a must_exist is
+/// \b true, then the process can't be exited or unloaded,
+/// otherwise exited and unloaded or other states where the
+/// process no longer exists are considered to be stopped.
+//------------------------------------------------------------------
+bool
+StateIsStoppedState (lldb::StateType state, bool must_exist);
+
+const char *
+GetPermissionsAsCString (uint32_t permissions);
+
+} // namespace lldb_private
+
+#endif // liblldb_State_h_
diff --git a/include/lldb/Core/Stream.h b/include/lldb/Core/Stream.h
new file mode 100644
index 000000000000..0fd4aac041a9
--- /dev/null
+++ b/include/lldb/Core/Stream.h
@@ -0,0 +1,612 @@
+//===-- Stream.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Stream_h_
+#define liblldb_Stream_h_
+#if defined(__cplusplus)
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Flags.h"
+#include <stdarg.h>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Stream Stream.h "lldb/Core/Stream.h"
+/// @brief A stream class that can stream formatted output to a file.
+//----------------------------------------------------------------------
+class Stream
+{
+public:
+ //------------------------------------------------------------------
+ /// \a m_flags bit values.
+ //------------------------------------------------------------------
+ enum
+ {
+ eVerbose = (1 << 0), ///< If set, verbose logging is enabled
+ eDebug = (1 << 1), ///< If set, debug logging is enabled
+ eAddPrefix = (1 << 2), ///< Add number prefixes for binary, octal and hex when eBinary is clear
+ eBinary = (1 << 3) ///< Get and put data as binary instead of as the default string mode.
+ };
+
+ //------------------------------------------------------------------
+ /// Construct with flags and address size and byte order.
+ ///
+ /// Construct with dump flags \a flags and the default address
+ /// size. \a flags can be any of the above enumeration logical OR'ed
+ /// together.
+ //------------------------------------------------------------------
+ Stream (uint32_t flags,
+ uint32_t addr_size,
+ lldb::ByteOrder byte_order);
+
+ //------------------------------------------------------------------
+ /// Construct a default Stream, not binary, host byte order and
+ /// host addr size.
+ ///
+ //------------------------------------------------------------------
+ Stream ();
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual
+ ~Stream ();
+
+ //------------------------------------------------------------------
+ // Subclasses must override these methods
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Flush the stream.
+ ///
+ /// Subclasses should flush the stream to make any output appear
+ /// if the stream has any buffering.
+ //------------------------------------------------------------------
+ virtual void
+ Flush () = 0;
+
+ //------------------------------------------------------------------
+ /// Output character bytes to the stream.
+ ///
+ /// Appends \a src_len characters from the buffer \a src to the
+ /// stream.
+ ///
+ /// @param[in] src
+ /// A buffer containing at least \a src_len bytes of data.
+ ///
+ /// @param[in] src_len
+ /// A number of bytes to append to the stream.
+ ///
+ /// @return
+ /// The number of bytes that were appended to the stream.
+ //------------------------------------------------------------------
+ virtual size_t
+ Write (const void *src, size_t src_len) = 0;
+
+ //------------------------------------------------------------------
+ // Member functions
+ //------------------------------------------------------------------
+ size_t
+ PutChar (char ch);
+
+ //------------------------------------------------------------------
+ /// Set the byte_order value.
+ ///
+ /// Sets the byte order of the data to extract. Extracted values
+ /// will be swapped if necessary when decoding.
+ ///
+ /// @param[in] byte_order
+ /// The byte order value to use when extracting data.
+ ///
+ /// @return
+ /// The old byte order value.
+ //------------------------------------------------------------------
+ lldb::ByteOrder
+ SetByteOrder (lldb::ByteOrder byte_order);
+
+ //------------------------------------------------------------------
+ /// Format a C string from a printf style format and variable
+ /// arguments and encode and append the resulting C string as hex
+ /// bytes.
+ ///
+ /// @param[in] format
+ /// A printf style format string.
+ ///
+ /// @param[in] ...
+ /// Any additional arguments needed for the printf format string.
+ ///
+ /// @return
+ /// The number of bytes that were appended to the stream.
+ //------------------------------------------------------------------
+ size_t
+ PrintfAsRawHex8 (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ //------------------------------------------------------------------
+ /// Format a C string from a printf style format and variable
+ /// arguments and encode and append the resulting C string as hex
+ /// bytes.
+ ///
+ /// @param[in] format
+ /// A printf style format string.
+ ///
+ /// @param[in] ...
+ /// Any additional arguments needed for the printf format string.
+ ///
+ /// @return
+ /// The number of bytes that were appended to the stream.
+ //------------------------------------------------------------------
+ size_t
+ PutHex8 (uint8_t uvalue);
+
+ size_t
+ PutNHex8 (size_t n, uint8_t uvalue);
+
+ size_t
+ PutHex16 (uint16_t uvalue,
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
+
+ size_t
+ PutHex32 (uint32_t uvalue,
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
+
+ size_t
+ PutHex64 (uint64_t uvalue,
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
+
+ size_t
+ PutMaxHex64 (uint64_t uvalue,
+ size_t byte_size,
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
+ size_t
+ PutFloat (float f,
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
+
+ size_t
+ PutDouble (double d,
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
+
+ size_t
+ PutLongDouble (long double ld,
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
+
+ size_t
+ PutPointer (void *ptr);
+
+ // Append \a src_len bytes from \a src to the stream as hex characters
+ // (two ascii characters per byte of input data)
+ size_t
+ PutBytesAsRawHex8 (const void *src,
+ size_t src_len,
+ lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid,
+ lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid);
+
+ // Append \a src_len bytes from \a s to the stream as binary data.
+ size_t
+ PutRawBytes (const void *s,
+ size_t src_len,
+ lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid,
+ lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid);
+
+ size_t
+ PutCStringAsRawHex8 (const char *s);
+
+ //------------------------------------------------------------------
+ /// Output a NULL terminated C string \a cstr to the stream \a s.
+ ///
+ /// @param[in] cstr
+ /// A NULL terminated C string.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (const char *cstr);
+
+ //------------------------------------------------------------------
+ /// Output a pointer value \a p to the stream \a s.
+ ///
+ /// @param[in] p
+ /// A void pointer.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (void *p);
+
+ //------------------------------------------------------------------
+ /// Output a character \a ch to the stream \a s.
+ ///
+ /// @param[in] ch
+ /// A printable character value.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (char ch);
+
+ //------------------------------------------------------------------
+ /// Output a uint8_t \a uval to the stream \a s.
+ ///
+ /// @param[in] uval
+ /// A uint8_t value.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (uint8_t uval);
+
+ //------------------------------------------------------------------
+ /// Output a uint16_t \a uval to the stream \a s.
+ ///
+ /// @param[in] uval
+ /// A uint16_t value.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (uint16_t uval);
+
+ //------------------------------------------------------------------
+ /// Output a uint32_t \a uval to the stream \a s.
+ ///
+ /// @param[in] uval
+ /// A uint32_t value.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (uint32_t uval);
+
+ //------------------------------------------------------------------
+ /// Output a uint64_t \a uval to the stream \a s.
+ ///
+ /// @param[in] uval
+ /// A uint64_t value.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (uint64_t uval);
+
+ //------------------------------------------------------------------
+ /// Output a int8_t \a sval to the stream \a s.
+ ///
+ /// @param[in] sval
+ /// A int8_t value.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (int8_t sval);
+
+ //------------------------------------------------------------------
+ /// Output a int16_t \a sval to the stream \a s.
+ ///
+ /// @param[in] sval
+ /// A int16_t value.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (int16_t sval);
+
+ //------------------------------------------------------------------
+ /// Output a int32_t \a sval to the stream \a s.
+ ///
+ /// @param[in] sval
+ /// A int32_t value.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (int32_t sval);
+
+ //------------------------------------------------------------------
+ /// Output a int64_t \a sval to the stream \a s.
+ ///
+ /// @param[in] sval
+ /// A int64_t value.
+ ///
+ /// @return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ //------------------------------------------------------------------
+ Stream&
+ operator<< (int64_t sval);
+
+ //------------------------------------------------------------------
+ /// Output an address value to this stream.
+ ///
+ /// Put an address \a addr out to the stream with optional \a prefix
+ /// and \a suffix strings.
+ ///
+ /// @param[in] addr
+ /// An address value.
+ ///
+ /// @param[in] addr_size
+ /// Size in bytes of the address, used for formatting.
+ ///
+ /// @param[in] prefix
+ /// A prefix C string. If NULL, no prefix will be output.
+ ///
+ /// @param[in] suffix
+ /// A suffix C string. If NULL, no suffix will be output.
+ //------------------------------------------------------------------
+ void
+ Address (uint64_t addr, uint32_t addr_size, const char *prefix = NULL, const char *suffix = NULL);
+
+ //------------------------------------------------------------------
+ /// Output an address range to this stream.
+ ///
+ /// Put an address range \a lo_addr - \a hi_addr out to the stream
+ /// with optional \a prefix and \a suffix strings.
+ ///
+ /// @param[in] lo_addr
+ /// The start address of the address range.
+ ///
+ /// @param[in] hi_addr
+ /// The end address of the address range.
+ ///
+ /// @param[in] addr_size
+ /// Size in bytes of the address, used for formatting.
+ ///
+ /// @param[in] prefix
+ /// A prefix C string. If NULL, no prefix will be output.
+ ///
+ /// @param[in] suffix
+ /// A suffix C string. If NULL, no suffix will be output.
+ //------------------------------------------------------------------
+ void
+ AddressRange(uint64_t lo_addr, uint64_t hi_addr, uint32_t addr_size, const char *prefix = NULL, const char *suffix = NULL);
+
+ //------------------------------------------------------------------
+ /// Output a C string to the stream.
+ ///
+ /// Print a C string \a cstr to the stream.
+ ///
+ /// @param[in] cstr
+ /// The string to be output to the stream.
+ //------------------------------------------------------------------
+ size_t
+ PutCString (const char *cstr);
+
+ //------------------------------------------------------------------
+ /// Output and End of Line character to the stream.
+ //------------------------------------------------------------------
+ size_t
+ EOL();
+
+ //------------------------------------------------------------------
+ /// Get the address size in bytes.
+ ///
+ /// @return
+ /// The size of an address in bytes that is used when outputting
+ /// address and pointer values to the stream.
+ //------------------------------------------------------------------
+ uint32_t
+ GetAddressByteSize () const;
+
+ //------------------------------------------------------------------
+ /// Test if debug logging is enabled.
+ ///
+ /// @return
+ // \b true if the debug flag bit is set in this stream, \b
+ // false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetDebug() const;
+
+ //------------------------------------------------------------------
+ /// The flags accessor.
+ ///
+ /// @return
+ /// A reference to the Flags member variable.
+ //------------------------------------------------------------------
+ Flags&
+ GetFlags();
+
+ //------------------------------------------------------------------
+ /// The flags const accessor.
+ ///
+ /// @return
+ /// A const reference to the Flags member variable.
+ //------------------------------------------------------------------
+ const Flags&
+ GetFlags() const;
+
+ //------------------------------------------------------------------
+ //// The byte order accessor.
+ ////
+ //// @return
+ //// The byte order.
+ //------------------------------------------------------------------
+ lldb::ByteOrder
+ GetByteOrder() const;
+
+ //------------------------------------------------------------------
+ /// Get the current indentation level.
+ ///
+ /// @return
+ /// The current indentation level as an integer.
+ //------------------------------------------------------------------
+ int
+ GetIndentLevel () const;
+
+ //------------------------------------------------------------------
+ /// Test if verbose logging is enabled.
+ ///
+ /// @return
+ // \b true if the verbose flag bit is set in this stream, \b
+ // false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetVerbose() const;
+
+ //------------------------------------------------------------------
+ /// Indent the current line in the stream.
+ ///
+ /// Indent the current line using the current indentation level and
+ /// print an optional string following the idenatation spaces.
+ ///
+ /// @param[in] s
+ /// A C string to print following the indentation. If NULL, just
+ /// output the indentation characters.
+ //------------------------------------------------------------------
+ size_t
+ Indent(const char *s = NULL);
+
+ //------------------------------------------------------------------
+ /// Decrement the current indentation level.
+ //------------------------------------------------------------------
+ void
+ IndentLess (int amount = 2);
+
+ //------------------------------------------------------------------
+ /// Increment the current indentation level.
+ //------------------------------------------------------------------
+ void
+ IndentMore (int amount = 2);
+
+ //------------------------------------------------------------------
+ /// Output an offset value.
+ ///
+ /// Put an offset \a uval out to the stream using the printf format
+ /// in \a format.
+ ///
+ /// @param[in] offset
+ /// The offset value.
+ ///
+ /// @param[in] format
+ /// The printf style format to use when outputting the offset.
+ //------------------------------------------------------------------
+ void
+ Offset (uint32_t offset, const char *format = "0x%8.8x: ");
+
+ //------------------------------------------------------------------
+ /// Output printf formatted output to the stream.
+ ///
+ /// Print some formatted output to the stream.
+ ///
+ /// @param[in] format
+ /// A printf style format string.
+ ///
+ /// @param[in] ...
+ /// Variable arguments that are needed for the printf style
+ /// format string \a format.
+ //------------------------------------------------------------------
+ size_t
+ Printf (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ size_t
+ PrintfVarArg(const char *format, va_list args);
+
+ //------------------------------------------------------------------
+ /// Output a quoted C string value to the stream.
+ ///
+ /// Print a double quoted NULL terminated C string to the stream
+ /// using the printf format in \a format.
+ ///
+ /// @param[in] cstr
+ /// A NULL terminated C string value.
+ ///
+ /// @param[in] format
+ /// The optional C string format that can be overridden.
+ //------------------------------------------------------------------
+ void
+ QuotedCString (const char *cstr, const char *format = "\"%s\"");
+
+ //------------------------------------------------------------------
+ /// Set the address size in bytes.
+ ///
+ /// @param[in] addr_size
+ /// The new size in bytes of an address to use when outputting
+ /// address and pointer values.
+ //------------------------------------------------------------------
+ void
+ SetAddressByteSize (uint32_t addr_size);
+
+ //------------------------------------------------------------------
+ /// Set the current indentation level.
+ ///
+ /// @param[in] level
+ /// The new indentation level.
+ //------------------------------------------------------------------
+ void
+ SetIndentLevel (int level);
+
+ //------------------------------------------------------------------
+ /// Output a SLEB128 number to the stream.
+ ///
+ /// Put an SLEB128 \a uval out to the stream using the printf format
+ /// in \a format.
+ ///
+ /// @param[in] uval
+ /// A uint64_t value that was extracted as a SLEB128 value.
+ ///
+ /// @param[in] format
+ /// The optional printf format that can be overridden.
+ //------------------------------------------------------------------
+ size_t
+ PutSLEB128 (int64_t uval);
+
+ //------------------------------------------------------------------
+ /// Output a ULEB128 number to the stream.
+ ///
+ /// Put an ULEB128 \a uval out to the stream using the printf format
+ /// in \a format.
+ ///
+ /// @param[in] uval
+ /// A uint64_t value that was extracted as a ULEB128 value.
+ ///
+ /// @param[in] format
+ /// The optional printf format that can be overridden.
+ //------------------------------------------------------------------
+ size_t
+ PutULEB128 (uint64_t uval);
+
+ static void
+ UnitTest(Stream *s);
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ Flags m_flags; ///< Dump flags.
+ uint32_t m_addr_size; ///< Size of an address in bytes.
+ lldb::ByteOrder m_byte_order; ///< Byte order to use when encoding scalar types.
+ int m_indent_level; ///< Indention level.
+
+ size_t _PutHex8 (uint8_t uvalue, bool add_prefix);
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_Stream_h_
+
diff --git a/include/lldb/Core/StreamAsynchronousIO.h b/include/lldb/Core/StreamAsynchronousIO.h
new file mode 100644
index 000000000000..0e3e9ee9bcf1
--- /dev/null
+++ b/include/lldb/Core/StreamAsynchronousIO.h
@@ -0,0 +1,42 @@
+//===-- StreamAsynchronousIO.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StreamAsynchronousIO_h_
+#define liblldb_StreamAsynchronousIO_h_
+
+#include <string>
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+
+namespace lldb_private {
+
+class StreamAsynchronousIO :
+ public Stream
+{
+public:
+ StreamAsynchronousIO (Broadcaster &broadcaster, uint32_t broadcast_event_type);
+
+ virtual ~StreamAsynchronousIO ();
+
+ virtual void
+ Flush ();
+
+ virtual size_t
+ Write (const void *src, size_t src_len);
+
+
+private:
+ Broadcaster &m_broadcaster;
+ uint32_t m_broadcast_event_type;
+ StreamString m_accumulated_data;
+};
+
+} // namespace lldb_private
+#endif // #ifndef liblldb_StreamAsynchronousIO_h
diff --git a/include/lldb/Core/StreamBuffer.h b/include/lldb/Core/StreamBuffer.h
new file mode 100644
index 000000000000..9d25e842ecc5
--- /dev/null
+++ b/include/lldb/Core/StreamBuffer.h
@@ -0,0 +1,87 @@
+//===-- StreamBuffer.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StreamBuffer_h_
+#define liblldb_StreamBuffer_h_
+
+#include <stdio.h>
+#include <string>
+#include "llvm/ADT/SmallVector.h"
+#include "lldb/Core/Stream.h"
+
+namespace lldb_private {
+
+template <unsigned N>
+class StreamBuffer : public Stream
+{
+public:
+ StreamBuffer () :
+ Stream (0, 4, lldb::eByteOrderBig),
+ m_packet ()
+ {
+ }
+
+
+ StreamBuffer (uint32_t flags,
+ uint32_t addr_size,
+ lldb::ByteOrder byte_order) :
+ Stream (flags, addr_size, byte_order),
+ m_packet ()
+ {
+ }
+
+ virtual
+ ~StreamBuffer ()
+ {
+ }
+
+ virtual void
+ Flush ()
+ {
+ // Nothing to do when flushing a buffer based stream...
+ }
+
+ virtual size_t
+ Write (const void *s, size_t length)
+ {
+ if (s && length)
+ m_packet.append ((const char *)s, ((const char *)s) + length);
+ return length;
+ }
+
+ void
+ Clear()
+ {
+ m_packet.clear();
+ }
+
+ // Beware, this might not be NULL terminated as you can expect from
+ // StringString as there may be random bits in the llvm::SmallVector. If
+ // you are using this class to create a C string, be sure the call PutChar ('\0')
+ // after you have created your string, or use StreamString.
+ const char *
+ GetData () const
+ {
+ return m_packet.data();
+ }
+
+ size_t
+ GetSize() const
+ {
+ return m_packet.size();
+ }
+
+protected:
+ llvm::SmallVector<char, N> m_packet;
+
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_StreamBuffer_h_
diff --git a/include/lldb/Core/StreamCallback.h b/include/lldb/Core/StreamCallback.h
new file mode 100644
index 000000000000..b5fb91c6ce07
--- /dev/null
+++ b/include/lldb/Core/StreamCallback.h
@@ -0,0 +1,47 @@
+//===-- StreamCallback.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StreamCallback_h_
+#define liblldb_StreamCallback_h_
+
+#include <string>
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+class StreamCallback :
+ public Stream
+{
+public:
+ StreamCallback (lldb::LogOutputCallback callback, void *baton);
+
+ virtual ~StreamCallback ();
+
+ virtual void
+ Flush ();
+
+ virtual size_t
+ Write (const void *src, size_t src_len);
+
+
+private:
+ typedef std::map<lldb::tid_t, StreamString> collection;
+ lldb::LogOutputCallback m_callback;
+ void *m_baton;
+ collection m_accumulated_data;
+ Mutex m_collection_mutex;
+
+ StreamString &FindStreamForThread(lldb::tid_t cur_tid);
+};
+
+} // namespace lldb_private
+#endif // #ifndef liblldb_StreamCallback_h
diff --git a/include/lldb/Core/StreamFile.h b/include/lldb/Core/StreamFile.h
new file mode 100644
index 000000000000..d032c0b21e6b
--- /dev/null
+++ b/include/lldb/Core/StreamFile.h
@@ -0,0 +1,75 @@
+//===-- StreamFile.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StreamFile_h_
+#define liblldb_StreamFile_h_
+
+// C Includes
+// C++ Includes
+
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Host/File.h"
+
+namespace lldb_private {
+
+class StreamFile : public Stream
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ StreamFile ();
+
+ StreamFile (uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order);
+
+ StreamFile (int fd, bool transfer_ownership);
+
+ StreamFile (const char *path);
+
+ StreamFile (FILE *fh, bool transfer_ownership);
+
+ virtual
+ ~StreamFile();
+
+ File &
+ GetFile ()
+ {
+ return m_file;
+ }
+
+ const File &
+ GetFile () const
+ {
+ return m_file;
+ }
+
+ virtual void
+ Flush ();
+
+ virtual size_t
+ Write (const void *s, size_t length);
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from StreamFile can see and modify these
+ //------------------------------------------------------------------
+ File m_file;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (StreamFile);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StreamFile_h_
diff --git a/include/lldb/Core/StreamString.h b/include/lldb/Core/StreamString.h
new file mode 100644
index 000000000000..a26ad2d16a05
--- /dev/null
+++ b/include/lldb/Core/StreamString.h
@@ -0,0 +1,64 @@
+//===-- StreamString.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StreamString_h_
+#define liblldb_StreamString_h_
+
+#include <string>
+
+#include "lldb/Core/Stream.h"
+
+namespace lldb_private {
+
+class StreamString : public Stream
+{
+public:
+ StreamString ();
+
+ StreamString (uint32_t flags,
+ uint32_t addr_size,
+ lldb::ByteOrder byte_order);
+
+ virtual
+ ~StreamString ();
+
+ virtual void
+ Flush ();
+
+ virtual size_t
+ Write (const void *s, size_t length);
+
+ void
+ Clear();
+
+ bool
+ Empty() const;
+
+ const char *
+ GetData () const;
+
+ size_t
+ GetSize() const;
+
+ std::string &
+ GetString();
+
+ const std::string &
+ GetString() const;
+
+ void
+ FillLastLineToColumn (uint32_t column, char fill_char);
+
+protected:
+ std::string m_packet;
+
+};
+
+} // namespace lldb_private
+#endif // #ifndef liblldb_StreamString_h_
diff --git a/include/lldb/Core/StreamTee.h b/include/lldb/Core/StreamTee.h
new file mode 100644
index 000000000000..e2a29a374553
--- /dev/null
+++ b/include/lldb/Core/StreamTee.h
@@ -0,0 +1,175 @@
+//===-- StreamTee.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StreamTee_h_
+#define liblldb_StreamTee_h_
+
+#include <limits.h>
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+class StreamTee : public Stream
+{
+public:
+ StreamTee () :
+ Stream (),
+ m_streams_mutex (Mutex::eMutexTypeRecursive),
+ m_streams ()
+ {
+ }
+
+ StreamTee (lldb::StreamSP &stream_sp):
+ Stream (),
+ m_streams_mutex (Mutex::eMutexTypeRecursive),
+ m_streams ()
+ {
+ // No need to lock mutex during construction
+ if (stream_sp)
+ m_streams.push_back (stream_sp);
+ }
+
+
+ StreamTee (lldb::StreamSP &stream_sp, lldb::StreamSP &stream_2_sp) :
+ Stream (),
+ m_streams_mutex (Mutex::eMutexTypeRecursive),
+ m_streams ()
+ {
+ // No need to lock mutex during construction
+ if (stream_sp)
+ m_streams.push_back (stream_sp);
+ if (stream_2_sp)
+ m_streams.push_back (stream_2_sp);
+ }
+
+ StreamTee (const StreamTee &rhs) :
+ Stream (rhs),
+ m_streams_mutex (Mutex::eMutexTypeRecursive),
+ m_streams() // Don't copy until we lock down "rhs"
+ {
+ Mutex::Locker locker (rhs.m_streams_mutex);
+ m_streams = rhs.m_streams;
+ }
+
+ virtual
+ ~StreamTee ()
+ {
+ }
+
+ StreamTee &
+ operator = (const StreamTee &rhs)
+ {
+ if (this != &rhs) {
+ Stream::operator=(rhs);
+ Mutex::Locker lhs_locker (m_streams_mutex);
+ Mutex::Locker rhs_locker (rhs.m_streams_mutex);
+ m_streams = rhs.m_streams;
+ }
+ return *this;
+ }
+
+ virtual void
+ Flush ()
+ {
+ Mutex::Locker locker (m_streams_mutex);
+ collection::iterator pos, end;
+ for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos)
+ {
+ // Allow for our collection to contain NULL streams. This allows
+ // the StreamTee to be used with hard coded indexes for clients
+ // that might want N total streams with only a few that are set
+ // to valid values.
+ Stream *strm = pos->get();
+ if (strm)
+ strm->Flush ();
+ }
+ }
+
+ virtual size_t
+ Write (const void *s, size_t length)
+ {
+ Mutex::Locker locker (m_streams_mutex);
+ if (m_streams.empty())
+ return 0;
+
+ size_t min_bytes_written = SIZE_MAX;
+ collection::iterator pos, end;
+ for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos)
+ {
+ // Allow for our collection to contain NULL streams. This allows
+ // the StreamTee to be used with hard coded indexes for clients
+ // that might want N total streams with only a few that are set
+ // to valid values.
+ Stream *strm = pos->get();
+ if (strm)
+ {
+ const size_t bytes_written = strm->Write (s, length);
+ if (min_bytes_written > bytes_written)
+ min_bytes_written = bytes_written;
+ }
+ }
+ if (min_bytes_written == SIZE_MAX)
+ return 0;
+ return min_bytes_written;
+ }
+
+ size_t
+ AppendStream (const lldb::StreamSP &stream_sp)
+ {
+ size_t new_idx = m_streams.size();
+ Mutex::Locker locker (m_streams_mutex);
+ m_streams.push_back (stream_sp);
+ return new_idx;
+ }
+
+ size_t
+ GetNumStreams () const
+ {
+ size_t result = 0;
+ {
+ Mutex::Locker locker (m_streams_mutex);
+ result = m_streams.size();
+ }
+ return result;
+ }
+
+ lldb::StreamSP
+ GetStreamAtIndex (uint32_t idx)
+ {
+ lldb::StreamSP stream_sp;
+ Mutex::Locker locker (m_streams_mutex);
+ if (idx < m_streams.size())
+ stream_sp = m_streams[idx];
+ return stream_sp;
+ }
+
+ void
+ SetStreamAtIndex (uint32_t idx, const lldb::StreamSP& stream_sp)
+ {
+ Mutex::Locker locker (m_streams_mutex);
+ // Resize our stream vector as necessary to fit as many streams
+ // as needed. This also allows this class to be used with hard
+ // coded indexes that can be used contain many streams, not all
+ // of which are valid.
+ if (idx >= m_streams.size())
+ m_streams.resize(idx + 1);
+ m_streams[idx] = stream_sp;
+ }
+
+
+protected:
+ typedef std::vector<lldb::StreamSP> collection;
+ mutable Mutex m_streams_mutex;
+ collection m_streams;
+};
+
+} // namespace lldb_private
+#endif // #ifndef liblldb_StreamTee_h_
diff --git a/include/lldb/Core/StringList.h b/include/lldb/Core/StringList.h
new file mode 100644
index 000000000000..5503274173cb
--- /dev/null
+++ b/include/lldb/Core/StringList.h
@@ -0,0 +1,107 @@
+//===-- StringList.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StringList_h_
+#define liblldb_StringList_h_
+
+#include <stdint.h>
+
+#include "lldb/Core/STLUtils.h"
+#include "lldb/lldb-forward.h"
+
+namespace lldb_private {
+
+class StringList
+{
+public:
+
+ StringList ();
+
+ StringList (const char *str);
+
+ StringList (const char **strv, int strc);
+
+ virtual
+ ~StringList ();
+
+ void
+ AppendString (const std::string &s);
+
+ void
+ AppendString (const char *str);
+
+ void
+ AppendString (const char *str, size_t str_len);
+
+ void
+ AppendList (const char ** strv, int strc);
+
+ void
+ AppendList (StringList strings);
+
+ bool
+ ReadFileLines (FileSpec &input_file);
+
+ size_t
+ GetSize () const;
+
+ const char *
+ GetStringAtIndex (size_t idx) const;
+
+ void
+ Join (const char *separator, Stream &strm);
+
+ void
+ Clear ();
+
+ void
+ LongestCommonPrefix (std::string &common_prefix);
+
+ void
+ InsertStringAtIndex (size_t id, const char *str);
+
+ void
+ DeleteStringAtIndex (size_t id);
+
+ void
+ RemoveBlankLines ();
+
+ size_t
+ SplitIntoLines (const char *lines, size_t len);
+
+ std::string
+ CopyList(const char* item_preamble = NULL,
+ const char* items_sep = "\n");
+
+ StringList&
+ operator << (const char* str);
+
+ StringList&
+ operator << (StringList strings);
+
+ // This string list contains a list of valid auto completion
+ // strings, and the "s" is passed in. "matches" is filled in
+ // with zero or more string values that start with "s", and
+ // the first string to exactly match one of the string
+ // values in this collection, will have "exact_matches_idx"
+ // filled in to match the index, or "exact_matches_idx" will
+ // have SIZE_MAX
+ size_t
+ AutoComplete (const char *s,
+ StringList &matches,
+ size_t &exact_matches_idx) const;
+
+private:
+
+ STLStringArray m_strings;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StringList_h_
diff --git a/include/lldb/Core/ThreadSafeSTLMap.h b/include/lldb/Core/ThreadSafeSTLMap.h
new file mode 100644
index 000000000000..703ce481f637
--- /dev/null
+++ b/include/lldb/Core/ThreadSafeSTLMap.h
@@ -0,0 +1,184 @@
+//===-- ThreadSafeSTLMap.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadSafeSTLMap_h_
+#define liblldb_ThreadSafeSTLMap_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+template <typename _Key, typename _Tp>
+class ThreadSafeSTLMap
+{
+public:
+ typedef std::map<_Key,_Tp> collection;
+ typedef typename collection::iterator iterator;
+ typedef typename collection::const_iterator const_iterator;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ThreadSafeSTLMap() :
+ m_collection (),
+ m_mutex (Mutex::eMutexTypeRecursive)
+ {
+ }
+
+ ~ThreadSafeSTLMap()
+ {
+ }
+
+ bool
+ IsEmpty() const
+ {
+ Mutex::Locker locker(m_mutex);
+ return m_collection.empty();
+ }
+
+ void
+ Clear()
+ {
+ Mutex::Locker locker(m_mutex);
+ return m_collection.clear();
+ }
+
+ size_t
+ Erase (const _Key& key)
+ {
+ Mutex::Locker locker(m_mutex);
+ return EraseNoLock (key);
+ }
+
+ size_t
+ EraseNoLock (const _Key& key)
+ {
+ return m_collection.erase (key);
+ }
+
+ bool
+ GetValueForKey (const _Key& key, _Tp &value) const
+ {
+ Mutex::Locker locker(m_mutex);
+ return GetValueForKeyNoLock (key, value);
+ }
+
+ // Call this if you have already manually locked the mutex using the
+ // GetMutex() accessor
+ bool
+ GetValueForKeyNoLock (const _Key& key, _Tp &value) const
+ {
+ const_iterator pos = m_collection.find(key);
+ if (pos != m_collection.end())
+ {
+ value = pos->second;
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ GetFirstKeyForValue (const _Tp &value, _Key& key) const
+ {
+ Mutex::Locker locker(m_mutex);
+ return GetFirstKeyForValueNoLock (value, key);
+ }
+
+ bool
+ GetFirstKeyForValueNoLock (const _Tp &value, _Key& key) const
+ {
+ const_iterator pos, end = m_collection.end();
+ for (pos = m_collection.begin(); pos != end; ++pos)
+ {
+ if (pos->second == value)
+ {
+ key = pos->first;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool
+ LowerBound (const _Key& key,
+ _Key& match_key,
+ _Tp &match_value,
+ bool decrement_if_not_equal) const
+ {
+ Mutex::Locker locker(m_mutex);
+ return LowerBoundNoLock (key, match_key, match_value, decrement_if_not_equal);
+ }
+
+ bool
+ LowerBoundNoLock (const _Key& key,
+ _Key& match_key,
+ _Tp &match_value,
+ bool decrement_if_not_equal) const
+ {
+ const_iterator pos = m_collection.lower_bound (key);
+ if (pos != m_collection.end())
+ {
+ match_key = pos->first;
+ if (decrement_if_not_equal && key != match_key && pos != m_collection.begin())
+ {
+ --pos;
+ match_key = pos->first;
+ }
+ match_value = pos->second;
+ return true;
+ }
+ return false;
+ }
+
+ iterator
+ lower_bound_unsafe (const _Key& key)
+ {
+ return m_collection.lower_bound (key);
+ }
+
+ void
+ SetValueForKey (const _Key& key, const _Tp &value)
+ {
+ Mutex::Locker locker(m_mutex);
+ SetValueForKeyNoLock (key, value);
+ }
+
+ // Call this if you have already manually locked the mutex using the
+ // GetMutex() accessor
+ void
+ SetValueForKeyNoLock (const _Key& key, const _Tp &value)
+ {
+ m_collection[key] = value;
+ }
+
+ Mutex &
+ GetMutex ()
+ {
+ return m_mutex;
+ }
+
+private:
+ collection m_collection;
+ mutable Mutex m_mutex;
+
+ //------------------------------------------------------------------
+ // For ThreadSafeSTLMap only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ThreadSafeSTLMap);
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadSafeSTLMap_h_
diff --git a/include/lldb/Core/ThreadSafeValue.h b/include/lldb/Core/ThreadSafeValue.h
new file mode 100644
index 000000000000..42a5a5c6725a
--- /dev/null
+++ b/include/lldb/Core/ThreadSafeValue.h
@@ -0,0 +1,96 @@
+//===-- ThreadSafeValue.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadSafeValue_h_
+#define liblldb_ThreadSafeValue_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+template <class T>
+class ThreadSafeValue
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ThreadSafeValue() :
+ m_value (),
+ m_mutex (Mutex::eMutexTypeRecursive)
+ {
+ }
+
+ ThreadSafeValue(const T& value) :
+ m_value (value),
+ m_mutex (Mutex::eMutexTypeRecursive)
+ {
+ }
+
+ ~ThreadSafeValue()
+ {
+ }
+
+ T
+ GetValue () const
+ {
+ T value;
+ {
+ Mutex::Locker locker(m_mutex);
+ value = m_value;
+ }
+ return value;
+ }
+
+ // Call this if you have already manually locked the mutex using the
+ // GetMutex() accessor
+ const T&
+ GetValueNoLock () const
+ {
+ return m_value;
+ }
+
+ void
+ SetValue (const T& value)
+ {
+ Mutex::Locker locker(m_mutex);
+ m_value = value;
+ }
+
+ // Call this if you have already manually locked the mutex using the
+ // GetMutex() accessor
+ void
+ SetValueNoLock (const T& value)
+ {
+ m_value = value;
+ }
+
+ Mutex &
+ GetMutex ()
+ {
+ return m_mutex;
+ }
+
+private:
+ T m_value;
+ mutable Mutex m_mutex;
+
+ //------------------------------------------------------------------
+ // For ThreadSafeValue only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ThreadSafeValue);
+};
+
+
+} // namespace lldb_private
+#endif // liblldb_ThreadSafeValue_h_
diff --git a/include/lldb/Core/Timer.h b/include/lldb/Core/Timer.h
new file mode 100644
index 000000000000..e354d91be442
--- /dev/null
+++ b/include/lldb/Core/Timer.h
@@ -0,0 +1,160 @@
+//===-- Timer.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Timer_h_
+#define liblldb_Timer_h_
+#if defined(__cplusplus)
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string>
+#include "lldb/lldb-private.h"
+#include "lldb/Host/TimeValue.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Timer Timer.h "lldb/Core/Timer.h"
+/// @brief A timer class that simplifies common timing metrics.
+///
+/// A scoped timer class that allows a variety of pthread mutex
+/// objects to have a mutex locked when a Timer::Locker
+/// object is created, and unlocked when it goes out of scope or
+/// when the Timer::Locker::Reset(pthread_mutex_t *)
+/// is called. This provides an exception safe way to lock a mutex
+/// in a scope.
+//----------------------------------------------------------------------
+
+class Timer
+{
+public:
+ static void
+ Initialize ();
+
+ //--------------------------------------------------------------
+ /// Default constructor.
+ //--------------------------------------------------------------
+ Timer(const char *category, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
+
+ //--------------------------------------------------------------
+ /// Desstructor
+ //--------------------------------------------------------------
+ ~Timer();
+
+ void
+ Dump ();
+
+ static void
+ SetDisplayDepth (uint32_t depth);
+
+ static void
+ SetQuiet (bool value);
+
+ static void
+ DumpCategoryTimes (Stream *s);
+
+ static void
+ ResetCategoryTimes ();
+
+protected:
+
+ void
+ ChildStarted (const TimeValue& time);
+
+ void
+ ChildStopped (const TimeValue& time);
+
+ uint64_t
+ GetTotalElapsedNanoSeconds();
+
+ uint64_t
+ GetTimerElapsedNanoSeconds();
+
+ //--------------------------------------------------------------
+ /// Member variables
+ //--------------------------------------------------------------
+ const char *m_category;
+ TimeValue m_total_start;
+ TimeValue m_timer_start;
+ uint64_t m_total_ticks; // Total running time for this timer including when other timers below this are running
+ uint64_t m_timer_ticks; // Ticks for this timer that do not include when other timers below this one are running
+ static uint32_t g_depth;
+ static uint32_t g_display_depth;
+ static FILE * g_file;
+private:
+ Timer();
+ DISALLOW_COPY_AND_ASSIGN (Timer);
+};
+
+class IntervalTimer
+{
+public:
+ IntervalTimer() :
+ m_start (TimeValue::Now())
+ {
+ }
+
+ ~IntervalTimer()
+ {
+ }
+
+ uint64_t
+ GetElapsedNanoSeconds() const
+ {
+ return TimeValue::Now() - m_start;
+ }
+
+ void
+ Reset ()
+ {
+ m_start = TimeValue::Now();
+ }
+
+ int
+ PrintfElapsed (const char *format, ...) __attribute__ ((format (printf, 2, 3)))
+ {
+ TimeValue now (TimeValue::Now());
+ const uint64_t elapsed_nsec = now - m_start;
+ const char *unit = NULL;
+ float elapsed_value;
+ if (elapsed_nsec < 1000)
+ {
+ unit = "ns";
+ elapsed_value = (float)elapsed_nsec;
+ }
+ else if (elapsed_nsec < 1000000)
+ {
+ unit = "us";
+ elapsed_value = (float)elapsed_nsec/1000.0f;
+ }
+ else if (elapsed_nsec < 1000000000)
+ {
+ unit = "ms";
+ elapsed_value = (float)elapsed_nsec/1000000.0f;
+ }
+ else
+ {
+ unit = "sec";
+ elapsed_value = (float)elapsed_nsec/1000000000.0f;
+ }
+ int result = printf ("%3.2f %s: ", elapsed_value, unit);
+ va_list args;
+ va_start (args, format);
+ result += vprintf (format, args);
+ va_end (args);
+ return result;
+ }
+protected:
+ TimeValue m_start;
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // #ifndef liblldb_Timer_h_
diff --git a/include/lldb/Core/UUID.h b/include/lldb/Core/UUID.h
new file mode 100644
index 000000000000..fe72b8eb0c70
--- /dev/null
+++ b/include/lldb/Core/UUID.h
@@ -0,0 +1,109 @@
+//===-- UUID.h --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_UUID_h_
+#define liblldb_UUID_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class UUID
+{
+public:
+ // Most UUIDs are 16 bytes, but some Linux build-ids (SHA1) are 20.
+ typedef uint8_t ValueType[20];
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ UUID ();
+ UUID (const UUID& rhs);
+ UUID (const void *uuid_bytes, uint32_t num_uuid_bytes);
+
+ ~UUID ();
+
+ const UUID&
+ operator=(const UUID& rhs);
+
+ void
+ Clear ();
+
+ void
+ Dump (Stream *s) const;
+
+ const void *
+ GetBytes() const;
+
+ size_t
+ GetByteSize();
+
+ bool
+ IsValid () const;
+
+ bool
+ SetBytes (const void *uuid_bytes, uint32_t num_uuid_bytes = 16);
+
+ std::string
+ GetAsString (const char *separator = NULL) const;
+
+ size_t
+ SetFromCString (const char *c_str, uint32_t num_uuid_bytes = 16);
+
+ // Decode as many UUID bytes (up to 16) as possible from the C string "cstr"
+ // This is used for auto completion where a partial UUID might have been
+ // typed in. It
+ //------------------------------------------------------------------
+ /// Decode as many UUID bytes (up to 16) as possible from the C
+ /// string \a cstr.
+ ///
+ /// @param[in] cstr
+ /// A NULL terminate C string that points at a UUID string value
+ /// (no leading spaces). The string must contain only hex
+ /// characters and optionally can contain the '-' sepearators.
+ ///
+ /// @param[in] uuid_bytes
+ /// A buffer of bytes that will contain a full or patially
+ /// decoded UUID.
+ ///
+ /// @param[out] end
+ /// If \a end is not NULL, it will be filled in with the a
+ /// pointer to the character after the last successfully decoded
+ /// byte.
+ ///
+ /// @return
+ /// Returns the number of bytes that were successfully decoded
+ /// which should be 16 if a full UUID value was properly decoded.
+ //------------------------------------------------------------------
+ static size_t
+ DecodeUUIDBytesFromCString (const char *cstr, ValueType &uuid_bytes, const char **end, uint32_t num_uuid_bytes = 16);
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from UUID can see and modify these
+ //------------------------------------------------------------------
+ uint32_t m_num_uuid_bytes; // Should be 16 or 20
+ ValueType m_uuid;
+};
+
+bool operator == (const UUID &lhs, const UUID &rhs);
+bool operator != (const UUID &lhs, const UUID &rhs);
+bool operator < (const UUID &lhs, const UUID &rhs);
+bool operator <= (const UUID &lhs, const UUID &rhs);
+bool operator > (const UUID &lhs, const UUID &rhs);
+bool operator >= (const UUID &lhs, const UUID &rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_UUID_h_
diff --git a/include/lldb/Core/UniqueCStringMap.h b/include/lldb/Core/UniqueCStringMap.h
new file mode 100644
index 000000000000..972c0d53ea99
--- /dev/null
+++ b/include/lldb/Core/UniqueCStringMap.h
@@ -0,0 +1,361 @@
+//===-- UniqueCStringMap.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_UniqueCStringMap_h_
+#define liblldb_UniqueCStringMap_h_
+#if defined(__cplusplus)
+
+#include <assert.h>
+#include <algorithm>
+#include <vector>
+
+#include "lldb/Core/RegularExpression.h"
+
+namespace lldb_private {
+
+
+
+//----------------------------------------------------------------------
+// Templatized uniqued string map.
+//
+// This map is useful for mapping unique C string names to values of
+// type T. Each "const char *" name added must be unique for a given
+// C string value. ConstString::GetCString() can provide such strings.
+// Any other string table that has guaranteed unique values can also
+// be used.
+//----------------------------------------------------------------------
+template <typename T>
+class UniqueCStringMap
+{
+public:
+ struct Entry
+ {
+ Entry () :
+ cstring(NULL),
+ value()
+ {
+ }
+
+ Entry (const char *cstr) :
+ cstring(cstr),
+ value()
+ {
+ }
+
+ Entry (const char *cstr, const T&v) :
+ cstring(cstr),
+ value(v)
+ {
+ }
+
+ bool
+ operator < (const Entry& rhs) const
+ {
+ return cstring < rhs.cstring;
+ }
+
+ const char* cstring;
+ T value;
+ };
+
+ //------------------------------------------------------------------
+ // Call this function multiple times to add a bunch of entries to
+ // this map, then later call UniqueCStringMap<T>::Sort() before doing
+ // any searches by name.
+ //------------------------------------------------------------------
+ void
+ Append (const char *unique_cstr, const T& value)
+ {
+ m_map.push_back (typename UniqueCStringMap<T>::Entry(unique_cstr, value));
+ }
+
+ void
+ Append (const Entry &e)
+ {
+ m_map.push_back (e);
+ }
+
+ void
+ Clear ()
+ {
+ m_map.clear();
+ }
+
+ //------------------------------------------------------------------
+ // Call this function to always keep the map sorted when putting
+ // entries into the map.
+ //------------------------------------------------------------------
+ void
+ Insert (const char *unique_cstr, const T& value)
+ {
+ typename UniqueCStringMap<T>::Entry e(unique_cstr, value);
+ m_map.insert (std::upper_bound (m_map.begin(), m_map.end(), e), e);
+ }
+
+ void
+ Insert (const Entry &e)
+ {
+ m_map.insert (std::upper_bound (m_map.begin(), m_map.end(), e), e);
+ }
+
+ //------------------------------------------------------------------
+ // Get an entries by index in a variety of forms.
+ //
+ // The caller is responsible for ensuring that the collection does
+ // not change during while using the returned values.
+ //------------------------------------------------------------------
+ bool
+ GetValueAtIndex (uint32_t idx, T &value) const
+ {
+ if (idx < m_map.size())
+ {
+ value = m_map[idx].value;
+ return true;
+ }
+ return false;
+ }
+
+ const char *
+ GetCStringAtIndexUnchecked (uint32_t idx) const
+ {
+ return m_map[idx].cstring;
+ }
+
+ // Use this function if you have simple types in your map that you
+ // can easily copy when accessing values by index.
+ T
+ GetValueAtIndexUnchecked (uint32_t idx) const
+ {
+ return m_map[idx].value;
+ }
+
+ // Use this function if you have complex types in your map that you
+ // don't want to copy when accessing values by index.
+ const T &
+ GetValueRefAtIndexUnchecked (uint32_t idx) const
+ {
+ return m_map[idx].value;
+ }
+
+ const char *
+ GetCStringAtIndex (uint32_t idx) const
+ {
+ if (idx < m_map.size())
+ return m_map[idx].cstring;
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ // Find the value for the unique string in the map.
+ //
+ // Return the value for \a unique_cstr if one is found, return
+ // \a fail_value otherwise. This method works well for simple type
+ // T values and only if there is a sensible failure value that can
+ // be returned and that won't match any existing values.
+ //------------------------------------------------------------------
+ T
+ Find (const char *unique_cstr, T fail_value) const
+ {
+ Entry search_entry (unique_cstr);
+ const_iterator end = m_map.end();
+ const_iterator pos = std::lower_bound (m_map.begin(), end, search_entry);
+ if (pos != end)
+ {
+ if (pos->cstring == unique_cstr)
+ return pos->value;
+ }
+ return fail_value;
+ }
+ //------------------------------------------------------------------
+ // Get a pointer to the first entry that matches "name". NULL will
+ // be returned if there is no entry that matches "name".
+ //
+ // The caller is responsible for ensuring that the collection does
+ // not change during while using the returned pointer.
+ //------------------------------------------------------------------
+ const Entry *
+ FindFirstValueForName (const char *unique_cstr) const
+ {
+ Entry search_entry (unique_cstr);
+ const_iterator end = m_map.end();
+ const_iterator pos = std::lower_bound (m_map.begin(), end, search_entry);
+ if (pos != end)
+ {
+ const char *pos_cstr = pos->cstring;
+ if (pos_cstr == unique_cstr)
+ return &(*pos);
+ }
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ // Get a pointer to the next entry that matches "name" from a
+ // previously returned Entry pointer. NULL will be returned if there
+ // is no subsequent entry that matches "name".
+ //
+ // The caller is responsible for ensuring that the collection does
+ // not change during while using the returned pointer.
+ //------------------------------------------------------------------
+ const Entry *
+ FindNextValueForName (const Entry *entry_ptr) const
+ {
+ if (!m_map.empty())
+ {
+ const Entry *first_entry = &m_map[0];
+ const Entry *after_last_entry = first_entry + m_map.size();
+ const Entry *next_entry = entry_ptr + 1;
+ if (first_entry <= next_entry && next_entry < after_last_entry)
+ {
+ if (next_entry->cstring == entry_ptr->cstring)
+ return next_entry;
+ }
+ }
+ return NULL;
+ }
+
+ size_t
+ GetValues (const char *unique_cstr, std::vector<T> &values) const
+ {
+ const size_t start_size = values.size();
+
+ Entry search_entry (unique_cstr);
+ const_iterator pos, end = m_map.end();
+ for (pos = std::lower_bound (m_map.begin(), end, search_entry); pos != end; ++pos)
+ {
+ if (pos->cstring == unique_cstr)
+ values.push_back (pos->value);
+ else
+ break;
+ }
+
+ return values.size() - start_size;
+ }
+
+ size_t
+ GetValues (const RegularExpression& regex, std::vector<T> &values) const
+ {
+ const size_t start_size = values.size();
+
+ const_iterator pos, end = m_map.end();
+ for (pos = m_map.begin(); pos != end; ++pos)
+ {
+ if (regex.Execute(pos->cstring))
+ values.push_back (pos->value);
+ }
+
+ return values.size() - start_size;
+ }
+
+ //------------------------------------------------------------------
+ // Get the total number of entries in this map.
+ //------------------------------------------------------------------
+ size_t
+ GetSize () const
+ {
+ return m_map.size();
+ }
+
+
+ //------------------------------------------------------------------
+ // Returns true if this map is empty.
+ //------------------------------------------------------------------
+ bool
+ IsEmpty() const
+ {
+ return m_map.empty();
+ }
+
+ //------------------------------------------------------------------
+ // Reserve memory for at least "n" entries in the map. This is
+ // useful to call when you know you will be adding a lot of entries
+ // using UniqueCStringMap::Append() (which should be followed by a
+ // call to UniqueCStringMap::Sort()) or to UniqueCStringMap::Insert().
+ //------------------------------------------------------------------
+ void
+ Reserve (size_t n)
+ {
+ m_map.reserve (n);
+ }
+
+ //------------------------------------------------------------------
+ // Sort the unsorted contents in this map. A typical code flow would
+ // be:
+ // size_t approximate_num_entries = ....
+ // UniqueCStringMap<uint32_t> my_map;
+ // my_map.Reserve (approximate_num_entries);
+ // for (...)
+ // {
+ // my_map.Append (UniqueCStringMap::Entry(GetName(...), GetValue(...)));
+ // }
+ // my_map.Sort();
+ //------------------------------------------------------------------
+ void
+ Sort ()
+ {
+ std::sort (m_map.begin(), m_map.end());
+ }
+
+ //------------------------------------------------------------------
+ // Since we are using a vector to contain our items it will always
+ // double its memory consumption as things are added to the vector,
+ // so if you intend to keep a UniqueCStringMap around and have
+ // a lot of entries in the map, you will want to call this function
+ // to create a new vector and copy _only_ the exact size needed as
+ // part of the finalization of the string map.
+ //------------------------------------------------------------------
+ void
+ SizeToFit ()
+ {
+ if (m_map.size() < m_map.capacity())
+ {
+ collection temp (m_map.begin(), m_map.end());
+ m_map.swap(temp);
+ }
+ }
+
+ size_t
+ Erase (const char *unique_cstr)
+ {
+ size_t num_removed = 0;
+ Entry search_entry (unique_cstr);
+ iterator end = m_map.end();
+ iterator begin = m_map.begin();
+ iterator lower_pos = std::lower_bound (begin, end, search_entry);
+ if (lower_pos != end)
+ {
+ if (lower_pos->cstring == unique_cstr)
+ {
+ iterator upper_pos = std::upper_bound (lower_pos, end, search_entry);
+ if (lower_pos == upper_pos)
+ {
+ m_map.erase (lower_pos);
+ num_removed = 1;
+ }
+ else
+ {
+ num_removed = std::distance (lower_pos, upper_pos);
+ m_map.erase (lower_pos, upper_pos);
+ }
+ }
+ }
+ return num_removed;
+ }
+protected:
+ typedef std::vector<Entry> collection;
+ typedef typename collection::iterator iterator;
+ typedef typename collection::const_iterator const_iterator;
+ collection m_map;
+};
+
+
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_UniqueCStringMap_h_
diff --git a/include/lldb/Core/UserID.h b/include/lldb/Core/UserID.h
new file mode 100644
index 000000000000..ea6af74759bf
--- /dev/null
+++ b/include/lldb/Core/UserID.h
@@ -0,0 +1,130 @@
+//===-- UserID.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef liblldb_UserID_h_
+#define liblldb_UserID_h_
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class UserID UserID.h "lldb/Core/UserID.h"
+/// @brief A mix in class that contains a generic user ID.
+///
+/// UserID is desinged as a mix in class that can contain an integer
+/// based unique identifier for a varietly of objects in lldb.
+///
+/// The value for this identifier is chosen by each parser plug-in. A
+/// value should be chosen that makes sense for each kind of object
+/// should and allows quick access to further and more in depth parsing.
+///
+/// Symbol table entries can use this to store the original symbol table
+/// index, functions can use it to store the symbol table index or the
+/// DWARF offset.
+//----------------------------------------------------------------------
+struct UserID
+{
+ //------------------------------------------------------------------
+ /// Construct with optional user ID.
+ //------------------------------------------------------------------
+ UserID (lldb::user_id_t uid = LLDB_INVALID_UID) : m_uid(uid) {}
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~UserID ()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Clears the object state.
+ ///
+ /// Clears the object contents back to a default invalid state.
+ //------------------------------------------------------------------
+ void
+ Clear () { m_uid = LLDB_INVALID_UID; }
+
+ //------------------------------------------------------------------
+ /// Get accessor for the user ID.
+ ///
+ /// @return
+ /// The user ID.
+ //------------------------------------------------------------------
+ lldb::user_id_t
+ GetID () const { return m_uid; }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the user ID.
+ ///
+ /// @param[in] uid
+ /// The new user ID.
+ //------------------------------------------------------------------
+ void
+ SetID (lldb::user_id_t uid) { m_uid = uid; }
+
+ //------------------------------------------------------------------
+ /// Unary predicate function object that can search for a matching
+ /// user ID.
+ ///
+ /// Function object that can be used on any class that inherits
+ /// from UserID:
+ /// \code
+ /// iterator pos;
+ /// pos = std::find_if (coll.begin(), coll.end(), UserID::IDMatches(blockID));
+ /// \endcode
+ //------------------------------------------------------------------
+ class IDMatches
+ {
+ public:
+ //--------------------------------------------------------------
+ /// Construct with the user ID to look for.
+ //--------------------------------------------------------------
+ IDMatches (lldb::user_id_t uid) : m_uid(uid) {}
+
+ //--------------------------------------------------------------
+ /// Unary predicate function object callback.
+ //--------------------------------------------------------------
+ bool
+ operator () (const UserID& rhs) const { return m_uid == rhs.GetID(); }
+
+ private:
+ //--------------------------------------------------------------
+ // Member variables.
+ //--------------------------------------------------------------
+ const lldb::user_id_t m_uid; ///< The user ID we are looking for
+ };
+
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ lldb::user_id_t m_uid; ///< The user ID that uniquely identifies an object.
+};
+
+inline bool operator== (const UserID& lhs, const UserID& rhs)
+{
+ return lhs.GetID() == rhs.GetID();
+}
+
+inline bool operator!= (const UserID& lhs, const UserID& rhs)
+{
+ return lhs.GetID() != rhs.GetID();
+}
+
+//--------------------------------------------------------------
+/// Stream the UserID object to a Stream.
+//--------------------------------------------------------------
+Stream& operator << (Stream& strm, const UserID& uid);
+
+} // namespace lldb_private
+
+#endif // liblldb_UserID_h_
diff --git a/include/lldb/Core/UserSettingsController.h b/include/lldb/Core/UserSettingsController.h
new file mode 100644
index 000000000000..7e72b89ad8e6
--- /dev/null
+++ b/include/lldb/Core/UserSettingsController.h
@@ -0,0 +1,98 @@
+//====-- UserSettingsController.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_UserSettingsController_h_
+#define liblldb_UserSettingsController_h_
+
+// C Includes
+// C++ Includes
+
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class Properties
+{
+public:
+ Properties () :
+ m_collection_sp ()
+ {
+ }
+
+ Properties (const lldb::OptionValuePropertiesSP &collection_sp) :
+ m_collection_sp (collection_sp)
+ {
+ }
+
+ virtual
+ ~Properties()
+ {
+ }
+
+ virtual lldb::OptionValuePropertiesSP
+ GetValueProperties () const
+ {
+ // This function is virtual in case subclasses want to lazily
+ // implement creating the properties.
+ return m_collection_sp;
+ }
+
+ virtual lldb::OptionValueSP
+ GetPropertyValue (const ExecutionContext *exe_ctx,
+ const char *property_path,
+ bool will_modify,
+ Error &error) const;
+
+ virtual Error
+ SetPropertyValue (const ExecutionContext *exe_ctx,
+ VarSetOperationType op,
+ const char *property_path,
+ const char *value);
+
+ virtual Error
+ DumpPropertyValue (const ExecutionContext *exe_ctx,
+ Stream &strm,
+ const char *property_path,
+ uint32_t dump_mask);
+
+ virtual void
+ DumpAllPropertyValues (const ExecutionContext *exe_ctx,
+ Stream &strm,
+ uint32_t dump_mask);
+
+ virtual void
+ DumpAllDescriptions (CommandInterpreter &interpreter,
+ Stream &strm) const;
+
+ size_t
+ Apropos (const char *keyword,
+ std::vector<const Property *> &matching_properties) const;
+
+ lldb::OptionValuePropertiesSP
+ GetSubProperty (const ExecutionContext *exe_ctx,
+ const ConstString &name);
+protected:
+ lldb::OptionValuePropertiesSP m_collection_sp;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_UserSettingsController_h_
diff --git a/include/lldb/Core/VMRange.h b/include/lldb/Core/VMRange.h
new file mode 100644
index 000000000000..94c83e730e96
--- /dev/null
+++ b/include/lldb/Core/VMRange.h
@@ -0,0 +1,181 @@
+//===-- VMRange.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_VMRange_h_
+#define liblldb_VMRange_h_
+
+#include "lldb/lldb-private.h"
+#include <vector>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A vm address range. These can represent offsets ranges or actual
+// addresses.
+//----------------------------------------------------------------------
+class VMRange
+{
+public:
+
+ typedef std::vector<VMRange> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ VMRange() :
+ m_base_addr(0),
+ m_byte_size(0)
+ {
+ }
+
+ VMRange(lldb::addr_t start_addr, lldb::addr_t end_addr) :
+ m_base_addr(start_addr),
+ m_byte_size(end_addr > start_addr ? end_addr - start_addr : 0)
+ {
+ }
+
+ ~VMRange()
+ {
+ }
+
+ void
+ Clear ()
+ {
+ m_base_addr = 0;
+ m_byte_size = 0;
+ }
+
+ // Set the start and end values
+ void
+ Reset (lldb::addr_t start_addr, lldb::addr_t end_addr)
+ {
+ SetBaseAddress (start_addr);
+ SetEndAddress (end_addr);
+ }
+
+ // Set the start value for the range, and keep the same size
+ void
+ SetBaseAddress (lldb::addr_t base_addr)
+ {
+ m_base_addr = base_addr;
+ }
+
+ void
+ SetEndAddress (lldb::addr_t end_addr)
+ {
+ const lldb::addr_t base_addr = GetBaseAddress();
+ if (end_addr > base_addr)
+ m_byte_size = end_addr - base_addr;
+ else
+ m_byte_size = 0;
+ }
+
+ lldb::addr_t
+ GetByteSize () const
+ {
+ return m_byte_size;
+ }
+
+ void
+ SetByteSize (lldb::addr_t byte_size)
+ {
+ m_byte_size = byte_size;
+ }
+
+ lldb::addr_t
+ GetBaseAddress () const
+ {
+ return m_base_addr;
+ }
+
+ lldb::addr_t
+ GetEndAddress () const
+ {
+ return GetBaseAddress() + m_byte_size;
+ }
+
+ bool
+ IsValid() const
+ {
+ return m_byte_size > 0;
+ }
+
+ bool
+ Contains (lldb::addr_t addr) const
+ {
+ return (GetBaseAddress() <= addr) && (addr < GetEndAddress());
+ }
+
+ bool
+ Contains (const VMRange& range) const
+ {
+ if (Contains(range.GetBaseAddress()))
+ {
+ lldb::addr_t range_end = range.GetEndAddress();
+ return (GetBaseAddress() <= range_end) && (range_end <= GetEndAddress());
+ }
+ return false;
+ }
+
+ void
+ Dump (Stream *s, lldb::addr_t base_addr = 0, uint32_t addr_width = 8) const;
+
+ class ValueInRangeUnaryPredicate
+ {
+ public:
+ ValueInRangeUnaryPredicate(lldb::addr_t value) :
+ _value(value)
+ {
+ }
+ bool operator()(const VMRange& range) const
+ {
+ return range.Contains(_value);
+ }
+ lldb::addr_t _value;
+ };
+
+ class RangeInRangeUnaryPredicate
+ {
+ public:
+ RangeInRangeUnaryPredicate(VMRange range) :
+ _range(range)
+ {
+ }
+ bool operator()(const VMRange& range) const
+ {
+ return range.Contains(_range);
+ }
+ const VMRange& _range;
+ };
+
+ static bool
+ ContainsValue(const VMRange::collection& coll, lldb::addr_t value);
+
+ static bool
+ ContainsRange(const VMRange::collection& coll, const VMRange& range);
+
+ // Returns a valid index into coll when a match is found, else UINT32_MAX
+ // is returned
+ static size_t
+ FindRangeIndexThatContainsValue (const VMRange::collection& coll, lldb::addr_t value);
+
+protected:
+ lldb::addr_t m_base_addr;
+ lldb::addr_t m_byte_size;
+};
+
+bool operator== (const VMRange& lhs, const VMRange& rhs);
+bool operator!= (const VMRange& lhs, const VMRange& rhs);
+bool operator< (const VMRange& lhs, const VMRange& rhs);
+bool operator<= (const VMRange& lhs, const VMRange& rhs);
+bool operator> (const VMRange& lhs, const VMRange& rhs);
+bool operator>= (const VMRange& lhs, const VMRange& rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_VMRange_h_
diff --git a/include/lldb/Core/Value.h b/include/lldb/Core/Value.h
new file mode 100644
index 000000000000..5461ca73d082
--- /dev/null
+++ b/include/lldb/Core/Value.h
@@ -0,0 +1,314 @@
+//===-- Value.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Value_h_
+#define liblldb_Value_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Symbol/ClangASTType.h"
+
+namespace lldb_private {
+
+class Value
+{
+public:
+
+ // Values Less than zero are an error, greater than or equal to zero
+ // returns what the Scalar result is.
+ enum ValueType
+ {
+ // m_value contains...
+ // ============================
+ eValueTypeScalar, // raw scalar value
+ eValueTypeVector, // byte array of m_vector.length with endianness of m_vector.byte_order
+ eValueTypeFileAddress, // file address value
+ eValueTypeLoadAddress, // load address value
+ eValueTypeHostAddress // host address value (for memory in the process that is using liblldb)
+ };
+
+ enum ContextType // Type that describes Value::m_context
+ {
+ // m_context contains...
+ // ====================
+ eContextTypeInvalid, // undefined
+ eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector register)
+ eContextTypeLLDBType, // lldb_private::Type *
+ eContextTypeVariable // lldb_private::Variable *
+ };
+
+ const static size_t kMaxByteSize = 32u;
+
+ struct Vector
+ {
+ // The byte array must be big enough to hold vector registers for any supported target.
+ uint8_t bytes[kMaxByteSize];
+ size_t length;
+ lldb::ByteOrder byte_order;
+
+ Vector() :
+ length(0),
+ byte_order(lldb::eByteOrderInvalid)
+ {
+ }
+
+ Vector(const Vector& vector)
+ { *this = vector;
+ }
+ const Vector&
+ operator=(const Vector& vector)
+ {
+ SetBytes(vector.bytes, vector.length, vector.byte_order);
+ return *this;
+ }
+
+ void
+ Clear ()
+ {
+ length = 0;
+ }
+
+ bool
+ SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
+ {
+ this->length = length;
+ this->byte_order = byte_order;
+ if (length)
+ ::memcpy(this->bytes, bytes, length < kMaxByteSize ? length : kMaxByteSize);
+ return IsValid();
+ }
+
+ bool
+ IsValid() const
+ {
+ return (length > 0 && length < kMaxByteSize && byte_order != lldb::eByteOrderInvalid);
+ }
+ // Casts a vector, if valid, to an unsigned int of matching or largest supported size.
+ // Truncates to the beginning of the vector if required.
+ // Returns a default constructed Scalar if the Vector data is internally inconsistent.
+ Scalar
+ GetAsScalar() const
+ {
+ Scalar scalar;
+ if (IsValid())
+ {
+ if (length == 1) scalar = *(const uint8_t *)bytes;
+ else if (length == 2) scalar = *(const uint16_t *)bytes;
+ else if (length == 4) scalar = *(const uint32_t *)bytes;
+ else if (length == 8) scalar = *(const uint64_t *)bytes;
+#if defined (ENABLE_128_BIT_SUPPORT)
+ else if (length >= 16) scalar = *(const __uint128_t *)bytes;
+#else
+ else if (length >= 16) scalar = *(const __uint64_t *)bytes;
+#endif
+ }
+ return scalar;
+ }
+ };
+
+ Value();
+ Value(const Scalar& scalar);
+ Value(const Vector& vector);
+ Value(const uint8_t *bytes, int len);
+ Value(const Value &rhs);
+
+ Value &
+ operator=(const Value &rhs);
+
+ const ClangASTType &
+ GetClangType();
+
+ void
+ SetClangType (const ClangASTType &clang_type);
+
+ ValueType
+ GetValueType() const;
+
+ AddressType
+ GetValueAddressType () const;
+
+ ContextType
+ GetContextType() const
+ {
+ return m_context_type;
+ }
+
+ void
+ SetValueType (ValueType value_type)
+ {
+ m_value_type = value_type;
+ }
+
+ void
+ ClearContext ()
+ {
+ m_context = NULL;
+ m_context_type = eContextTypeInvalid;
+ }
+
+ void
+ SetContext (ContextType context_type, void *p)
+ {
+ m_context_type = context_type;
+ m_context = p;
+ if (m_context_type == eContextTypeRegisterInfo) {
+ RegisterInfo *reg_info = GetRegisterInfo();
+ if (reg_info->encoding == lldb::eEncodingVector)
+ SetValueType(eValueTypeVector);
+ else
+ SetValueType(eValueTypeScalar);
+ }
+ }
+
+ RegisterInfo *
+ GetRegisterInfo() const;
+
+ Type *
+ GetType();
+
+ Scalar &
+ ResolveValue (ExecutionContext *exe_ctx);
+
+ const Scalar &
+ GetScalar() const
+ {
+ return m_value;
+ }
+
+ const Vector &
+ GetVector() const
+ {
+ return m_vector;
+ }
+
+ Scalar &
+ GetScalar()
+ {
+ return m_value;
+ }
+
+ Vector &
+ GetVector()
+ {
+ return m_vector;
+ }
+
+ bool
+ SetVectorBytes(const Vector& vector)
+ {
+ m_vector = vector;
+ return m_vector.IsValid();
+ }
+
+ bool
+ SetVectorBytes(uint8_t *bytes, size_t length, lldb::ByteOrder byte_order)
+ {
+ return m_vector.SetBytes(bytes, length, byte_order);
+ }
+
+ bool
+ SetScalarFromVector()
+ {
+ if (m_vector.IsValid())
+ {
+ m_value = m_vector.GetAsScalar();
+ return true;
+ }
+ return false;
+ }
+
+ void
+ ResizeData(size_t len);
+
+ bool
+ ValueOf(ExecutionContext *exe_ctx);
+
+ Variable *
+ GetVariable();
+
+ void
+ Dump (Stream* strm);
+
+ lldb::Format
+ GetValueDefaultFormat ();
+
+ uint64_t
+ GetValueByteSize (Error *error_ptr);
+
+ Error
+ GetValueAsData (ExecutionContext *exe_ctx,
+ DataExtractor &data,
+ uint32_t data_offset,
+ Module *module); // Can be NULL
+
+ static const char *
+ GetValueTypeAsCString (ValueType context_type);
+
+ static const char *
+ GetContextTypeAsCString (ContextType context_type);
+
+ bool
+ GetData (DataExtractor &data);
+
+ void
+ Clear();
+
+protected:
+ Scalar m_value;
+ Vector m_vector;
+ ClangASTType m_clang_type;
+ void * m_context;
+ ValueType m_value_type;
+ ContextType m_context_type;
+ DataBufferHeap m_data_buffer;
+};
+
+class ValueList
+{
+public:
+ ValueList () :
+ m_values()
+ {
+ }
+
+ ValueList (const ValueList &rhs);
+
+ ~ValueList ()
+ {
+ }
+
+ const ValueList & operator= (const ValueList &rhs);
+
+ // void InsertValue (Value *value, size_t idx);
+ void PushValue (const Value &value);
+
+ size_t GetSize ();
+ Value *GetValueAtIndex(size_t idx);
+ void Clear();
+
+protected:
+
+private:
+ typedef std::vector<Value> collection;
+
+ collection m_values;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Value_h_
diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h
new file mode 100644
index 000000000000..0d965d6ccc01
--- /dev/null
+++ b/include/lldb/Core/ValueObject.h
@@ -0,0 +1,1375 @@
+//===-- ValueObject.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObject_h_
+#define liblldb_ValueObject_h_
+
+// C Includes
+// C++ Includes
+#include <initializer_list>
+#include <map>
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StackID.h"
+#include "lldb/Utility/SharedCluster.h"
+
+namespace lldb_private {
+
+/// ValueObject:
+///
+/// This abstract class provides an interface to a particular value, be it a register, a local or global variable,
+/// that is evaluated in some particular scope. The ValueObject also has the capibility of being the "child" of
+/// some other variable object, and in turn of having children.
+/// If a ValueObject is a root variable object - having no parent - then it must be constructed with respect to some
+/// particular ExecutionContextScope. If it is a child, it inherits the ExecutionContextScope from its parent.
+/// The ValueObject will update itself if necessary before fetching its value, summary, object description, etc.
+/// But it will always update itself in the ExecutionContextScope with which it was originally created.
+
+/// A brief note on life cycle management for ValueObjects. This is a little tricky because a ValueObject can contain
+/// various other ValueObjects - the Dynamic Value, its children, the dereference value, etc. Any one of these can be
+/// handed out as a shared pointer, but for that contained value object to be valid, the root object and potentially other
+/// of the value objects need to stay around.
+/// We solve this problem by handing out shared pointers to the Value Object and any of its dependents using a shared
+/// ClusterManager. This treats each shared pointer handed out for the entire cluster as a reference to the whole
+/// cluster. The whole cluster will stay around until the last reference is released.
+///
+/// The ValueObject mostly handle this automatically, if a value object is made with a Parent ValueObject, then it adds
+/// itself to the ClusterManager of the parent.
+
+/// It does mean that external to the ValueObjects we should only ever make available ValueObjectSP's, never ValueObjects
+/// or pointers to them. So all the "Root level" ValueObject derived constructors should be private, and
+/// should implement a Create function that new's up object and returns a Shared Pointer that it gets from the GetSP() method.
+///
+/// However, if you are making an derived ValueObject that will be contained in a parent value object, you should just
+/// hold onto a pointer to it internally, and by virtue of passing the parent ValueObject into its constructor, it will
+/// be added to the ClusterManager for the parent. Then if you ever hand out a Shared Pointer to the contained ValueObject,
+/// just do so by calling GetSP() on the contained object.
+
+class ValueObject : public UserID
+{
+public:
+
+ enum GetExpressionPathFormat
+ {
+ eGetExpressionPathFormatDereferencePointers = 1,
+ eGetExpressionPathFormatHonorPointers
+ };
+
+ enum ValueObjectRepresentationStyle
+ {
+ eValueObjectRepresentationStyleValue = 1,
+ eValueObjectRepresentationStyleSummary,
+ eValueObjectRepresentationStyleLanguageSpecific,
+ eValueObjectRepresentationStyleLocation,
+ eValueObjectRepresentationStyleChildrenCount,
+ eValueObjectRepresentationStyleType,
+ eValueObjectRepresentationStyleName,
+ eValueObjectRepresentationStyleExpressionPath
+ };
+
+ enum ExpressionPathScanEndReason
+ {
+ eExpressionPathScanEndReasonEndOfString = 1, // out of data to parse
+ eExpressionPathScanEndReasonNoSuchChild, // child element not found
+ eExpressionPathScanEndReasonEmptyRangeNotAllowed, // [] only allowed for arrays
+ eExpressionPathScanEndReasonDotInsteadOfArrow, // . used when -> should be used
+ eExpressionPathScanEndReasonArrowInsteadOfDot, // -> used when . should be used
+ eExpressionPathScanEndReasonFragileIVarNotAllowed, // ObjC ivar expansion not allowed
+ eExpressionPathScanEndReasonRangeOperatorNotAllowed, // [] not allowed by options
+ eExpressionPathScanEndReasonRangeOperatorInvalid, // [] not valid on objects other than scalars, pointers or arrays
+ eExpressionPathScanEndReasonArrayRangeOperatorMet, // [] is good for arrays, but I cannot parse it
+ eExpressionPathScanEndReasonBitfieldRangeOperatorMet, // [] is good for bitfields, but I cannot parse after it
+ eExpressionPathScanEndReasonUnexpectedSymbol, // something is malformed in the expression
+ eExpressionPathScanEndReasonTakingAddressFailed, // impossible to apply & operator
+ eExpressionPathScanEndReasonDereferencingFailed, // impossible to apply * operator
+ eExpressionPathScanEndReasonRangeOperatorExpanded, // [] was expanded into a VOList
+ eExpressionPathScanEndReasonSyntheticValueMissing, // getting the synthetic children failed
+ eExpressionPathScanEndReasonUnknown = 0xFFFF
+ };
+
+ enum ExpressionPathEndResultType
+ {
+ eExpressionPathEndResultTypePlain = 1, // anything but...
+ eExpressionPathEndResultTypeBitfield, // a bitfield
+ eExpressionPathEndResultTypeBoundedRange, // a range [low-high]
+ eExpressionPathEndResultTypeUnboundedRange, // a range []
+ eExpressionPathEndResultTypeValueObjectList, // several items in a VOList
+ eExpressionPathEndResultTypeInvalid = 0xFFFF
+ };
+
+ enum ExpressionPathAftermath
+ {
+ eExpressionPathAftermathNothing = 1, // just return it
+ eExpressionPathAftermathDereference, // dereference the target
+ eExpressionPathAftermathTakeAddress // take target's address
+ };
+
+ enum ClearUserVisibleDataItems
+ {
+ eClearUserVisibleDataItemsNothing = 1u << 0,
+ eClearUserVisibleDataItemsValue = 1u << 1,
+ eClearUserVisibleDataItemsSummary = 1u << 2,
+ eClearUserVisibleDataItemsLocation = 1u << 3,
+ eClearUserVisibleDataItemsDescription = 1u << 4,
+ eClearUserVisibleDataItemsSyntheticChildren = 1u << 5,
+ eClearUserVisibleDataItemsAllStrings = eClearUserVisibleDataItemsValue | eClearUserVisibleDataItemsSummary | eClearUserVisibleDataItemsLocation | eClearUserVisibleDataItemsDescription,
+ eClearUserVisibleDataItemsAll = 0xFFFF
+ };
+
+ struct GetValueForExpressionPathOptions
+ {
+ bool m_check_dot_vs_arrow_syntax;
+ bool m_no_fragile_ivar;
+ bool m_allow_bitfields_syntax;
+ bool m_no_synthetic_children;
+
+ GetValueForExpressionPathOptions(bool dot = false,
+ bool no_ivar = false,
+ bool bitfield = true,
+ bool no_synth = false) :
+ m_check_dot_vs_arrow_syntax(dot),
+ m_no_fragile_ivar(no_ivar),
+ m_allow_bitfields_syntax(bitfield),
+ m_no_synthetic_children(no_synth)
+ {
+ }
+
+ GetValueForExpressionPathOptions&
+ DoCheckDotVsArrowSyntax()
+ {
+ m_check_dot_vs_arrow_syntax = true;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions&
+ DontCheckDotVsArrowSyntax()
+ {
+ m_check_dot_vs_arrow_syntax = false;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions&
+ DoAllowFragileIVar()
+ {
+ m_no_fragile_ivar = false;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions&
+ DontAllowFragileIVar()
+ {
+ m_no_fragile_ivar = true;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions&
+ DoAllowBitfieldSyntax()
+ {
+ m_allow_bitfields_syntax = true;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions&
+ DontAllowBitfieldSyntax()
+ {
+ m_allow_bitfields_syntax = false;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions&
+ DoAllowSyntheticChildren()
+ {
+ m_no_synthetic_children = false;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions&
+ DontAllowSyntheticChildren()
+ {
+ m_no_synthetic_children = true;
+ return *this;
+ }
+
+ static const GetValueForExpressionPathOptions
+ DefaultOptions()
+ {
+ static GetValueForExpressionPathOptions g_default_options;
+
+ return g_default_options;
+ }
+
+ };
+
+ struct DumpValueObjectOptions
+ {
+ uint32_t m_max_ptr_depth;
+ uint32_t m_max_depth;
+ bool m_show_types;
+ bool m_show_location;
+ bool m_use_objc;
+ lldb::DynamicValueType m_use_dynamic;
+ bool m_use_synthetic;
+ bool m_scope_already_checked;
+ bool m_flat_output;
+ uint32_t m_omit_summary_depth;
+ bool m_ignore_cap;
+ lldb::Format m_format;
+ lldb::TypeSummaryImplSP m_summary_sp;
+ std::string m_root_valobj_name;
+ bool m_hide_root_type;
+ bool m_hide_name;
+ bool m_hide_value;
+
+ DumpValueObjectOptions() :
+ m_max_ptr_depth(0),
+ m_max_depth(UINT32_MAX),
+ m_show_types(false),
+ m_show_location(false),
+ m_use_objc(false),
+ m_use_dynamic(lldb::eNoDynamicValues),
+ m_use_synthetic(true),
+ m_scope_already_checked(false),
+ m_flat_output(false),
+ m_omit_summary_depth(0),
+ m_ignore_cap(false),
+ m_format (lldb::eFormatDefault),
+ m_summary_sp(),
+ m_root_valobj_name(),
+ m_hide_root_type(false), // provide a special compact display for "po"
+ m_hide_name(false), // provide a special compact display for "po"
+ m_hide_value(false) // provide a special compact display for "po"
+ {}
+
+ static const DumpValueObjectOptions
+ DefaultOptions()
+ {
+ static DumpValueObjectOptions g_default_options;
+
+ return g_default_options;
+ }
+
+ DumpValueObjectOptions (const DumpValueObjectOptions& rhs) :
+ m_max_ptr_depth(rhs.m_max_ptr_depth),
+ m_max_depth(rhs.m_max_depth),
+ m_show_types(rhs.m_show_types),
+ m_show_location(rhs.m_show_location),
+ m_use_objc(rhs.m_use_objc),
+ m_use_dynamic(rhs.m_use_dynamic),
+ m_use_synthetic(rhs.m_use_synthetic),
+ m_scope_already_checked(rhs.m_scope_already_checked),
+ m_flat_output(rhs.m_flat_output),
+ m_omit_summary_depth(rhs.m_omit_summary_depth),
+ m_ignore_cap(rhs.m_ignore_cap),
+ m_format(rhs.m_format),
+ m_summary_sp(rhs.m_summary_sp),
+ m_root_valobj_name(rhs.m_root_valobj_name),
+ m_hide_root_type(rhs.m_hide_root_type),
+ m_hide_name(rhs.m_hide_name),
+ m_hide_value(rhs.m_hide_value)
+ {}
+
+ DumpValueObjectOptions&
+ SetMaximumPointerDepth(uint32_t depth = 0)
+ {
+ m_max_ptr_depth = depth;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetMaximumDepth(uint32_t depth = 0)
+ {
+ m_max_depth = depth;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetShowTypes(bool show = false)
+ {
+ m_show_types = show;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetShowLocation(bool show = false)
+ {
+ m_show_location = show;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetUseObjectiveC(bool use = false)
+ {
+ m_use_objc = use;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetShowSummary(bool show = true)
+ {
+ if (show == false)
+ SetOmitSummaryDepth(UINT32_MAX);
+ else
+ SetOmitSummaryDepth(0);
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetUseDynamicType(lldb::DynamicValueType dyn = lldb::eNoDynamicValues)
+ {
+ m_use_dynamic = dyn;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetUseSyntheticValue(bool use_synthetic = true)
+ {
+ m_use_synthetic = use_synthetic;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetScopeChecked(bool check = true)
+ {
+ m_scope_already_checked = check;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetFlatOutput(bool flat = false)
+ {
+ m_flat_output = flat;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetOmitSummaryDepth(uint32_t depth = 0)
+ {
+ m_omit_summary_depth = depth;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetIgnoreCap(bool ignore = false)
+ {
+ m_ignore_cap = ignore;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetRawDisplay(bool raw = false)
+ {
+ if (raw)
+ {
+ SetUseSyntheticValue(false);
+ SetOmitSummaryDepth(UINT32_MAX);
+ SetIgnoreCap(true);
+ SetHideName(false);
+ SetHideValue(false);
+ }
+ else
+ {
+ SetUseSyntheticValue(true);
+ SetOmitSummaryDepth(0);
+ SetIgnoreCap(false);
+ SetHideName(false);
+ SetHideValue(false);
+ }
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetFormat (lldb::Format format = lldb::eFormatDefault)
+ {
+ m_format = format;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetSummary (lldb::TypeSummaryImplSP summary = lldb::TypeSummaryImplSP())
+ {
+ m_summary_sp = summary;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetRootValueObjectName (const char* name = NULL)
+ {
+ if (name)
+ m_root_valobj_name.assign(name);
+ else
+ m_root_valobj_name.clear();
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetHideRootType (bool hide_root_type = false)
+ {
+ m_hide_root_type = hide_root_type;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetHideName (bool hide_name = false)
+ {
+ m_hide_name = hide_name;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetHideValue (bool hide_value = false)
+ {
+ m_hide_value = hide_value;
+ return *this;
+ }
+ };
+
+ class EvaluationPoint
+ {
+ public:
+
+ EvaluationPoint ();
+
+ EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected = false);
+
+ EvaluationPoint (const EvaluationPoint &rhs);
+
+ ~EvaluationPoint ();
+
+ const ExecutionContextRef &
+ GetExecutionContextRef() const
+ {
+ return m_exe_ctx_ref;
+ }
+
+ // Set the EvaluationPoint to the values in exe_scope,
+ // Return true if the Evaluation Point changed.
+ // Since the ExecutionContextScope is always going to be valid currently,
+ // the Updated Context will also always be valid.
+
+// bool
+// SetContext (ExecutionContextScope *exe_scope);
+
+ void
+ SetIsConstant ()
+ {
+ SetUpdated();
+ m_mod_id.SetInvalid();
+ }
+
+ bool
+ IsConstant () const
+ {
+ return !m_mod_id.IsValid();
+ }
+
+ ProcessModID
+ GetModID () const
+ {
+ return m_mod_id;
+ }
+
+ void
+ SetUpdateID (ProcessModID new_id)
+ {
+ m_mod_id = new_id;
+ }
+
+ bool
+ IsFirstEvaluation () const
+ {
+ return m_first_update;
+ }
+
+ void
+ SetNeedsUpdate ()
+ {
+ m_needs_update = true;
+ }
+
+ void
+ SetUpdated ();
+
+ bool
+ NeedsUpdating()
+ {
+ SyncWithProcessState();
+ return m_needs_update;
+ }
+
+ bool
+ IsValid ()
+ {
+ if (!m_mod_id.IsValid())
+ return false;
+ else if (SyncWithProcessState ())
+ {
+ if (!m_mod_id.IsValid())
+ return false;
+ }
+ return true;
+ }
+
+ void
+ SetInvalid ()
+ {
+ // Use the stop id to mark us as invalid, leave the thread id and the stack id around for logging and
+ // history purposes.
+ m_mod_id.SetInvalid();
+
+ // Can't update an invalid state.
+ m_needs_update = false;
+
+ }
+
+ private:
+ bool
+ SyncWithProcessState ();
+
+ ProcessModID m_mod_id; // This is the stop id when this ValueObject was last evaluated.
+ ExecutionContextRef m_exe_ctx_ref;
+ bool m_needs_update;
+ bool m_first_update;
+ };
+
+ const EvaluationPoint &
+ GetUpdatePoint () const
+ {
+ return m_update_point;
+ }
+
+ EvaluationPoint &
+ GetUpdatePoint ()
+ {
+ return m_update_point;
+ }
+
+ const ExecutionContextRef &
+ GetExecutionContextRef() const
+ {
+ return m_update_point.GetExecutionContextRef();
+ }
+
+ lldb::TargetSP
+ GetTargetSP() const
+ {
+ return m_update_point.GetExecutionContextRef().GetTargetSP();
+ }
+
+ lldb::ProcessSP
+ GetProcessSP() const
+ {
+ return m_update_point.GetExecutionContextRef().GetProcessSP();
+ }
+
+ lldb::ThreadSP
+ GetThreadSP() const
+ {
+ return m_update_point.GetExecutionContextRef().GetThreadSP();
+ }
+
+ lldb::StackFrameSP
+ GetFrameSP() const
+ {
+ return m_update_point.GetExecutionContextRef().GetFrameSP();
+ }
+
+ void
+ SetNeedsUpdate ();
+
+ virtual ~ValueObject();
+
+ ClangASTType
+ GetClangType ();
+
+ //------------------------------------------------------------------
+ // Sublasses must implement the functions below.
+ //------------------------------------------------------------------
+ virtual uint64_t
+ GetByteSize() = 0;
+
+ virtual lldb::ValueType
+ GetValueType() const = 0;
+
+ //------------------------------------------------------------------
+ // Sublasses can implement the functions below.
+ //------------------------------------------------------------------
+ virtual ConstString
+ GetTypeName();
+
+ virtual ConstString
+ GetQualifiedTypeName();
+
+ virtual lldb::LanguageType
+ GetObjectRuntimeLanguage();
+
+ virtual uint32_t
+ GetTypeInfo (ClangASTType *pointee_or_element_clang_type = NULL);
+
+ virtual bool
+ IsPointerType ();
+
+ virtual bool
+ IsArrayType ();
+
+ virtual bool
+ IsScalarType ();
+
+ virtual bool
+ IsPointerOrReferenceType ();
+
+ virtual bool
+ IsPossibleDynamicType ();
+
+ virtual bool
+ IsObjCNil ();
+
+ virtual bool
+ IsBaseClass ()
+ {
+ return false;
+ }
+
+ virtual bool
+ IsDereferenceOfParent ()
+ {
+ return false;
+ }
+
+ bool
+ IsIntegerType (bool &is_signed);
+
+ virtual bool
+ GetBaseClassPath (Stream &s);
+
+ virtual void
+ GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat = eGetExpressionPathFormatDereferencePointers);
+
+ lldb::ValueObjectSP
+ GetValueForExpressionPath(const char* expression,
+ const char** first_unparsed = NULL,
+ ExpressionPathScanEndReason* reason_to_stop = NULL,
+ ExpressionPathEndResultType* final_value_type = NULL,
+ const GetValueForExpressionPathOptions& options = GetValueForExpressionPathOptions::DefaultOptions(),
+ ExpressionPathAftermath* final_task_on_target = NULL);
+
+ int
+ GetValuesForExpressionPath(const char* expression,
+ lldb::ValueObjectListSP& list,
+ const char** first_unparsed = NULL,
+ ExpressionPathScanEndReason* reason_to_stop = NULL,
+ ExpressionPathEndResultType* final_value_type = NULL,
+ const GetValueForExpressionPathOptions& options = GetValueForExpressionPathOptions::DefaultOptions(),
+ ExpressionPathAftermath* final_task_on_target = NULL);
+
+ virtual bool
+ IsInScope ()
+ {
+ return true;
+ }
+
+ virtual off_t
+ GetByteOffset()
+ {
+ return 0;
+ }
+
+ virtual uint32_t
+ GetBitfieldBitSize ()
+ {
+ return 0;
+ }
+
+ virtual uint32_t
+ GetBitfieldBitOffset ()
+ {
+ return 0;
+ }
+
+ bool
+ IsBitfield ()
+ {
+ return (GetBitfieldBitSize() != 0) || (GetBitfieldBitOffset() != 0);
+ }
+
+ virtual bool
+ IsArrayItemForPointer()
+ {
+ return m_is_array_item_for_pointer;
+ }
+
+ virtual const char *
+ GetValueAsCString ();
+
+ virtual bool
+ GetValueAsCString (lldb::Format format,
+ std::string& destination);
+
+ virtual uint64_t
+ GetValueAsUnsigned (uint64_t fail_value, bool *success = NULL);
+
+ virtual bool
+ SetValueFromCString (const char *value_str, Error& error);
+
+ // Return the module associated with this value object in case the
+ // value is from an executable file and might have its data in
+ // sections of the file. This can be used for variables.
+ virtual lldb::ModuleSP
+ GetModule();
+
+ virtual ValueObject*
+ GetRoot ();
+
+ virtual bool
+ GetDeclaration (Declaration &decl);
+
+ //------------------------------------------------------------------
+ // The functions below should NOT be modified by sublasses
+ //------------------------------------------------------------------
+ const Error &
+ GetError();
+
+ const ConstString &
+ GetName() const;
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx, bool can_create);
+
+ // this will always create the children if necessary
+ lldb::ValueObjectSP
+ GetChildAtIndexPath (const std::initializer_list<size_t> &idxs,
+ size_t* index_of_error = NULL);
+
+ lldb::ValueObjectSP
+ GetChildAtIndexPath (const std::vector<size_t> &idxs,
+ size_t* index_of_error = NULL);
+
+ lldb::ValueObjectSP
+ GetChildAtIndexPath (const std::initializer_list< std::pair<size_t, bool> > &idxs,
+ size_t* index_of_error = NULL);
+
+ lldb::ValueObjectSP
+ GetChildAtIndexPath (const std::vector< std::pair<size_t, bool> > &idxs,
+ size_t* index_of_error = NULL);
+
+ virtual lldb::ValueObjectSP
+ GetChildMemberWithName (const ConstString &name, bool can_create);
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ size_t
+ GetNumChildren ();
+
+ const Value &
+ GetValue() const;
+
+ Value &
+ GetValue();
+
+ virtual bool
+ ResolveValue (Scalar &scalar);
+
+ virtual const char *
+ GetLocationAsCString ();
+
+ const char *
+ GetSummaryAsCString ();
+
+ bool
+ GetSummaryAsCString (TypeSummaryImpl* summary_ptr,
+ std::string& destination);
+
+ const char *
+ GetObjectDescription ();
+
+ bool
+ HasSpecialPrintableRepresentation (ValueObjectRepresentationStyle val_obj_display,
+ lldb::Format custom_format);
+
+ enum PrintableRepresentationSpecialCases
+ {
+ ePrintableRepresentationSpecialCasesDisable = 0,
+ ePrintableRepresentationSpecialCasesAllow = 1,
+ ePrintableRepresentationSpecialCasesOnly = 3
+ };
+
+ bool
+ DumpPrintableRepresentation (Stream& s,
+ ValueObjectRepresentationStyle val_obj_display = eValueObjectRepresentationStyleSummary,
+ lldb::Format custom_format = lldb::eFormatInvalid,
+ PrintableRepresentationSpecialCases special = ePrintableRepresentationSpecialCasesAllow);
+ bool
+ GetValueIsValid () const;
+
+ bool
+ GetValueDidChange ();
+
+ bool
+ UpdateValueIfNeeded (bool update_format = true);
+
+ bool
+ UpdateFormatsIfNeeded();
+
+ lldb::ValueObjectSP
+ GetSP ()
+ {
+ return m_manager->GetSharedPointer(this);
+ }
+
+ void
+ SetName (const ConstString &name);
+
+ virtual lldb::addr_t
+ GetAddressOf (bool scalar_is_load_address = true,
+ AddressType *address_type = NULL);
+
+ lldb::addr_t
+ GetPointerValue (AddressType *address_type = NULL);
+
+ lldb::ValueObjectSP
+ GetSyntheticChild (const ConstString &key) const;
+
+ lldb::ValueObjectSP
+ GetSyntheticArrayMember (size_t index, bool can_create);
+
+ lldb::ValueObjectSP
+ GetSyntheticArrayMemberFromPointer (size_t index, bool can_create);
+
+ lldb::ValueObjectSP
+ GetSyntheticArrayMemberFromArray (size_t index, bool can_create);
+
+ lldb::ValueObjectSP
+ GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create);
+
+ lldb::ValueObjectSP
+ GetSyntheticExpressionPathChild(const char* expression, bool can_create);
+
+ virtual lldb::ValueObjectSP
+ GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create);
+
+ virtual lldb::ValueObjectSP
+ GetDynamicValue (lldb::DynamicValueType valueType);
+
+ lldb::DynamicValueType
+ GetDynamicValueType ();
+
+ virtual lldb::ValueObjectSP
+ GetStaticValue ();
+
+ virtual lldb::ValueObjectSP
+ GetNonSyntheticValue ();
+
+ lldb::ValueObjectSP
+ GetSyntheticValue (bool use_synthetic = true);
+
+ virtual bool
+ HasSyntheticValue();
+
+ virtual bool
+ IsSynthetic() { return false; }
+
+ virtual lldb::ValueObjectSP
+ CreateConstantValue (const ConstString &name);
+
+ virtual lldb::ValueObjectSP
+ Dereference (Error &error);
+
+ virtual lldb::ValueObjectSP
+ AddressOf (Error &error);
+
+ virtual lldb::addr_t
+ GetLiveAddress()
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ virtual void
+ SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
+ AddressType address_type = eAddressTypeLoad)
+ {
+ }
+
+ virtual lldb::ValueObjectSP
+ Cast (const ClangASTType &clang_ast_type);
+
+ virtual lldb::ValueObjectSP
+ CastPointerType (const char *name,
+ ClangASTType &ast_type);
+
+ virtual lldb::ValueObjectSP
+ CastPointerType (const char *name,
+ lldb::TypeSP &type_sp);
+
+ // The backing bits of this value object were updated, clear any
+ // descriptive string, so we know we have to refetch them
+ virtual void
+ ValueUpdated ()
+ {
+ ClearUserVisibleData(eClearUserVisibleDataItemsValue |
+ eClearUserVisibleDataItemsSummary |
+ eClearUserVisibleDataItemsDescription);
+ }
+
+ virtual bool
+ IsDynamic ()
+ {
+ return false;
+ }
+
+ virtual SymbolContextScope *
+ GetSymbolContextScope();
+
+ static void
+ DumpValueObject (Stream &s,
+ ValueObject *valobj);
+ static void
+ DumpValueObject (Stream &s,
+ ValueObject *valobj,
+ const DumpValueObjectOptions& options);
+
+ static lldb::ValueObjectSP
+ CreateValueObjectFromExpression (const char* name,
+ const char* expression,
+ const ExecutionContext& exe_ctx);
+
+ static lldb::ValueObjectSP
+ CreateValueObjectFromAddress (const char* name,
+ uint64_t address,
+ const ExecutionContext& exe_ctx,
+ ClangASTType type);
+
+ static lldb::ValueObjectSP
+ CreateValueObjectFromData (const char* name,
+ DataExtractor& data,
+ const ExecutionContext& exe_ctx,
+ ClangASTType type);
+
+ static void
+ LogValueObject (Log *log,
+ ValueObject *valobj);
+
+ static void
+ LogValueObject (Log *log,
+ ValueObject *valobj,
+ const DumpValueObjectOptions& options);
+
+
+ // returns true if this is a char* or a char[]
+ // if it is a char* and check_pointer is true,
+ // it also checks that the pointer is valid
+ bool
+ IsCStringContainer (bool check_pointer = false);
+
+ size_t
+ ReadPointedString (Stream& s,
+ Error& error,
+ uint32_t max_length = 0,
+ bool honor_array = true,
+ lldb::Format item_format = lldb::eFormatCharArray);
+
+ virtual size_t
+ GetPointeeData (DataExtractor& data,
+ uint32_t item_idx = 0,
+ uint32_t item_count = 1);
+
+ virtual uint64_t
+ GetData (DataExtractor& data);
+
+ virtual bool
+ SetData (DataExtractor &data, Error &error);
+
+ bool
+ GetIsConstant () const
+ {
+ return m_update_point.IsConstant();
+ }
+
+ void
+ SetIsConstant ()
+ {
+ m_update_point.SetIsConstant();
+ }
+
+ lldb::Format
+ GetFormat () const;
+
+ void
+ SetFormat (lldb::Format format)
+ {
+ if (format != m_format)
+ ClearUserVisibleData(eClearUserVisibleDataItemsValue);
+ m_format = format;
+ }
+
+ lldb::TypeSummaryImplSP
+ GetSummaryFormat()
+ {
+ UpdateFormatsIfNeeded();
+ return m_type_summary_sp;
+ }
+
+ void
+ SetSummaryFormat(lldb::TypeSummaryImplSP format)
+ {
+ m_type_summary_sp = format;
+ ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
+ }
+
+ void
+ SetValueFormat(lldb::TypeFormatImplSP format)
+ {
+ m_type_format_sp = format;
+ ClearUserVisibleData(eClearUserVisibleDataItemsValue);
+ }
+
+ lldb::TypeFormatImplSP
+ GetValueFormat()
+ {
+ UpdateFormatsIfNeeded();
+ return m_type_format_sp;
+ }
+
+ void
+ SetSyntheticChildren(const lldb::SyntheticChildrenSP &synth_sp)
+ {
+ if (synth_sp.get() == m_synthetic_children_sp.get())
+ return;
+ ClearUserVisibleData(eClearUserVisibleDataItemsSyntheticChildren);
+ m_synthetic_children_sp = synth_sp;
+ }
+
+ lldb::SyntheticChildrenSP
+ GetSyntheticChildren()
+ {
+ UpdateFormatsIfNeeded();
+ return m_synthetic_children_sp;
+ }
+
+ // Use GetParent for display purposes, but if you want to tell the parent to update itself
+ // then use m_parent. The ValueObjectDynamicValue's parent is not the correct parent for
+ // displaying, they are really siblings, so for display it needs to route through to its grandparent.
+ virtual ValueObject *
+ GetParent()
+ {
+ return m_parent;
+ }
+
+ virtual const ValueObject *
+ GetParent() const
+ {
+ return m_parent;
+ }
+
+ ValueObject *
+ GetNonBaseClassParent();
+
+ void
+ SetAddressTypeOfChildren(AddressType at)
+ {
+ m_address_type_of_ptr_or_ref_children = at;
+ }
+
+ AddressType
+ GetAddressTypeOfChildren();
+
+ void
+ SetHasCompleteType()
+ {
+ m_did_calculate_complete_objc_class_type = true;
+ }
+
+ //------------------------------------------------------------------
+ /// Find out if a ValueObject might have children.
+ ///
+ /// This call is much more efficient than CalculateNumChildren() as
+ /// it doesn't need to complete the underlying type. This is designed
+ /// to be used in a UI environment in order to detect if the
+ /// disclosure triangle should be displayed or not.
+ ///
+ /// This function returns true for class, union, structure,
+ /// pointers, references, arrays and more. Again, it does so without
+ /// doing any expensive type completion.
+ ///
+ /// @return
+ /// Returns \b true if the ValueObject might have children, or \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ MightHaveChildren();
+
+protected:
+ typedef ClusterManager<ValueObject> ValueObjectManager;
+
+ class ChildrenManager
+ {
+ public:
+ ChildrenManager() :
+ m_mutex(Mutex::eMutexTypeRecursive),
+ m_children(),
+ m_children_count(0)
+ {}
+
+ bool
+ HasChildAtIndex (size_t idx)
+ {
+ Mutex::Locker locker(m_mutex);
+ ChildrenIterator iter = m_children.find(idx);
+ ChildrenIterator end = m_children.end();
+ return (iter != end);
+ }
+
+ ValueObject*
+ GetChildAtIndex (size_t idx)
+ {
+ Mutex::Locker locker(m_mutex);
+ ChildrenIterator iter = m_children.find(idx);
+ ChildrenIterator end = m_children.end();
+ if (iter == end)
+ return NULL;
+ else
+ return iter->second;
+ }
+
+ void
+ SetChildAtIndex (size_t idx, ValueObject* valobj)
+ {
+ ChildrenPair pair(idx,valobj); // we do not need to be mutex-protected to make a pair
+ Mutex::Locker locker(m_mutex);
+ m_children.insert(pair);
+ }
+
+ void
+ SetChildrenCount (size_t count)
+ {
+ m_children_count = count;
+ }
+
+ size_t
+ GetChildrenCount ()
+ {
+ return m_children_count;
+ }
+
+ void
+ Clear()
+ {
+ m_children_count = 0;
+ Mutex::Locker locker(m_mutex);
+ m_children.clear();
+ }
+
+ private:
+ typedef std::map<size_t, ValueObject*> ChildrenMap;
+ typedef ChildrenMap::iterator ChildrenIterator;
+ typedef ChildrenMap::value_type ChildrenPair;
+ Mutex m_mutex;
+ ChildrenMap m_children;
+ size_t m_children_count;
+ };
+
+ //------------------------------------------------------------------
+ // Classes that inherit from ValueObject can see and modify these
+ //------------------------------------------------------------------
+ ValueObject * m_parent; // The parent value object, or NULL if this has no parent
+ ValueObject * m_root; // The root of the hierarchy for this ValueObject (or NULL if never calculated)
+ EvaluationPoint m_update_point; // Stores both the stop id and the full context at which this value was last
+ // updated. When we are asked to update the value object, we check whether
+ // the context & stop id are the same before updating.
+ ConstString m_name; // The name of this object
+ DataExtractor m_data; // A data extractor that can be used to extract the value.
+ Value m_value;
+ Error m_error; // An error object that can describe any errors that occur when updating values.
+ std::string m_value_str; // Cached value string that will get cleared if/when the value is updated.
+ std::string m_old_value_str;// Cached old value string from the last time the value was gotten
+ std::string m_location_str; // Cached location string that will get cleared if/when the value is updated.
+ std::string m_summary_str; // Cached summary string that will get cleared if/when the value is updated.
+ std::string m_object_desc_str; // Cached result of the "object printer". This differs from the summary
+ // in that the summary is consed up by us, the object_desc_string is builtin.
+
+ ClangASTType m_override_type;// If the type of the value object should be overridden, the type to impose.
+
+ ValueObjectManager *m_manager; // This object is managed by the root object (any ValueObject that gets created
+ // without a parent.) The manager gets passed through all the generations of
+ // dependent objects, and will keep the whole cluster of objects alive as long
+ // as a shared pointer to any of them has been handed out. Shared pointers to
+ // value objects must always be made with the GetSP method.
+
+ ChildrenManager m_children;
+ std::map<ConstString, ValueObject *> m_synthetic_children;
+
+ ValueObject* m_dynamic_value;
+ ValueObject* m_synthetic_value;
+ ValueObject* m_deref_valobj;
+
+ lldb::ValueObjectSP m_addr_of_valobj_sp; // We have to hold onto a shared pointer to this one because it is created
+ // as an independent ValueObjectConstResult, which isn't managed by us.
+
+ lldb::Format m_format;
+ lldb::Format m_last_format;
+ uint32_t m_last_format_mgr_revision;
+ lldb::TypeSummaryImplSP m_type_summary_sp;
+ lldb::TypeFormatImplSP m_type_format_sp;
+ lldb::SyntheticChildrenSP m_synthetic_children_sp;
+ ProcessModID m_user_id_of_forced_summary;
+ AddressType m_address_type_of_ptr_or_ref_children;
+
+ bool m_value_is_valid:1,
+ m_value_did_change:1,
+ m_children_count_valid:1,
+ m_old_value_valid:1,
+ m_is_deref_of_parent:1,
+ m_is_array_item_for_pointer:1,
+ m_is_bitfield_for_scalar:1,
+ m_is_child_at_offset:1,
+ m_is_getting_summary:1,
+ m_did_calculate_complete_objc_class_type:1;
+
+ friend class ClangExpressionDeclMap; // For GetValue
+ friend class ClangExpressionVariable; // For SetName
+ friend class Target; // For SetName
+ friend class ValueObjectConstResultImpl;
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+
+ // Use the no-argument constructor to make a constant variable object (with no ExecutionContextScope.)
+
+ ValueObject();
+
+ // Use this constructor to create a "root variable object". The ValueObject will be locked to this context
+ // through-out its lifespan.
+
+ ValueObject (ExecutionContextScope *exe_scope,
+ AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad);
+
+ // Use this constructor to create a ValueObject owned by another ValueObject. It will inherit the ExecutionContext
+ // of its parent.
+
+ ValueObject (ValueObject &parent);
+
+ ValueObjectManager *
+ GetManager()
+ {
+ return m_manager;
+ }
+
+ virtual bool
+ UpdateValue () = 0;
+
+ virtual void
+ CalculateDynamicValue (lldb::DynamicValueType use_dynamic);
+
+ virtual lldb::DynamicValueType
+ GetDynamicValueTypeImpl ()
+ {
+ return lldb::eNoDynamicValues;
+ }
+
+ virtual bool
+ HasDynamicValueTypeInfo ()
+ {
+ return false;
+ }
+
+ virtual void
+ CalculateSyntheticValue (bool use_synthetic = true);
+
+ // Should only be called by ValueObject::GetChildAtIndex()
+ // Returns a ValueObject managed by this ValueObject's manager.
+ virtual ValueObject *
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
+
+ // Should only be called by ValueObject::GetNumChildren()
+ virtual size_t
+ CalculateNumChildren() = 0;
+
+ void
+ SetNumChildren (size_t num_children);
+
+ void
+ SetValueDidChange (bool value_changed);
+
+ void
+ SetValueIsValid (bool valid);
+
+ void
+ ClearUserVisibleData(uint32_t items = ValueObject::eClearUserVisibleDataItemsAllStrings);
+
+ void
+ AddSyntheticChild (const ConstString &key,
+ ValueObject *valobj);
+
+ DataExtractor &
+ GetDataExtractor ();
+
+ void
+ ClearDynamicTypeInformation ();
+
+ //------------------------------------------------------------------
+ // Sublasses must implement the functions below.
+ //------------------------------------------------------------------
+
+ virtual ClangASTType
+ GetClangTypeImpl () = 0;
+
+ const char *
+ GetLocationAsCStringImpl (const Value& value,
+ const DataExtractor& data);
+
+private:
+ //------------------------------------------------------------------
+ // For ValueObject only
+ //------------------------------------------------------------------
+
+ virtual ClangASTType
+ MaybeCalculateCompleteType ();
+
+ lldb::ValueObjectSP
+ GetValueForExpressionPath_Impl(const char* expression_cstr,
+ const char** first_unparsed,
+ ExpressionPathScanEndReason* reason_to_stop,
+ ExpressionPathEndResultType* final_value_type,
+ const GetValueForExpressionPathOptions& options,
+ ExpressionPathAftermath* final_task_on_target);
+
+ // this method will ONLY expand [] expressions into a VOList and return
+ // the number of elements it added to the VOList
+ // it will NOT loop through expanding the follow-up of the expression_cstr
+ // for all objects in the list
+ int
+ ExpandArraySliceExpression(const char* expression_cstr,
+ const char** first_unparsed,
+ lldb::ValueObjectSP root,
+ lldb::ValueObjectListSP& list,
+ ExpressionPathScanEndReason* reason_to_stop,
+ ExpressionPathEndResultType* final_value_type,
+ const GetValueForExpressionPathOptions& options,
+ ExpressionPathAftermath* final_task_on_target);
+
+
+ DISALLOW_COPY_AND_ASSIGN (ValueObject);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObject_h_
diff --git a/include/lldb/Core/ValueObjectCast.h b/include/lldb/Core/ValueObjectCast.h
new file mode 100644
index 000000000000..1538d7a55639
--- /dev/null
+++ b/include/lldb/Core/ValueObjectCast.h
@@ -0,0 +1,87 @@
+//===-- ValueObjectDynamicValue.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectCast_h_
+#define liblldb_ValueObjectCast_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ValueObject.h"
+
+namespace lldb_private {
+
+//---------------------------------------------------------------------------------
+// A ValueObject that represents a given value represented as a different type.
+//---------------------------------------------------------------------------------
+class ValueObjectCast : public ValueObject
+{
+public:
+ static lldb::ValueObjectSP
+ Create (ValueObject &parent,
+ const ConstString &name,
+ const ClangASTType &cast_type);
+
+ virtual
+ ~ValueObjectCast();
+
+ virtual uint64_t
+ GetByteSize();
+
+ virtual size_t
+ CalculateNumChildren();
+
+ virtual lldb::ValueType
+ GetValueType() const;
+
+ virtual bool
+ IsInScope ();
+
+ virtual ValueObject *
+ GetParent()
+ {
+ if (m_parent)
+ return m_parent->GetParent();
+ else
+ return NULL;
+ }
+
+ virtual const ValueObject *
+ GetParent() const
+ {
+ if (m_parent)
+ return m_parent->GetParent();
+ else
+ return NULL;
+ }
+
+protected:
+ virtual bool
+ UpdateValue ();
+
+ virtual ClangASTType
+ GetClangTypeImpl ();
+
+ ClangASTType m_cast_type;
+
+private:
+ ValueObjectCast (ValueObject &parent,
+ const ConstString &name,
+ const ClangASTType &cast_type);
+
+ //------------------------------------------------------------------
+ // For ValueObject only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectCast);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectCast_h_
diff --git a/include/lldb/Core/ValueObjectChild.h b/include/lldb/Core/ValueObjectChild.h
new file mode 100644
index 000000000000..780529a4af11
--- /dev/null
+++ b/include/lldb/Core/ValueObjectChild.h
@@ -0,0 +1,122 @@
+//===-- ValueObjectChild.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectChild_h_
+#define liblldb_ValueObjectChild_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ValueObject.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A child of another ValueObject.
+//----------------------------------------------------------------------
+class ValueObjectChild : public ValueObject
+{
+public:
+ virtual ~ValueObjectChild();
+
+ virtual uint64_t
+ GetByteSize()
+ {
+ return m_byte_size;
+ }
+
+ virtual off_t
+ GetByteOffset()
+ {
+ return m_byte_offset;
+ }
+
+ virtual uint32_t
+ GetBitfieldBitSize()
+ {
+ return m_bitfield_bit_size;
+ }
+
+ virtual uint32_t
+ GetBitfieldBitOffset()
+ {
+ return m_bitfield_bit_offset;
+ }
+
+ virtual lldb::ValueType
+ GetValueType() const;
+
+ virtual size_t
+ CalculateNumChildren();
+
+ virtual ConstString
+ GetTypeName();
+
+ virtual ConstString
+ GetQualifiedTypeName();
+
+ virtual bool
+ IsInScope ();
+
+ virtual bool
+ IsBaseClass ()
+ {
+ return m_is_base_class;
+ }
+
+ virtual bool
+ IsDereferenceOfParent ()
+ {
+ return m_is_deref_of_parent;
+ }
+
+protected:
+ virtual bool
+ UpdateValue ();
+
+ virtual ClangASTType
+ GetClangTypeImpl ()
+ {
+ return m_clang_type;
+ }
+
+ ClangASTType m_clang_type;
+ ConstString m_type_name;
+ uint64_t m_byte_size;
+ int32_t m_byte_offset;
+ uint8_t m_bitfield_bit_size;
+ uint8_t m_bitfield_bit_offset;
+ bool m_is_base_class;
+ bool m_is_deref_of_parent;
+
+//
+// void
+// ReadValueFromMemory (ValueObject* parent, lldb::addr_t address);
+
+protected:
+ friend class ValueObject;
+ friend class ValueObjectConstResult;
+ ValueObjectChild (ValueObject &parent,
+ const ClangASTType &clang_type,
+ const ConstString &name,
+ uint64_t byte_size,
+ int32_t byte_offset,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset,
+ bool is_base_class,
+ bool is_deref_of_parent,
+ AddressType child_ptr_or_ref_addr_type);
+
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectChild);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectChild_h_
diff --git a/include/lldb/Core/ValueObjectConstResult.h b/include/lldb/Core/ValueObjectConstResult.h
new file mode 100644
index 000000000000..4964d0589a09
--- /dev/null
+++ b/include/lldb/Core/ValueObjectConstResult.h
@@ -0,0 +1,179 @@
+//===-- ValueObjectConstResult.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectConstResult_h_
+#define liblldb_ValueObjectConstResult_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ValueObject.h"
+
+#include "lldb/Core/ValueObjectConstResultImpl.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A frozen ValueObject copied into host memory
+//----------------------------------------------------------------------
+class ValueObjectConstResult : public ValueObject
+{
+public:
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope,
+ lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size,
+ lldb::addr_t address = LLDB_INVALID_ADDRESS);
+
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope,
+ const ClangASTType &clang_type,
+ const ConstString &name,
+ const DataExtractor &data,
+ lldb::addr_t address = LLDB_INVALID_ADDRESS);
+
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope,
+ const ClangASTType &clang_type,
+ const ConstString &name,
+ const lldb::DataBufferSP &result_data_sp,
+ lldb::ByteOrder byte_order,
+ uint32_t addr_size,
+ lldb::addr_t address = LLDB_INVALID_ADDRESS);
+
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope,
+ const ClangASTType &clang_type,
+ const ConstString &name,
+ lldb::addr_t address,
+ AddressType address_type,
+ uint32_t addr_byte_size);
+
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope,
+ Value &value,
+ const ConstString &name);
+
+ // When an expression fails to evaluate, we return an error
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope,
+ const Error& error);
+
+ virtual ~ValueObjectConstResult();
+
+ virtual uint64_t
+ GetByteSize();
+
+ virtual lldb::ValueType
+ GetValueType() const;
+
+ virtual size_t
+ CalculateNumChildren();
+
+ virtual ConstString
+ GetTypeName();
+
+ virtual bool
+ IsInScope ();
+
+ void
+ SetByteSize (size_t size);
+
+ virtual lldb::ValueObjectSP
+ Dereference (Error &error);
+
+ virtual ValueObject *
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
+
+ virtual lldb::ValueObjectSP
+ GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create);
+
+ virtual lldb::ValueObjectSP
+ AddressOf (Error &error);
+
+ virtual lldb::addr_t
+ GetAddressOf (bool scalar_is_load_address = true,
+ AddressType *address_type = NULL);
+
+ virtual size_t
+ GetPointeeData (DataExtractor& data,
+ uint32_t item_idx = 0,
+ uint32_t item_count = 1);
+
+ virtual lldb::addr_t
+ GetLiveAddress()
+ {
+ return m_impl.GetLiveAddress();
+ }
+
+ virtual void
+ SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
+ AddressType address_type = eAddressTypeLoad)
+ {
+ m_impl.SetLiveAddress(addr,
+ address_type);
+ }
+
+ virtual lldb::ValueObjectSP
+ GetDynamicValue (lldb::DynamicValueType valueType);
+
+protected:
+ virtual bool
+ UpdateValue ();
+
+ virtual ClangASTType
+ GetClangTypeImpl ();
+
+ ConstString m_type_name;
+ uint64_t m_byte_size;
+
+ ValueObjectConstResultImpl m_impl;
+
+private:
+ friend class ValueObjectConstResultImpl;
+ ValueObjectConstResult (ExecutionContextScope *exe_scope,
+ lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size,
+ lldb::addr_t address);
+
+ ValueObjectConstResult (ExecutionContextScope *exe_scope,
+ const ClangASTType &clang_type,
+ const ConstString &name,
+ const DataExtractor &data,
+ lldb::addr_t address);
+
+ ValueObjectConstResult (ExecutionContextScope *exe_scope,
+ const ClangASTType &clang_type,
+ const ConstString &name,
+ const lldb::DataBufferSP &result_data_sp,
+ lldb::ByteOrder byte_order,
+ uint32_t addr_size,
+ lldb::addr_t address);
+
+ ValueObjectConstResult (ExecutionContextScope *exe_scope,
+ const ClangASTType &clang_type,
+ const ConstString &name,
+ lldb::addr_t address,
+ AddressType address_type,
+ uint32_t addr_byte_size);
+
+ ValueObjectConstResult (ExecutionContextScope *exe_scope,
+ const Value &value,
+ const ConstString &name);
+
+ ValueObjectConstResult (ExecutionContextScope *exe_scope,
+ const Error& error);
+
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectConstResult);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectConstResult_h_
diff --git a/include/lldb/Core/ValueObjectConstResultChild.h b/include/lldb/Core/ValueObjectConstResultChild.h
new file mode 100644
index 000000000000..9063276b0198
--- /dev/null
+++ b/include/lldb/Core/ValueObjectConstResultChild.h
@@ -0,0 +1,77 @@
+//===-- ValueObjectConstResultChild.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectConstResultChild_h_
+#define liblldb_ValueObjectConstResultChild_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Core/ValueObjectConstResultImpl.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A child of a ValueObjectConstResult.
+//----------------------------------------------------------------------
+class ValueObjectConstResultChild : public ValueObjectChild
+{
+public:
+
+ ValueObjectConstResultChild (ValueObject &parent,
+ const ClangASTType &clang_type,
+ const ConstString &name,
+ uint32_t byte_size,
+ int32_t byte_offset,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset,
+ bool is_base_class,
+ bool is_deref_of_parent);
+
+ virtual ~ValueObjectConstResultChild();
+
+ virtual lldb::ValueObjectSP
+ Dereference (Error &error);
+
+ virtual ValueObject *
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
+
+ virtual ClangASTType
+ GetClangType ()
+ {
+ return ValueObjectChild::GetClangType();
+ }
+
+ virtual lldb::ValueObjectSP
+ GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create);
+
+ virtual lldb::ValueObjectSP
+ AddressOf (Error &error);
+
+ virtual size_t
+ GetPointeeData (DataExtractor& data,
+ uint32_t item_idx = 0,
+ uint32_t item_count = 1);
+
+protected:
+ ValueObjectConstResultImpl m_impl;
+
+private:
+ friend class ValueObject;
+ friend class ValueObjectConstResult;
+ friend class ValueObjectConstResultImpl;
+
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectConstResultChild);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectConstResultChild_h_
diff --git a/include/lldb/Core/ValueObjectConstResultImpl.h b/include/lldb/Core/ValueObjectConstResultImpl.h
new file mode 100644
index 000000000000..271b93823569
--- /dev/null
+++ b/include/lldb/Core/ValueObjectConstResultImpl.h
@@ -0,0 +1,96 @@
+//===-- ValueObjectConstResultImpl.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectConstResultImpl_h_
+#define liblldb_ValueObjectConstResultImpl_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ValueObject.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A class wrapping common implementation details for operations in
+// ValueObjectConstResult ( & Child ) that may need to jump from the host
+// memory space into the target's memory space
+//----------------------------------------------------------------------
+class ValueObjectConstResultImpl
+{
+public:
+
+ ValueObjectConstResultImpl (ValueObject* valobj,
+ lldb::addr_t live_address = LLDB_INVALID_ADDRESS);
+
+ virtual
+ ~ValueObjectConstResultImpl()
+ {
+ }
+
+ lldb::ValueObjectSP
+ Dereference (Error &error);
+
+ ValueObject *
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
+
+ lldb::ValueObjectSP
+ GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create);
+
+ lldb::ValueObjectSP
+ AddressOf (Error &error);
+
+ bool
+ NeedsDerefOnTarget()
+ {
+ m_impl_backend->UpdateValueIfNeeded(false);
+ return (m_impl_backend->GetValue().GetValueType() == Value::eValueTypeHostAddress);
+ }
+
+ lldb::addr_t
+ GetLiveAddress()
+ {
+ return m_live_address;
+ }
+
+ void
+ SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
+ AddressType address_type = eAddressTypeLoad)
+ {
+ m_live_address = addr;
+ m_live_address_type = address_type;
+ }
+
+ lldb::ValueObjectSP
+ DerefOnTarget();
+
+ virtual lldb::addr_t
+ GetAddressOf (bool scalar_is_load_address = true,
+ AddressType *address_type = NULL);
+
+ virtual size_t
+ GetPointeeData (DataExtractor& data,
+ uint32_t item_idx = 0,
+ uint32_t item_count = 1);
+
+private:
+
+ ValueObject *m_impl_backend;
+ lldb::addr_t m_live_address;
+ AddressType m_live_address_type;
+ lldb::ValueObjectSP m_load_addr_backend;
+ lldb::ValueObjectSP m_address_of_backend;
+
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectConstResultImpl);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectConstResultImpl_h_
diff --git a/include/lldb/Core/ValueObjectDynamicValue.h b/include/lldb/Core/ValueObjectDynamicValue.h
new file mode 100644
index 000000000000..c0f6baade3fb
--- /dev/null
+++ b/include/lldb/Core/ValueObjectDynamicValue.h
@@ -0,0 +1,133 @@
+//===-- ValueObjectDynamicValue.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectDynamicValue_h_
+#define liblldb_ValueObjectDynamicValue_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/Type.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A ValueObject that represents memory at a given address, viewed as some
+// set lldb type.
+//----------------------------------------------------------------------
+class ValueObjectDynamicValue : public ValueObject
+{
+public:
+ virtual
+ ~ValueObjectDynamicValue();
+
+ virtual uint64_t
+ GetByteSize();
+
+ virtual ConstString
+ GetTypeName();
+
+ virtual ConstString
+ GetQualifiedTypeName();
+
+ virtual size_t
+ CalculateNumChildren();
+
+ virtual lldb::ValueType
+ GetValueType() const;
+
+ virtual bool
+ IsInScope ();
+
+ virtual bool
+ IsDynamic ()
+ {
+ return true;
+ }
+
+ virtual ValueObject *
+ GetParent()
+ {
+ if (m_parent)
+ return m_parent->GetParent();
+ else
+ return NULL;
+ }
+
+ virtual const ValueObject *
+ GetParent() const
+ {
+ if (m_parent)
+ return m_parent->GetParent();
+ else
+ return NULL;
+ }
+
+ virtual lldb::ValueObjectSP
+ GetStaticValue ()
+ {
+ return m_parent->GetSP();
+ }
+
+ void
+ SetOwningSP (lldb::ValueObjectSP &owning_sp)
+ {
+ if (m_owning_valobj_sp == owning_sp)
+ return;
+
+ assert (m_owning_valobj_sp.get() == NULL);
+ m_owning_valobj_sp = owning_sp;
+ }
+
+ virtual bool
+ SetValueFromCString (const char *value_str, Error& error);
+
+ virtual bool
+ SetData (DataExtractor &data, Error &error);
+
+protected:
+ virtual bool
+ UpdateValue ();
+
+ virtual lldb::DynamicValueType
+ GetDynamicValueTypeImpl ()
+ {
+ return m_use_dynamic;
+ }
+
+ virtual bool
+ HasDynamicValueTypeInfo ()
+ {
+ return true;
+ }
+
+ virtual ClangASTType
+ GetClangTypeImpl ();
+
+ Address m_address; ///< The variable that this value object is based upon
+ TypeAndOrName m_dynamic_type_info; // We can have a type_sp or just a name
+ lldb::ValueObjectSP m_owning_valobj_sp;
+ lldb::DynamicValueType m_use_dynamic;
+
+private:
+ friend class ValueObject;
+ friend class ValueObjectConstResult;
+ ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic);
+
+ //------------------------------------------------------------------
+ // For ValueObject only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectDynamicValue);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectDynamicValue_h_
diff --git a/include/lldb/Core/ValueObjectList.h b/include/lldb/Core/ValueObjectList.h
new file mode 100644
index 000000000000..5bfe40b2e952
--- /dev/null
+++ b/include/lldb/Core/ValueObjectList.h
@@ -0,0 +1,90 @@
+//===-- ValueObjectList.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectList_h_
+#define liblldb_ValueObjectList_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Target/ExecutionContextScope.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A collection of ValueObject values that
+//----------------------------------------------------------------------
+class ValueObjectList
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ValueObjectList ();
+
+ ValueObjectList (const ValueObjectList &rhs);
+
+ ~ValueObjectList();
+
+ const ValueObjectList &
+ operator = (const ValueObjectList &rhs);
+
+ void
+ Append (const lldb::ValueObjectSP &val_obj_sp);
+
+ void
+ Append (const ValueObjectList &valobj_list);
+
+ lldb::ValueObjectSP
+ FindValueObjectByPointer (ValueObject *valobj);
+
+ size_t
+ GetSize () const;
+
+ void
+ Resize (size_t size);
+
+ lldb::ValueObjectSP
+ GetValueObjectAtIndex (size_t idx);
+
+ lldb::ValueObjectSP
+ RemoveValueObjectAtIndex (size_t idx);
+
+ void
+ SetValueObjectAtIndex (size_t idx,
+ const lldb::ValueObjectSP &valobj_sp);
+
+ lldb::ValueObjectSP
+ FindValueObjectByValueName (const char *name);
+
+ lldb::ValueObjectSP
+ FindValueObjectByUID (lldb::user_id_t uid);
+
+ void
+ Swap (ValueObjectList &value_object_list);
+
+protected:
+ typedef std::vector<lldb::ValueObjectSP> collection;
+ //------------------------------------------------------------------
+ // Classes that inherit from ValueObjectList can see and modify these
+ //------------------------------------------------------------------
+ collection m_value_objects;
+
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectList_h_
diff --git a/include/lldb/Core/ValueObjectMemory.h b/include/lldb/Core/ValueObjectMemory.h
new file mode 100644
index 000000000000..627d73eb4b27
--- /dev/null
+++ b/include/lldb/Core/ValueObjectMemory.h
@@ -0,0 +1,91 @@
+//===-- ValueObjectMemory.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectMemory_h_
+#define liblldb_ValueObjectMemory_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/ClangASTType.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A ValueObject that represents memory at a given address, viewed as some
+// set lldb type.
+//----------------------------------------------------------------------
+class ValueObjectMemory : public ValueObject
+{
+public:
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope,
+ const char *name,
+ const Address &address,
+ lldb::TypeSP &type_sp);
+
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope,
+ const char *name,
+ const Address &address,
+ const ClangASTType &ast_type);
+
+ virtual
+ ~ValueObjectMemory();
+
+ virtual uint64_t
+ GetByteSize();
+
+ virtual ConstString
+ GetTypeName();
+
+ virtual size_t
+ CalculateNumChildren();
+
+ virtual lldb::ValueType
+ GetValueType() const;
+
+ virtual bool
+ IsInScope ();
+
+ virtual lldb::ModuleSP
+ GetModule();
+
+protected:
+ virtual bool
+ UpdateValue ();
+
+ virtual ClangASTType
+ GetClangTypeImpl ();
+
+ Address m_address; ///< The variable that this value object is based upon
+ lldb::TypeSP m_type_sp;
+ ClangASTType m_clang_type;
+
+private:
+ ValueObjectMemory (ExecutionContextScope *exe_scope,
+ const char *name,
+ const Address &address,
+ lldb::TypeSP &type_sp);
+
+ ValueObjectMemory (ExecutionContextScope *exe_scope,
+ const char *name,
+ const Address &address,
+ const ClangASTType &ast_type);
+ //------------------------------------------------------------------
+ // For ValueObject only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectMemory);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectMemory_h_
diff --git a/include/lldb/Core/ValueObjectRegister.h b/include/lldb/Core/ValueObjectRegister.h
new file mode 100644
index 000000000000..6820629f08e1
--- /dev/null
+++ b/include/lldb/Core/ValueObjectRegister.h
@@ -0,0 +1,195 @@
+//===-- ValueObjectRegister.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectRegister_h_
+#define liblldb_ValueObjectRegister_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/ValueObject.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A ValueObject that contains a root variable that may or may not
+// have children.
+//----------------------------------------------------------------------
+class ValueObjectRegisterContext : public ValueObject
+{
+public:
+
+ virtual
+ ~ValueObjectRegisterContext();
+
+ virtual uint64_t
+ GetByteSize();
+
+ virtual lldb::ValueType
+ GetValueType () const
+ {
+ return lldb::eValueTypeRegisterSet;
+ }
+
+ virtual ConstString
+ GetTypeName();
+
+ virtual ConstString
+ GetQualifiedTypeName();
+
+ virtual size_t
+ CalculateNumChildren();
+
+ virtual ValueObject *
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
+
+protected:
+ virtual bool
+ UpdateValue ();
+
+ virtual ClangASTType
+ GetClangTypeImpl ();
+
+ lldb::RegisterContextSP m_reg_ctx_sp;
+
+private:
+ ValueObjectRegisterContext (ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp);
+ //------------------------------------------------------------------
+ // For ValueObject only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectRegisterContext);
+};
+
+class ValueObjectRegisterSet : public ValueObject
+{
+public:
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx);
+
+ virtual
+ ~ValueObjectRegisterSet();
+
+ virtual uint64_t
+ GetByteSize();
+
+ virtual lldb::ValueType
+ GetValueType () const
+ {
+ return lldb::eValueTypeRegisterSet;
+ }
+
+ virtual ConstString
+ GetTypeName();
+
+ virtual ConstString
+ GetQualifiedTypeName();
+
+ virtual size_t
+ CalculateNumChildren();
+
+ virtual ValueObject *
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
+
+ virtual lldb::ValueObjectSP
+ GetChildMemberWithName (const ConstString &name, bool can_create);
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+
+protected:
+ virtual bool
+ UpdateValue ();
+
+ virtual ClangASTType
+ GetClangTypeImpl ();
+
+ lldb::RegisterContextSP m_reg_ctx_sp;
+ const RegisterSet *m_reg_set;
+ uint32_t m_reg_set_idx;
+
+private:
+ friend class ValueObjectRegisterContext;
+ ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx);
+
+ //------------------------------------------------------------------
+ // For ValueObject only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectRegisterSet);
+};
+
+class ValueObjectRegister : public ValueObject
+{
+public:
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num);
+
+ virtual
+ ~ValueObjectRegister();
+
+ virtual uint64_t
+ GetByteSize();
+
+ virtual lldb::ValueType
+ GetValueType () const
+ {
+ return lldb::eValueTypeRegister;
+ }
+
+ virtual ConstString
+ GetTypeName();
+
+ virtual size_t
+ CalculateNumChildren();
+
+ virtual bool
+ SetValueFromCString (const char *value_str, Error& error);
+
+ virtual bool
+ SetData (DataExtractor &data, Error &error);
+
+ virtual bool
+ ResolveValue (Scalar &scalar);
+
+ virtual void
+ GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat = eGetExpressionPathFormatDereferencePointers);
+
+protected:
+ virtual bool
+ UpdateValue ();
+
+ virtual ClangASTType
+ GetClangTypeImpl ();
+
+ lldb::RegisterContextSP m_reg_ctx_sp;
+ RegisterInfo m_reg_info;
+ RegisterValue m_reg_value;
+ ConstString m_type_name;
+ ClangASTType m_clang_type;
+
+private:
+ void
+ ConstructObject (uint32_t reg_num);
+
+ friend class ValueObjectRegisterSet;
+ ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num);
+ ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num);
+
+ //------------------------------------------------------------------
+ // For ValueObject only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectRegister);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectRegister_h_
diff --git a/include/lldb/Core/ValueObjectSyntheticFilter.h b/include/lldb/Core/ValueObjectSyntheticFilter.h
new file mode 100644
index 000000000000..f1d8c885c255
--- /dev/null
+++ b/include/lldb/Core/ValueObjectSyntheticFilter.h
@@ -0,0 +1,182 @@
+//===-- ValueObjectSyntheticFilter.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectSyntheticFilter_h_
+#define liblldb_ValueObjectSyntheticFilter_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ValueObject.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A ValueObject that obtains its children from some source other than
+// real information
+// This is currently used to implement Python-based children and filters
+// but you can bind it to any source of synthetic information and have
+// it behave accordingly
+//----------------------------------------------------------------------
+class ValueObjectSynthetic : public ValueObject
+{
+public:
+ virtual
+ ~ValueObjectSynthetic();
+
+ virtual uint64_t
+ GetByteSize();
+
+ virtual ConstString
+ GetTypeName();
+
+ virtual ConstString
+ GetQualifiedTypeName();
+
+ virtual bool
+ MightHaveChildren();
+
+ virtual size_t
+ CalculateNumChildren();
+
+ virtual lldb::ValueType
+ GetValueType() const;
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx, bool can_create);
+
+ virtual lldb::ValueObjectSP
+ GetChildMemberWithName (const ConstString &name, bool can_create);
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual lldb::ValueObjectSP
+ GetDynamicValue (lldb::DynamicValueType valueType);
+
+ virtual bool
+ IsInScope ();
+
+ virtual bool
+ HasSyntheticValue()
+ {
+ return false;
+ }
+
+ virtual bool
+ IsSynthetic() { return true; }
+
+ virtual void
+ CalculateSyntheticValue (bool use_synthetic)
+ {
+ }
+
+ virtual bool
+ IsDynamic ()
+ {
+ if (m_parent)
+ return m_parent->IsDynamic();
+ else
+ return false;
+ }
+
+ virtual lldb::ValueObjectSP
+ GetStaticValue ()
+ {
+ if (m_parent)
+ return m_parent->GetStaticValue();
+ else
+ return GetSP();
+ }
+
+ virtual lldb::DynamicValueType
+ GetDynamicValueType ()
+ {
+ if (m_parent)
+ return m_parent->GetDynamicValueType();
+ else
+ return lldb::eNoDynamicValues;
+ }
+
+ virtual ValueObject *
+ GetParent()
+ {
+ if (m_parent)
+ return m_parent->GetParent();
+ else
+ return NULL;
+ }
+
+ virtual const ValueObject *
+ GetParent() const
+ {
+ if (m_parent)
+ return m_parent->GetParent();
+ else
+ return NULL;
+ }
+
+ virtual lldb::ValueObjectSP
+ GetNonSyntheticValue ();
+
+ virtual bool
+ ResolveValue (Scalar &scalar)
+ {
+ if (m_parent)
+ return m_parent->ResolveValue(scalar);
+ return false;
+ }
+
+protected:
+ virtual bool
+ UpdateValue ();
+
+ virtual ClangASTType
+ GetClangTypeImpl ();
+
+ virtual void
+ CreateSynthFilter ();
+
+ // we need to hold on to the SyntheticChildren because someone might delete the type binding while we are alive
+ lldb::SyntheticChildrenSP m_synth_sp;
+ std::unique_ptr<SyntheticChildrenFrontEnd> m_synth_filter_ap;
+
+ typedef std::map<uint32_t, ValueObject*> ByIndexMap;
+ typedef std::map<const char*, uint32_t> NameToIndexMap;
+
+ typedef ByIndexMap::iterator ByIndexIterator;
+ typedef NameToIndexMap::iterator NameToIndexIterator;
+
+ ByIndexMap m_children_byindex;
+ NameToIndexMap m_name_toindex;
+ uint32_t m_synthetic_children_count; // FIXME use the ValueObject's ChildrenManager instead of a special purpose solution
+
+ ConstString m_parent_type_name;
+
+ LazyBool m_might_have_children;
+
+private:
+ friend class ValueObject;
+ ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter);
+
+ void
+ CopyParentData ();
+
+ //------------------------------------------------------------------
+ // For ValueObject only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectSynthetic);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectSyntheticFilter_h_
diff --git a/include/lldb/Core/ValueObjectVariable.h b/include/lldb/Core/ValueObjectVariable.h
new file mode 100644
index 000000000000..8a30b00f6bbd
--- /dev/null
+++ b/include/lldb/Core/ValueObjectVariable.h
@@ -0,0 +1,90 @@
+//===-- ValueObjectVariable.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ValueObjectVariable_h_
+#define liblldb_ValueObjectVariable_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ValueObject.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A ValueObject that contains a root variable that may or may not
+// have children.
+//----------------------------------------------------------------------
+class ValueObjectVariable : public ValueObject
+{
+public:
+ static lldb::ValueObjectSP
+ Create (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp);
+
+ virtual
+ ~ValueObjectVariable();
+
+ virtual uint64_t
+ GetByteSize();
+
+ virtual ConstString
+ GetTypeName();
+
+ virtual ConstString
+ GetQualifiedTypeName();
+
+ virtual size_t
+ CalculateNumChildren();
+
+ virtual lldb::ValueType
+ GetValueType() const;
+
+ virtual bool
+ IsInScope ();
+
+ virtual lldb::ModuleSP
+ GetModule();
+
+ virtual SymbolContextScope *
+ GetSymbolContextScope();
+
+ virtual bool
+ GetDeclaration (Declaration &decl);
+
+ virtual const char *
+ GetLocationAsCString ();
+
+ virtual bool
+ SetValueFromCString (const char *value_str, Error& error);
+
+ virtual bool
+ SetData (DataExtractor &data, Error &error);
+
+protected:
+ virtual bool
+ UpdateValue ();
+
+ virtual ClangASTType
+ GetClangTypeImpl ();
+
+ lldb::VariableSP m_variable_sp; ///< The variable that this value object is based upon
+ Value m_resolved_value; ///< The value that DWARFExpression resolves this variable to before we patch it up
+
+private:
+ ValueObjectVariable (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp);
+ //------------------------------------------------------------------
+ // For ValueObject only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (ValueObjectVariable);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectVariable_h_
diff --git a/include/lldb/Core/dwarf.h b/include/lldb/Core/dwarf.h
new file mode 100644
index 000000000000..bf77125d86a8
--- /dev/null
+++ b/include/lldb/Core/dwarf.h
@@ -0,0 +1,64 @@
+//===-- dwarf.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DebugBase_dwarf_h_
+#define DebugBase_dwarf_h_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+// Get the DWARF constant defintions from llvm
+#include "llvm/Support/Dwarf.h"
+// and stuff them in our default namespace
+using namespace llvm::dwarf;
+
+typedef uint32_t dw_uleb128_t;
+typedef int32_t dw_sleb128_t;
+typedef uint16_t dw_attr_t;
+typedef uint8_t dw_form_t;
+typedef uint16_t dw_tag_t;
+typedef uint64_t dw_addr_t; // Dwarf address define that must be big enough for any addresses in the compile units that get parsed
+
+#ifdef DWARFUTILS_DWARF64
+#define DWARF_REF_ADDR_SIZE 8
+typedef uint64_t dw_offset_t; // Dwarf Debug Information Entry offset for any offset into the file
+#else
+#define DWARF_REF_ADDR_SIZE 4
+typedef uint32_t dw_offset_t; // Dwarf Debug Information Entry offset for any offset into the file
+#endif
+
+/* Constants */
+#define DW_INVALID_OFFSET (~(dw_offset_t)0)
+#define DW_INVALID_INDEX 0xFFFFFFFFul
+
+// #define DW_ADDR_none 0x0
+
+#define DW_EH_PE_MASK_ENCODING 0x0F
+
+//// The following are used only internally within lldb - don't
+//// document them in the llvm Dwarf.h header file, we won't see
+//// them in executable files anywhere.
+//// These constants fit between DW_OP_lo_user (0xe0) and DW_OP_hi_user (0xff).
+//
+//#define DW_OP_APPLE_array_ref 0xEE // first pops index, then pops array; pushes array[index]
+//#define DW_OP_APPLE_extern 0xEF // ULEB128 index of external object (i.e., an entity from the program that was used in the expression)
+#define DW_OP_APPLE_uninit 0xF0 // This is actually generated by some apple compilers in locations lists
+//#define DW_OP_APPLE_assign 0xF1 // pops value off and assigns it to second item on stack (2nd item must have assignable context)
+//#define DW_OP_APPLE_address_of 0xF2 // gets the address of the top stack item (top item must be a variable, or have value_type that is an address already)
+//#define DW_OP_APPLE_value_of 0xF3 // pops the value off the stack and pushes the value of that object (top item must be a variable, or expression local)
+//#define DW_OP_APPLE_deref_type 0xF4 // gets the address of the top stack item (top item must be a variable, or a clang type)
+//#define DW_OP_APPLE_expr_local 0xF5 // ULEB128 expression local index
+//#define DW_OP_APPLE_constf 0xF6 // 1 byte float size, followed by constant float data
+//#define DW_OP_APPLE_scalar_cast 0xF7 // Cast top of stack to 2nd in stack's type leaving all items in place
+//#define DW_OP_APPLE_clang_cast 0xF8 // pointer size clang::Type * off the stack and cast top stack item to this type
+//#define DW_OP_APPLE_clear 0xFE // clears the entire expression stack, ok if the stack is empty
+//#define DW_OP_APPLE_error 0xFF // Stops expression evaluation and returns an error (no args)
+
+
+#endif // DebugBase_dwarf_h_
diff --git a/include/lldb/DataFormatters/CXXFormatterFunctions.h b/include/lldb/DataFormatters/CXXFormatterFunctions.h
new file mode 100644
index 000000000000..2f56c56810ab
--- /dev/null
+++ b/include/lldb/DataFormatters/CXXFormatterFunctions.h
@@ -0,0 +1,874 @@
+//===-- CXXFormatterFunctions.h------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CXXFormatterFunctions_h_
+#define liblldb_CXXFormatterFunctions_h_
+
+#include <stdint.h>
+#include <time.h>
+
+#include "lldb/lldb-forward.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/DataFormatters/FormatClasses.h"
+#include "lldb/Target/Target.h"
+
+#include "clang/AST/ASTContext.h"
+
+namespace lldb_private {
+ namespace formatters
+ {
+ bool
+ ExtractValueFromObjCExpression (ValueObject &valobj,
+ const char* target_type,
+ const char* selector,
+ uint64_t &value);
+
+ bool
+ ExtractSummaryFromObjCExpression (ValueObject &valobj,
+ const char* target_type,
+ const char* selector,
+ Stream &stream);
+
+ lldb::ValueObjectSP
+ CallSelectorOnObject (ValueObject &valobj,
+ const char* return_type,
+ const char* selector,
+ uint64_t index);
+
+ lldb::ValueObjectSP
+ CallSelectorOnObject (ValueObject &valobj,
+ const char* return_type,
+ const char* selector,
+ const char* key);
+
+ size_t
+ ExtractIndexFromString (const char* item_name);
+
+ time_t
+ GetOSXEpoch ();
+
+ bool
+ Char16StringSummaryProvider (ValueObject& valobj, Stream& stream); // char16_t* and unichar*
+
+ bool
+ Char32StringSummaryProvider (ValueObject& valobj, Stream& stream); // char32_t*
+
+ bool
+ WCharStringSummaryProvider (ValueObject& valobj, Stream& stream); // wchar_t*
+
+ bool
+ Char16SummaryProvider (ValueObject& valobj, Stream& stream); // char16_t and unichar
+
+ bool
+ Char32SummaryProvider (ValueObject& valobj, Stream& stream); // char32_t
+
+ bool
+ WCharSummaryProvider (ValueObject& valobj, Stream& stream); // wchar_t
+
+ bool
+ LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::string
+
+ bool
+ LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::wstring
+
+ bool
+ ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ SyntheticChildrenFrontEnd* ObjCClassSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ template<bool name_entries>
+ bool
+ NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSArraySummaryProvider (ValueObject& valobj, Stream& stream);
+
+ template<bool cf_style>
+ bool
+ NSSetSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ template<bool needs_at>
+ bool
+ NSDataSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSNumberSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ CFBagSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSDateSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSBundleSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSStringSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSURLSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ template <bool is_sel_ptr>
+ bool
+ ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ extern template bool
+ NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
+
+ extern template bool
+ NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
+
+ extern template bool
+ NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
+
+ extern template bool
+ NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
+
+ extern template bool
+ ObjCSELSummaryProvider<true> (ValueObject&, Stream&);
+
+ extern template bool
+ ObjCSELSummaryProvider<false> (ValueObject&, Stream&);
+
+ class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ struct DataDescriptor_32
+ {
+ uint32_t _used;
+ uint32_t _priv1 : 2 ;
+ uint32_t _size : 30;
+ uint32_t _priv2 : 2;
+ uint32_t offset : 30;
+ uint32_t _priv3;
+ uint32_t _data;
+ };
+ struct DataDescriptor_64
+ {
+ uint64_t _used;
+ uint64_t _priv1 : 2 ;
+ uint64_t _size : 62;
+ uint64_t _priv2 : 2;
+ uint64_t offset : 62;
+ uint32_t _priv3;
+ uint64_t _data;
+ };
+ public:
+ NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSArrayMSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ ClangASTType m_id_type;
+ std::vector<lldb::ValueObjectSP> m_children;
+ };
+
+ class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSArrayISyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ uint64_t m_items;
+ lldb::addr_t m_data_ptr;
+ ClangASTType m_id_type;
+ std::vector<lldb::ValueObjectSP> m_children;
+ };
+
+ class NSArrayCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSArrayCodeRunningSyntheticFrontEnd ();
+ };
+
+ SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class NSDictionaryISyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ struct DataDescriptor_32
+ {
+ uint32_t _used : 26;
+ uint32_t _szidx : 6;
+ };
+ struct DataDescriptor_64
+ {
+ uint64_t _used : 58;
+ uint32_t _szidx : 6;
+ };
+
+ struct DictionaryItemDescriptor
+ {
+ lldb::addr_t key_ptr;
+ lldb::addr_t val_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ public:
+ NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSDictionaryISyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_order;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ lldb::addr_t m_data_ptr;
+ ClangASTType m_pair_type;
+ std::vector<DictionaryItemDescriptor> m_children;
+ };
+
+ class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ struct DataDescriptor_32
+ {
+ uint32_t _used : 26;
+ uint32_t _kvo : 1;
+ uint32_t _size;
+ uint32_t _mutations;
+ uint32_t _objs_addr;
+ uint32_t _keys_addr;
+ };
+ struct DataDescriptor_64
+ {
+ uint64_t _used : 58;
+ uint32_t _kvo : 1;
+ uint64_t _size;
+ uint64_t _mutations;
+ uint64_t _objs_addr;
+ uint64_t _keys_addr;
+ };
+ struct DictionaryItemDescriptor
+ {
+ lldb::addr_t key_ptr;
+ lldb::addr_t val_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+ public:
+ NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSDictionaryMSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_order;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ ClangASTType m_pair_type;
+ std::vector<DictionaryItemDescriptor> m_children;
+ };
+
+ class NSDictionaryCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSDictionaryCodeRunningSyntheticFrontEnd ();
+ };
+
+ SyntheticChildrenFrontEnd* NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ struct DataDescriptor_32
+ {
+ uint32_t _used : 26;
+ uint32_t _szidx : 6;
+ };
+ struct DataDescriptor_64
+ {
+ uint64_t _used : 58;
+ uint32_t _szidx : 6;
+ };
+
+ struct SetItemDescriptor
+ {
+ lldb::addr_t item_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ public:
+ NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSSetISyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ lldb::addr_t m_data_ptr;
+ std::vector<SetItemDescriptor> m_children;
+ };
+
+ class NSOrderedSetSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+
+ public:
+ NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSOrderedSetSyntheticFrontEnd ();
+ private:
+ uint32_t m_count;
+ std::map<uint32_t,lldb::ValueObjectSP> m_children;
+ };
+
+ class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ struct DataDescriptor_32
+ {
+ uint32_t _used : 26;
+ uint32_t _size;
+ uint32_t _mutations;
+ uint32_t _objs_addr;
+ };
+ struct DataDescriptor_64
+ {
+ uint64_t _used : 58;
+ uint64_t _size;
+ uint64_t _mutations;
+ uint64_t _objs_addr;
+ };
+ struct SetItemDescriptor
+ {
+ lldb::addr_t item_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+ public:
+ NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSSetMSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ std::vector<SetItemDescriptor> m_children;
+ };
+
+ class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ NSSetCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSSetCodeRunningSyntheticFrontEnd ();
+ };
+
+ SyntheticChildrenFrontEnd* NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibcxxVectorBoolSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint64_t m_count;
+ lldb::addr_t m_base_data_address;
+ EvaluateExpressionOptions m_options;
+ };
+
+ SyntheticChildrenFrontEnd* LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ bool
+ LibcxxContainerSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ class LibstdcppVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibstdcppVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibstdcppVectorBoolSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint64_t m_count;
+ lldb::addr_t m_base_data_address;
+ EvaluateExpressionOptions m_options;
+ };
+
+ SyntheticChildrenFrontEnd* LibstdcppVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibstdcppMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibstdcppMapIteratorSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ lldb::addr_t m_pair_address;
+ ClangASTType m_pair_type;
+ EvaluateExpressionOptions m_options;
+ lldb::ValueObjectSP m_pair_sp;
+ };
+
+ SyntheticChildrenFrontEnd* LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibCxxMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibCxxMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibCxxMapIteratorSyntheticFrontEnd ();
+ private:
+ ValueObject *m_pair_ptr;
+ };
+
+ SyntheticChildrenFrontEnd* LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class VectorIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ VectorIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp,
+ ConstString item_name);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~VectorIteratorSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ ConstString m_item_name;
+ lldb::ValueObjectSP m_item_sp;
+ };
+
+ SyntheticChildrenFrontEnd* LibCxxVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ SyntheticChildrenFrontEnd* LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibcxxSharedPtrSyntheticFrontEnd ();
+ private:
+ ValueObject* m_cntrl;
+ lldb::ValueObjectSP m_count_sp;
+ lldb::ValueObjectSP m_weak_count_sp;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_byte_order;
+ };
+
+ SyntheticChildrenFrontEnd* LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibcxxStdVectorSyntheticFrontEnd ();
+ private:
+ ValueObject* m_start;
+ ValueObject* m_finish;
+ ClangASTType m_element_type;
+ uint32_t m_element_size;
+ std::map<size_t,lldb::ValueObjectSP> m_children;
+ };
+
+ SyntheticChildrenFrontEnd* LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibcxxStdListSyntheticFrontEnd ();
+ private:
+ bool
+ HasLoop();
+
+ size_t m_list_capping_size;
+ static const bool g_use_loop_detect = true;
+ lldb::addr_t m_node_address;
+ ValueObject* m_head;
+ ValueObject* m_tail;
+ ClangASTType m_element_type;
+ size_t m_count;
+ std::map<size_t,lldb::ValueObjectSP> m_children;
+ };
+
+ SyntheticChildrenFrontEnd* LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibcxxStdMapSyntheticFrontEnd ();
+ private:
+ bool
+ GetDataType();
+
+ void
+ GetValueOffset (const lldb::ValueObjectSP& node);
+
+ ValueObject* m_tree;
+ ValueObject* m_root_node;
+ ClangASTType m_element_type;
+ uint32_t m_skip_size;
+ size_t m_count;
+ std::map<size_t,lldb::ValueObjectSP> m_children;
+ };
+
+ SyntheticChildrenFrontEnd* LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ } // namespace formatters
+} // namespace lldb_private
+
+#endif // liblldb_CXXFormatterFunctions_h_
diff --git a/include/lldb/DataFormatters/DataVisualization.h b/include/lldb/DataFormatters/DataVisualization.h
new file mode 100644
index 000000000000..499e0fe14d93
--- /dev/null
+++ b/include/lldb/DataFormatters/DataVisualization.h
@@ -0,0 +1,174 @@
+//===-- DataVisualization.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_DataVisualization_h_
+#define lldb_DataVisualization_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/DataFormatters/FormatClasses.h"
+#include "lldb/DataFormatters/FormatManager.h"
+
+namespace lldb_private {
+
+// this class is the high-level front-end of LLDB Data Visualization
+// code in FormatManager.h/cpp is the low-level implementation of this feature
+// clients should refer to this class as the entry-point into the data formatters
+// unless they have a good reason to bypass this and go to the backend
+class DataVisualization
+{
+public:
+
+ // use this call to force the FM to consider itself updated even when there is no apparent reason for that
+ static void
+ ForceUpdate();
+
+ static uint32_t
+ GetCurrentRevision ();
+
+ class ValueFormats
+ {
+ public:
+ static lldb::TypeFormatImplSP
+ GetFormat (ValueObject& valobj, lldb::DynamicValueType use_dynamic);
+
+ static lldb::TypeFormatImplSP
+ GetFormat (const ConstString &type);
+
+ static void
+ Add (const ConstString &type, const lldb::TypeFormatImplSP &entry);
+
+ static bool
+ Delete (const ConstString &type);
+
+ static void
+ Clear ();
+
+ static void
+ LoopThrough (TypeFormatImpl::ValueCallback callback, void* callback_baton);
+
+ static size_t
+ GetCount ();
+
+ static lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierForFormatAtIndex (size_t);
+
+ static lldb::TypeFormatImplSP
+ GetFormatAtIndex (size_t);
+ };
+
+ static lldb::TypeSummaryImplSP
+ GetSummaryFormat(ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+
+ static lldb::TypeSummaryImplSP
+ GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+#ifndef LLDB_DISABLE_PYTHON
+ static lldb::SyntheticChildrenSP
+ GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp);
+#endif
+
+ static lldb::TypeFilterImplSP
+ GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+#ifndef LLDB_DISABLE_PYTHON
+ static lldb::ScriptedSyntheticChildrenSP
+ GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+ static lldb::SyntheticChildrenSP
+ GetSyntheticChildren(ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+#endif
+
+ static bool
+ AnyMatches(ConstString type_name,
+ TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,
+ bool only_enabled = true,
+ const char** matching_category = NULL,
+ TypeCategoryImpl::FormatCategoryItems* matching_type = NULL);
+
+ class NamedSummaryFormats
+ {
+ public:
+ static bool
+ GetSummaryFormat (const ConstString &type, lldb::TypeSummaryImplSP &entry);
+
+ static void
+ Add (const ConstString &type, const lldb::TypeSummaryImplSP &entry);
+
+ static bool
+ Delete (const ConstString &type);
+
+ static void
+ Clear ();
+
+ static void
+ LoopThrough (TypeSummaryImpl::SummaryCallback callback, void* callback_baton);
+
+ static uint32_t
+ GetCount ();
+ };
+
+ class Categories
+ {
+ public:
+
+ static bool
+ GetCategory (const ConstString &category,
+ lldb::TypeCategoryImplSP &entry,
+ bool allow_create = true);
+
+ static void
+ Add (const ConstString &category);
+
+ static bool
+ Delete (const ConstString &category);
+
+ static void
+ Clear ();
+
+ static void
+ Clear (const ConstString &category);
+
+ static void
+ Enable (const ConstString& category,
+ TypeCategoryMap::Position = TypeCategoryMap::Default);
+
+ static void
+ Disable (const ConstString& category);
+
+ static void
+ Enable (const lldb::TypeCategoryImplSP& category,
+ TypeCategoryMap::Position = TypeCategoryMap::Default);
+
+ static void
+ Disable (const lldb::TypeCategoryImplSP& category);
+
+ static void
+ LoopThrough (FormatManager::CategoryCallback callback, void* callback_baton);
+
+ static uint32_t
+ GetCount ();
+
+ static lldb::TypeCategoryImplSP
+ GetCategoryAtIndex (size_t);
+ };
+};
+
+
+} // namespace lldb_private
+
+#endif // lldb_DataVisualization_h_
diff --git a/include/lldb/DataFormatters/FormatCache.h b/include/lldb/DataFormatters/FormatCache.h
new file mode 100644
index 000000000000..941b96c1facc
--- /dev/null
+++ b/include/lldb/DataFormatters/FormatCache.h
@@ -0,0 +1,101 @@
+//===-- FormatCache.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_FormatCache_h_
+#define lldb_FormatCache_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/DataFormatters/FormatClasses.h"
+
+namespace lldb_private {
+class FormatCache
+{
+private:
+ struct Entry
+ {
+ private:
+ bool m_summary_cached : 1;
+ bool m_synthetic_cached : 1;
+
+ lldb::TypeSummaryImplSP m_summary_sp;
+ lldb::SyntheticChildrenSP m_synthetic_sp;
+ public:
+ Entry ();
+ Entry (lldb::TypeSummaryImplSP);
+ Entry (lldb::SyntheticChildrenSP);
+ Entry (lldb::TypeSummaryImplSP,lldb::SyntheticChildrenSP);
+
+ bool
+ IsSummaryCached ();
+
+ bool
+ IsSyntheticCached ();
+
+ lldb::TypeSummaryImplSP
+ GetSummary ();
+
+ lldb::SyntheticChildrenSP
+ GetSynthetic ();
+
+ void
+ SetSummary (lldb::TypeSummaryImplSP);
+
+ void
+ SetSynthetic (lldb::SyntheticChildrenSP);
+ };
+ typedef std::map<ConstString,Entry> CacheMap;
+ CacheMap m_map;
+ Mutex m_mutex;
+
+ uint64_t m_cache_hits;
+ uint64_t m_cache_misses;
+
+ Entry&
+ GetEntry (const ConstString& type);
+
+public:
+ FormatCache ();
+
+ bool
+ GetSummary (const ConstString& type,lldb::TypeSummaryImplSP& summary_sp);
+
+ bool
+ GetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp);
+
+ void
+ SetSummary (const ConstString& type,lldb::TypeSummaryImplSP& summary_sp);
+
+ void
+ SetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp);
+
+ void
+ Clear ();
+
+ uint64_t
+ GetCacheHits ()
+ {
+ return m_cache_hits;
+ }
+
+ uint64_t
+ GetCacheMisses ()
+ {
+ return m_cache_misses;
+ }
+};
+} // namespace lldb_private
+
+#endif // lldb_FormatCache_h_
diff --git a/include/lldb/DataFormatters/FormatClasses.h b/include/lldb/DataFormatters/FormatClasses.h
new file mode 100644
index 000000000000..48a8eda4ad43
--- /dev/null
+++ b/include/lldb/DataFormatters/FormatClasses.h
@@ -0,0 +1,128 @@
+//===-- FormatClasses.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_FormatClasses_h_
+#define lldb_FormatClasses_h_
+
+// C Includes
+#include <stdint.h>
+#include <unistd.h>
+
+// C++ Includes
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/Type.h"
+
+#include "lldb/DataFormatters/TypeFormat.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+
+namespace lldb_private {
+
+class TypeNameSpecifierImpl
+{
+public:
+ TypeNameSpecifierImpl() :
+ m_is_regex(false),
+ m_type()
+ {
+ }
+
+ TypeNameSpecifierImpl (const char* name, bool is_regex) :
+ m_is_regex(is_regex),
+ m_type()
+ {
+ if (name)
+ m_type.m_type_name.assign(name);
+ }
+
+ // if constructing with a given type, is_regex cannot be true since we are
+ // giving an exact type to match
+ TypeNameSpecifierImpl (lldb::TypeSP type) :
+ m_is_regex(false),
+ m_type()
+ {
+ if (type)
+ {
+ m_type.m_type_name.assign(type->GetName().GetCString());
+ m_type.m_typeimpl_sp = lldb::TypeImplSP(new TypeImpl(type));
+ }
+ }
+
+ TypeNameSpecifierImpl (ClangASTType type) :
+ m_is_regex(false),
+ m_type()
+ {
+ if (type.IsValid())
+ {
+ m_type.m_type_name.assign(type.GetConstTypeName().GetCString());
+ m_type.m_typeimpl_sp = lldb::TypeImplSP(new TypeImpl(type));
+ }
+ }
+
+ const char*
+ GetName()
+ {
+ if (m_type.m_type_name.size())
+ return m_type.m_type_name.c_str();
+ return NULL;
+ }
+
+ lldb::TypeSP
+ GetTypeSP ()
+ {
+ if (m_type.m_typeimpl_sp && m_type.m_typeimpl_sp->IsValid())
+ return m_type.m_typeimpl_sp->GetTypeSP();
+ return lldb::TypeSP();
+ }
+
+ ClangASTType
+ GetClangASTType ()
+ {
+ if (m_type.m_typeimpl_sp && m_type.m_typeimpl_sp->IsValid())
+ return m_type.m_typeimpl_sp->GetClangASTType();
+ return ClangASTType();
+ }
+
+ bool
+ IsRegex()
+ {
+ return m_is_regex;
+ }
+
+private:
+ bool m_is_regex;
+ // this works better than TypeAndOrName because the latter only wraps a TypeSP
+ // whereas TypeImplSP can also be backed by a ClangASTType which is more commonly
+ // used in LLDB. moreover, TypeImplSP is also what is currently backing SBType
+ struct TypeOrName
+ {
+ std::string m_type_name;
+ lldb::TypeImplSP m_typeimpl_sp;
+ };
+ TypeOrName m_type;
+
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(TypeNameSpecifierImpl);
+};
+
+} // namespace lldb_private
+
+#endif // lldb_FormatClasses_h_
diff --git a/include/lldb/DataFormatters/FormatManager.h b/include/lldb/DataFormatters/FormatManager.h
new file mode 100644
index 000000000000..162e25143f27
--- /dev/null
+++ b/include/lldb/DataFormatters/FormatManager.h
@@ -0,0 +1,251 @@
+//===-- FormatManager.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_FormatManager_h_
+#define lldb_FormatManager_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/DataFormatters/FormatCache.h"
+#include "lldb/DataFormatters/FormatNavigator.h"
+#include "lldb/DataFormatters/TypeCategory.h"
+#include "lldb/DataFormatters/TypeCategoryMap.h"
+
+namespace lldb_private {
+
+// this file (and its. cpp) contain the low-level implementation of LLDB Data Visualization
+// class DataVisualization is the high-level front-end of this feature
+// clients should refer to that class as the entry-point into the data formatters
+// unless they have a good reason to bypass it and prefer to use this file's objects directly
+
+class FormatManager : public IFormatChangeListener
+{
+ typedef FormatNavigator<ConstString, TypeFormatImpl> ValueNavigator;
+ typedef ValueNavigator::MapType ValueMap;
+ typedef FormatMap<ConstString, TypeSummaryImpl> NamedSummariesMap;
+ typedef TypeCategoryMap::MapType::iterator CategoryMapIterator;
+public:
+
+ typedef TypeCategoryMap::CallbackType CategoryCallback;
+
+ FormatManager ();
+
+ ValueNavigator&
+ GetValueNavigator ()
+ {
+ return m_value_nav;
+ }
+
+ NamedSummariesMap&
+ GetNamedSummaryNavigator ()
+ {
+ return m_named_summaries_map;
+ }
+
+ void
+ EnableCategory (const ConstString& category_name,
+ TypeCategoryMap::Position pos = TypeCategoryMap::Default)
+ {
+ m_categories_map.Enable(category_name,
+ pos);
+ }
+
+ void
+ DisableCategory (const ConstString& category_name)
+ {
+ m_categories_map.Disable(category_name);
+ }
+
+ void
+ EnableCategory (const lldb::TypeCategoryImplSP& category,
+ TypeCategoryMap::Position pos = TypeCategoryMap::Default)
+ {
+ m_categories_map.Enable(category,
+ pos);
+ }
+
+ void
+ DisableCategory (const lldb::TypeCategoryImplSP& category)
+ {
+ m_categories_map.Disable(category);
+ }
+
+ bool
+ DeleteCategory (const ConstString& category_name)
+ {
+ return m_categories_map.Delete(category_name);
+ }
+
+ void
+ ClearCategories ()
+ {
+ return m_categories_map.Clear();
+ }
+
+ uint32_t
+ GetCategoriesCount ()
+ {
+ return m_categories_map.GetCount();
+ }
+
+ lldb::TypeCategoryImplSP
+ GetCategoryAtIndex (size_t index)
+ {
+ return m_categories_map.GetAtIndex(index);
+ }
+
+ void
+ LoopThroughCategories (CategoryCallback callback, void* param)
+ {
+ m_categories_map.LoopThrough(callback, param);
+ }
+
+ lldb::TypeCategoryImplSP
+ GetCategory (const char* category_name = NULL,
+ bool can_create = true)
+ {
+ if (!category_name)
+ return GetCategory(m_default_category_name);
+ return GetCategory(ConstString(category_name));
+ }
+
+ lldb::TypeCategoryImplSP
+ GetCategory (const ConstString& category_name,
+ bool can_create = true);
+
+ lldb::TypeSummaryImplSP
+ GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+ lldb::TypeFilterImplSP
+ GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+#ifndef LLDB_DISABLE_PYTHON
+ lldb::ScriptedSyntheticChildrenSP
+ GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+ lldb::SyntheticChildrenSP
+ GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp);
+#endif
+
+ lldb::TypeSummaryImplSP
+ GetSummaryFormat (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+
+#ifndef LLDB_DISABLE_PYTHON
+ lldb::SyntheticChildrenSP
+ GetSyntheticChildren (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+#endif
+
+ bool
+ AnyMatches (ConstString type_name,
+ TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,
+ bool only_enabled = true,
+ const char** matching_category = NULL,
+ TypeCategoryImpl::FormatCategoryItems* matching_type = NULL)
+ {
+ return m_categories_map.AnyMatches(type_name,
+ items,
+ only_enabled,
+ matching_category,
+ matching_type);
+ }
+
+ static bool
+ GetFormatFromCString (const char *format_cstr,
+ bool partial_match_ok,
+ lldb::Format &format);
+
+ static char
+ GetFormatAsFormatChar (lldb::Format format);
+
+ static const char *
+ GetFormatAsCString (lldb::Format format);
+
+ // if the user tries to add formatters for, say, "struct Foo"
+ // those will not match any type because of the way we strip qualifiers from typenames
+ // this method looks for the case where the user is adding a "class","struct","enum" or "union" Foo
+ // and strips the unnecessary qualifier
+ static ConstString
+ GetValidTypeName (const ConstString& type);
+
+ // when DataExtractor dumps a vectorOfT, it uses a predefined format for each item
+ // this method returns it, or eFormatInvalid if vector_format is not a vectorOf
+ static lldb::Format
+ GetSingleItemFormat (lldb::Format vector_format);
+
+ void
+ Changed ()
+ {
+ __sync_add_and_fetch(&m_last_revision, +1);
+ m_format_cache.Clear ();
+ }
+
+ uint32_t
+ GetCurrentRevision ()
+ {
+ return m_last_revision;
+ }
+
+ ~FormatManager ()
+ {
+ }
+
+private:
+ FormatCache m_format_cache;
+ ValueNavigator m_value_nav;
+ NamedSummariesMap m_named_summaries_map;
+ uint32_t m_last_revision;
+ TypeCategoryMap m_categories_map;
+
+ ConstString m_default_category_name;
+ ConstString m_system_category_name;
+ ConstString m_gnu_cpp_category_name;
+ ConstString m_libcxx_category_name;
+ ConstString m_objc_category_name;
+ ConstString m_corefoundation_category_name;
+ ConstString m_coregraphics_category_name;
+ ConstString m_coreservices_category_name;
+ ConstString m_vectortypes_category_name;
+ ConstString m_appkit_category_name;
+
+ TypeCategoryMap&
+ GetCategories ()
+ {
+ return m_categories_map;
+ }
+
+ // WARNING: these are temporary functions that setup formatters
+ // while a few of these actually should be globally available and setup by LLDB itself
+ // most would actually belong to the users' lldbinit file or to some other form of configurable
+ // storage
+ void
+ LoadLibStdcppFormatters ();
+
+ void
+ LoadLibcxxFormatters ();
+
+ void
+ LoadSystemFormatters ();
+
+ void
+ LoadObjCFormatters ();
+};
+
+} // namespace lldb_private
+
+#endif // lldb_FormatManager_h_
diff --git a/include/lldb/DataFormatters/FormatNavigator.h b/include/lldb/DataFormatters/FormatNavigator.h
new file mode 100644
index 000000000000..a738cfd069e7
--- /dev/null
+++ b/include/lldb/DataFormatters/FormatNavigator.h
@@ -0,0 +1,690 @@
+//===-- FormatNavigator.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_FormatNavigator_h_
+#define lldb_FormatNavigator_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/DeclObjC.h"
+
+// Project includes
+#include "lldb/lldb-public.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/ValueObject.h"
+
+#include "lldb/DataFormatters/FormatClasses.h"
+
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangASTType.h"
+
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/TargetList.h"
+
+namespace lldb_private {
+
+// this file (and its. cpp) contain the low-level implementation of LLDB Data Visualization
+// class DataVisualization is the high-level front-end of this feature
+// clients should refer to that class as the entry-point into the data formatters
+// unless they have a good reason to bypass it and prefer to use this file's objects directly
+class IFormatChangeListener
+{
+public:
+ virtual void
+ Changed () = 0;
+
+ virtual
+ ~IFormatChangeListener () {}
+
+ virtual uint32_t
+ GetCurrentRevision () = 0;
+
+};
+
+static inline bool
+IsWhitespace (char c)
+{
+ return ( (c == ' ') || (c == '\t') || (c == '\v') || (c == '\f') );
+}
+
+static inline bool
+HasPrefix (const char* str1, const char* str2)
+{
+ return ( ::strstr(str1, str2) == str1 );
+}
+
+// if the user tries to add formatters for, say, "struct Foo"
+// those will not match any type because of the way we strip qualifiers from typenames
+// this method looks for the case where the user is adding a "class","struct","enum" or "union" Foo
+// and strips the unnecessary qualifier
+static inline ConstString
+GetValidTypeName_Impl (const ConstString& type)
+{
+ int strip_len = 0;
+
+ if (type == false)
+ return type;
+
+ const char* type_cstr = type.AsCString();
+
+ if ( HasPrefix(type_cstr, "class ") )
+ strip_len = 6;
+ else if ( HasPrefix(type_cstr, "enum ") )
+ strip_len = 5;
+ else if ( HasPrefix(type_cstr, "struct ") )
+ strip_len = 7;
+ else if ( HasPrefix(type_cstr, "union ") )
+ strip_len = 6;
+
+ if (strip_len == 0)
+ return type;
+
+ type_cstr += strip_len;
+ while (IsWhitespace(*type_cstr) && ++type_cstr)
+ ;
+
+ return ConstString(type_cstr);
+}
+
+template<typename KeyType, typename ValueType>
+class FormatNavigator;
+
+template<typename KeyType, typename ValueType>
+class FormatMap
+{
+public:
+
+ typedef typename ValueType::SharedPointer ValueSP;
+ typedef std::map<KeyType, ValueSP> MapType;
+ typedef typename MapType::iterator MapIterator;
+ typedef bool(*CallbackType)(void*, KeyType, const ValueSP&);
+
+ FormatMap(IFormatChangeListener* lst) :
+ m_map(),
+ m_map_mutex(Mutex::eMutexTypeRecursive),
+ listener(lst)
+ {
+ }
+
+ void
+ Add(KeyType name,
+ const ValueSP& entry)
+ {
+ if (listener)
+ entry->GetRevision() = listener->GetCurrentRevision();
+ else
+ entry->GetRevision() = 0;
+
+ Mutex::Locker locker(m_map_mutex);
+ m_map[name] = entry;
+ if (listener)
+ listener->Changed();
+ }
+
+ bool
+ Delete (KeyType name)
+ {
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.find(name);
+ if (iter == m_map.end())
+ return false;
+ m_map.erase(name);
+ if (listener)
+ listener->Changed();
+ return true;
+ }
+
+ void
+ Clear ()
+ {
+ Mutex::Locker locker(m_map_mutex);
+ m_map.clear();
+ if (listener)
+ listener->Changed();
+ }
+
+ bool
+ Get(KeyType name,
+ ValueSP& entry)
+ {
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.find(name);
+ if (iter == m_map.end())
+ return false;
+ entry = iter->second;
+ return true;
+ }
+
+ void
+ LoopThrough (CallbackType callback, void* param)
+ {
+ if (callback)
+ {
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator pos, end = m_map.end();
+ for (pos = m_map.begin(); pos != end; pos++)
+ {
+ KeyType type = pos->first;
+ if (!callback(param, type, pos->second))
+ break;
+ }
+ }
+ }
+
+ uint32_t
+ GetCount ()
+ {
+ return m_map.size();
+ }
+
+ ValueSP
+ GetValueAtIndex (size_t index)
+ {
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.begin();
+ MapIterator end = m_map.end();
+ while (index > 0)
+ {
+ iter++;
+ index--;
+ if (end == iter)
+ return ValueSP();
+ }
+ return iter->second;
+ }
+
+ KeyType
+ GetKeyAtIndex (size_t index)
+ {
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.begin();
+ MapIterator end = m_map.end();
+ while (index > 0)
+ {
+ iter++;
+ index--;
+ if (end == iter)
+ return KeyType();
+ }
+ return iter->first;
+ }
+
+protected:
+ MapType m_map;
+ Mutex m_map_mutex;
+ IFormatChangeListener* listener;
+
+ MapType&
+ map ()
+ {
+ return m_map;
+ }
+
+ Mutex&
+ mutex ()
+ {
+ return m_map_mutex;
+ }
+
+ friend class FormatNavigator<KeyType, ValueType>;
+ friend class FormatManager;
+
+};
+
+template<typename KeyType, typename ValueType>
+class FormatNavigator
+{
+protected:
+ typedef FormatMap<KeyType,ValueType> BackEndType;
+
+public:
+ typedef typename BackEndType::MapType MapType;
+ typedef typename MapType::iterator MapIterator;
+ typedef typename MapType::key_type MapKeyType;
+ typedef typename MapType::mapped_type MapValueType;
+ typedef typename BackEndType::CallbackType CallbackType;
+ typedef typename std::shared_ptr<FormatNavigator<KeyType, ValueType> > SharedPointer;
+
+ friend class TypeCategoryImpl;
+
+ FormatNavigator(std::string name,
+ IFormatChangeListener* lst) :
+ m_format_map(lst),
+ m_name(name),
+ m_id_cs(ConstString("id"))
+ {
+ }
+
+ void
+ Add (const MapKeyType &type, const MapValueType& entry)
+ {
+ Add_Impl(type, entry, (KeyType*)NULL);
+ }
+
+ bool
+ Delete (ConstString type)
+ {
+ return Delete_Impl(type, (KeyType*)NULL);
+ }
+
+ bool
+ Get(ValueObject& valobj,
+ MapValueType& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t* why = NULL)
+ {
+ uint32_t value = lldb_private::eFormatterChoiceCriterionDirectChoice;
+ ClangASTType ast_type(valobj.GetClangType());
+ bool ret = Get(valobj, ast_type, entry, use_dynamic, value);
+ if (ret)
+ entry = MapValueType(entry);
+ else
+ entry = MapValueType();
+ if (why)
+ *why = value;
+ return ret;
+ }
+
+ bool
+ Get (ConstString type, MapValueType& entry)
+ {
+ return Get_Impl(type, entry, (KeyType*)NULL);
+ }
+
+ bool
+ GetExact (ConstString type, MapValueType& entry)
+ {
+ return GetExact_Impl(type, entry, (KeyType*)NULL);
+ }
+
+ MapValueType
+ GetAtIndex (size_t index)
+ {
+ return m_format_map.GetValueAtIndex(index);
+ }
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierAtIndex (size_t index)
+ {
+ return GetTypeNameSpecifierAtIndex_Impl(index, (KeyType*)NULL);
+ }
+
+ void
+ Clear ()
+ {
+ m_format_map.Clear();
+ }
+
+ void
+ LoopThrough (CallbackType callback, void* param)
+ {
+ m_format_map.LoopThrough(callback,param);
+ }
+
+ uint32_t
+ GetCount ()
+ {
+ return m_format_map.GetCount();
+ }
+
+protected:
+
+ BackEndType m_format_map;
+
+ std::string m_name;
+
+ DISALLOW_COPY_AND_ASSIGN(FormatNavigator);
+
+ ConstString m_id_cs;
+
+ void
+ Add_Impl (const MapKeyType &type, const MapValueType& entry, lldb::RegularExpressionSP *dummy)
+ {
+ m_format_map.Add(type,entry);
+ }
+
+ void Add_Impl (const ConstString &type, const MapValueType& entry, ConstString *dummy)
+ {
+ m_format_map.Add(GetValidTypeName_Impl(type), entry);
+ }
+
+ bool
+ Delete_Impl (ConstString type, ConstString *dummy)
+ {
+ return m_format_map.Delete(type);
+ }
+
+ bool
+ Delete_Impl (ConstString type, lldb::RegularExpressionSP *dummy)
+ {
+ Mutex& x_mutex = m_format_map.mutex();
+ lldb_private::Mutex::Locker locker(x_mutex);
+ MapIterator pos, end = m_format_map.map().end();
+ for (pos = m_format_map.map().begin(); pos != end; pos++)
+ {
+ lldb::RegularExpressionSP regex = pos->first;
+ if ( ::strcmp(type.AsCString(),regex->GetText()) == 0)
+ {
+ m_format_map.map().erase(pos);
+ if (m_format_map.listener)
+ m_format_map.listener->Changed();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool
+ Get_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
+ {
+ return m_format_map.Get(type, entry);
+ }
+
+ bool
+ GetExact_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
+ {
+ return Get_Impl(type,entry, (KeyType*)0);
+ }
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierAtIndex_Impl (size_t index, ConstString *dummy)
+ {
+ ConstString key = m_format_map.GetKeyAtIndex(index);
+ if (key)
+ return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(key.AsCString(),
+ false));
+ else
+ return lldb::TypeNameSpecifierImplSP();
+ }
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierAtIndex_Impl (size_t index, lldb::RegularExpressionSP *dummy)
+ {
+ lldb::RegularExpressionSP regex = m_format_map.GetKeyAtIndex(index);
+ if (regex.get() == NULL)
+ return lldb::TypeNameSpecifierImplSP();
+ return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(regex->GetText(),
+ true));
+ }
+
+ bool
+ Get_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
+ {
+ const char* key_cstr = key.AsCString();
+ if (!key_cstr)
+ return false;
+ Mutex& x_mutex = m_format_map.mutex();
+ lldb_private::Mutex::Locker locker(x_mutex);
+ MapIterator pos, end = m_format_map.map().end();
+ for (pos = m_format_map.map().begin(); pos != end; pos++)
+ {
+ lldb::RegularExpressionSP regex = pos->first;
+ if (regex->Execute(key_cstr))
+ {
+ value = pos->second;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool
+ GetExact_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
+ {
+ Mutex& x_mutex = m_format_map.mutex();
+ lldb_private::Mutex::Locker locker(x_mutex);
+ MapIterator pos, end = m_format_map.map().end();
+ for (pos = m_format_map.map().begin(); pos != end; pos++)
+ {
+ lldb::RegularExpressionSP regex = pos->first;
+ if (strcmp(regex->GetText(),key.AsCString()) == 0)
+ {
+ value = pos->second;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool
+ Get_BitfieldMatch (ValueObject& valobj,
+ ConstString typeName,
+ MapValueType& entry,
+ uint32_t& reason)
+ {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+ // for bitfields, append size to the typename so one can custom format them
+ StreamString sstring;
+ sstring.Printf("%s:%d",typeName.AsCString(),valobj.GetBitfieldBitSize());
+ ConstString bitfieldname = ConstString(sstring.GetData());
+ if (log)
+ log->Printf("[Get_BitfieldMatch] appended bitfield info, final result is %s", bitfieldname.GetCString());
+ if (Get(bitfieldname, entry))
+ {
+ if (log)
+ log->Printf("[Get_BitfieldMatch] bitfield direct match found, returning");
+ return true;
+ }
+ else
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
+ if (log)
+ log->Printf("[Get_BitfieldMatch] no bitfield direct match");
+ return false;
+ }
+ }
+
+ bool Get_ObjC (ValueObject& valobj,
+ MapValueType& entry)
+ {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+ lldb::ProcessSP process_sp = valobj.GetProcessSP();
+ ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
+ if (runtime == NULL)
+ {
+ if (log)
+ log->Printf("[Get_ObjC] no valid ObjC runtime, skipping dynamic");
+ return false;
+ }
+ ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetClassDescriptor(valobj));
+ if (!objc_class_sp)
+ {
+ if (log)
+ log->Printf("[Get_ObjC] invalid ISA, skipping dynamic");
+ return false;
+ }
+ ConstString name (objc_class_sp->GetClassName());
+ if (log)
+ log->Printf("[Get_ObjC] dynamic type inferred is %s - looking for direct dynamic match", name.GetCString());
+ if (Get(name, entry))
+ {
+ if (log)
+ log->Printf("[Get_ObjC] direct dynamic match found, returning");
+ return true;
+ }
+ if (log)
+ log->Printf("[Get_ObjC] no dynamic match");
+ return false;
+ }
+
+ bool
+ Get_Impl (ValueObject& valobj,
+ ClangASTType clang_type,
+ MapValueType& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t& reason)
+ {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+
+ if (!clang_type.IsValid())
+ {
+ if (log)
+ log->Printf("[Get_Impl] type is invalid, returning");
+ return false;
+ }
+
+ clang_type = clang_type.RemoveFastQualifiers();
+
+ ConstString typeName(clang_type.GetConstTypeName());
+
+ if (valobj.GetBitfieldBitSize() > 0)
+ {
+ if (Get_BitfieldMatch(valobj, typeName, entry, reason))
+ return true;
+ }
+
+ if (log)
+ log->Printf("[Get_Impl] trying to get %s for VO name %s of type %s",
+ m_name.c_str(),
+ valobj.GetName().AsCString(),
+ typeName.AsCString());
+
+ if (Get(typeName, entry))
+ {
+ if (log)
+ log->Printf("[Get] direct match found, returning");
+ return true;
+ }
+ if (log)
+ log->Printf("[Get_Impl] no direct match");
+
+ // strip pointers and references and see if that helps
+ if (clang_type.IsReferenceType())
+ {
+ if (log)
+ log->Printf("[Get_Impl] stripping reference");
+ if (Get_Impl(valobj, clang_type.GetNonReferenceType(), entry, use_dynamic, reason) && !entry->SkipsReferences())
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
+ return true;
+ }
+ }
+ else if (clang_type.IsPointerType())
+ {
+ if (log)
+ log->Printf("[Get_Impl] stripping pointer");
+ if (Get_Impl(valobj, clang_type.GetPointeeType(), entry, use_dynamic, reason) && !entry->SkipsPointers())
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
+ return true;
+ }
+ }
+
+ bool canBeObjCDynamic = valobj.GetClangType().IsPossibleDynamicType (NULL,
+ false, // no C++
+ true); // yes ObjC
+
+ if (canBeObjCDynamic)
+ {
+ if (use_dynamic != lldb::eNoDynamicValues)
+ {
+ if (log)
+ log->Printf("[Get_Impl] allowed to figure out dynamic ObjC type");
+ if (Get_ObjC(valobj,entry))
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionDynamicObjCDiscovery;
+ return true;
+ }
+ }
+ if (log)
+ log->Printf("[Get_Impl] dynamic disabled or failed - stripping ObjC pointer");
+ if (Get_Impl(valobj, clang_type.GetPointeeType(), entry, use_dynamic, reason) && !entry->SkipsPointers())
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
+ return true;
+ }
+ }
+
+ // try to strip typedef chains
+ if (clang_type.IsTypedefType())
+ {
+ if (log)
+ log->Printf("[Get_Impl] stripping typedef");
+ if ((Get_Impl(valobj, clang_type.GetTypedefedType(), entry, use_dynamic, reason)) && entry->Cascades())
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionNavigatedTypedefs;
+ return true;
+ }
+ }
+
+ // out of luck here
+ return false;
+ }
+
+ // we are separately passing in valobj and type because the valobj is fixed (and is used for ObjC discovery and bitfield size)
+ // but the type can change (e.g. stripping pointers, ...)
+ bool Get (ValueObject& valobj,
+ ClangASTType clang_type,
+ MapValueType& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t& reason)
+ {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+
+ if (Get_Impl (valobj, clang_type, entry, use_dynamic, reason))
+ return true;
+
+ // try going to the unqualified type
+ do {
+ if (log)
+ log->Printf("[Get] trying the unqualified type");
+ if (!clang_type.IsValid())
+ break;
+
+ ClangASTType unqual_clang_ast_type = clang_type.GetFullyUnqualifiedType();
+ if (!unqual_clang_ast_type.IsValid())
+ {
+ if (log)
+ log->Printf("[Get] could not get the unqual_clang_ast_type");
+ break;
+ }
+ if (unqual_clang_ast_type.GetOpaqueQualType() != clang_type.GetOpaqueQualType())
+ {
+ if (log)
+ log->Printf("[Get] unqualified type is there and is not the same, let's try");
+ if (Get_Impl (valobj, unqual_clang_ast_type,entry, use_dynamic, reason))
+ return true;
+ }
+ else if (log)
+ log->Printf("[Get] unqualified type same as original type");
+ } while(false);
+
+ // if all else fails, go to static type
+ if (valobj.IsDynamic())
+ {
+ if (log)
+ log->Printf("[Get] going to static value");
+ lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
+ if (static_value_sp)
+ {
+ if (log)
+ log->Printf("[Get] has a static value - actually use it");
+ if (Get(*static_value_sp.get(), static_value_sp->GetClangType(), entry, use_dynamic, reason))
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionWentToStaticValue;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+};
+
+} // namespace lldb_private
+
+#endif // lldb_FormatNavigator_h_
diff --git a/include/lldb/DataFormatters/TypeCategory.h b/include/lldb/DataFormatters/TypeCategory.h
new file mode 100644
index 000000000000..b76d84f4772f
--- /dev/null
+++ b/include/lldb/DataFormatters/TypeCategory.h
@@ -0,0 +1,230 @@
+//===-- TypeCategory.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_TypeCategory_h_
+#define lldb_TypeCategory_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/DataFormatters/FormatNavigator.h"
+
+namespace lldb_private {
+ class TypeCategoryImpl
+ {
+ private:
+
+ typedef FormatNavigator<ConstString, TypeSummaryImpl> SummaryNavigator;
+ typedef FormatNavigator<lldb::RegularExpressionSP, TypeSummaryImpl> RegexSummaryNavigator;
+
+ typedef FormatNavigator<ConstString, TypeFilterImpl> FilterNavigator;
+ typedef FormatNavigator<lldb::RegularExpressionSP, TypeFilterImpl> RegexFilterNavigator;
+
+#ifndef LLDB_DISABLE_PYTHON
+ typedef FormatNavigator<ConstString, ScriptedSyntheticChildren> SynthNavigator;
+ typedef FormatNavigator<lldb::RegularExpressionSP, ScriptedSyntheticChildren> RegexSynthNavigator;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+
+ typedef SummaryNavigator::MapType SummaryMap;
+ typedef RegexSummaryNavigator::MapType RegexSummaryMap;
+ typedef FilterNavigator::MapType FilterMap;
+ typedef RegexFilterNavigator::MapType RegexFilterMap;
+#ifndef LLDB_DISABLE_PYTHON
+ typedef SynthNavigator::MapType SynthMap;
+ typedef RegexSynthNavigator::MapType RegexSynthMap;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+
+ public:
+
+ typedef uint16_t FormatCategoryItems;
+ static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;
+
+ typedef SummaryNavigator::SharedPointer SummaryNavigatorSP;
+ typedef RegexSummaryNavigator::SharedPointer RegexSummaryNavigatorSP;
+ typedef FilterNavigator::SharedPointer FilterNavigatorSP;
+ typedef RegexFilterNavigator::SharedPointer RegexFilterNavigatorSP;
+#ifndef LLDB_DISABLE_PYTHON
+ typedef SynthNavigator::SharedPointer SynthNavigatorSP;
+ typedef RegexSynthNavigator::SharedPointer RegexSynthNavigatorSP;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+
+ TypeCategoryImpl (IFormatChangeListener* clist,
+ ConstString name);
+
+ SummaryNavigatorSP
+ GetSummaryNavigator ()
+ {
+ return SummaryNavigatorSP(m_summary_nav);
+ }
+
+ RegexSummaryNavigatorSP
+ GetRegexSummaryNavigator ()
+ {
+ return RegexSummaryNavigatorSP(m_regex_summary_nav);
+ }
+
+ FilterNavigatorSP
+ GetFilterNavigator ()
+ {
+ return FilterNavigatorSP(m_filter_nav);
+ }
+
+ RegexFilterNavigatorSP
+ GetRegexFilterNavigator ()
+ {
+ return RegexFilterNavigatorSP(m_regex_filter_nav);
+ }
+
+ SummaryNavigator::MapValueType
+ GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+ FilterNavigator::MapValueType
+ GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+#ifndef LLDB_DISABLE_PYTHON
+ SynthNavigator::MapValueType
+ GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
+#endif
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierForSummaryAtIndex (size_t index);
+
+ SummaryNavigator::MapValueType
+ GetSummaryAtIndex (size_t index);
+
+ FilterNavigator::MapValueType
+ GetFilterAtIndex (size_t index);
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierForFilterAtIndex (size_t index);
+
+#ifndef LLDB_DISABLE_PYTHON
+ SynthNavigatorSP
+ GetSyntheticNavigator ()
+ {
+ return SynthNavigatorSP(m_synth_nav);
+ }
+
+ RegexSynthNavigatorSP
+ GetRegexSyntheticNavigator ()
+ {
+ return RegexSynthNavigatorSP(m_regex_synth_nav);
+ }
+
+ SynthNavigator::MapValueType
+ GetSyntheticAtIndex (size_t index);
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierForSyntheticAtIndex (size_t index);
+
+#endif // #ifndef LLDB_DISABLE_PYTHON
+
+ bool
+ IsEnabled () const
+ {
+ return m_enabled;
+ }
+
+ uint32_t
+ GetEnabledPosition()
+ {
+ if (m_enabled == false)
+ return UINT32_MAX;
+ else
+ return m_enabled_position;
+ }
+
+ bool
+ Get (ValueObject& valobj,
+ lldb::TypeSummaryImplSP& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t* reason = NULL);
+
+ bool
+ Get (ValueObject& valobj,
+ lldb::SyntheticChildrenSP& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t* reason = NULL);
+
+ void
+ Clear (FormatCategoryItems items = ALL_ITEM_TYPES);
+
+ bool
+ Delete (ConstString name,
+ FormatCategoryItems items = ALL_ITEM_TYPES);
+
+ uint32_t
+ GetCount (FormatCategoryItems items = ALL_ITEM_TYPES);
+
+ const char*
+ GetName ()
+ {
+ return m_name.GetCString();
+ }
+
+ bool
+ AnyMatches (ConstString type_name,
+ FormatCategoryItems items = ALL_ITEM_TYPES,
+ bool only_enabled = true,
+ const char** matching_category = NULL,
+ FormatCategoryItems* matching_type = NULL);
+
+ typedef std::shared_ptr<TypeCategoryImpl> SharedPointer;
+
+ private:
+ SummaryNavigator::SharedPointer m_summary_nav;
+ RegexSummaryNavigator::SharedPointer m_regex_summary_nav;
+ FilterNavigator::SharedPointer m_filter_nav;
+ RegexFilterNavigator::SharedPointer m_regex_filter_nav;
+#ifndef LLDB_DISABLE_PYTHON
+ SynthNavigator::SharedPointer m_synth_nav;
+ RegexSynthNavigator::SharedPointer m_regex_synth_nav;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+
+ bool m_enabled;
+
+ IFormatChangeListener* m_change_listener;
+
+ Mutex m_mutex;
+
+ ConstString m_name;
+
+ uint32_t m_enabled_position;
+
+ void
+ Enable (bool value, uint32_t position);
+
+ void
+ Disable ()
+ {
+ Enable(false, UINT32_MAX);
+ }
+
+ friend class TypeCategoryMap;
+
+ friend class FormatNavigator<ConstString, TypeSummaryImpl>;
+ friend class FormatNavigator<lldb::RegularExpressionSP, TypeSummaryImpl>;
+
+ friend class FormatNavigator<ConstString, TypeFilterImpl>;
+ friend class FormatNavigator<lldb::RegularExpressionSP, TypeFilterImpl>;
+
+#ifndef LLDB_DISABLE_PYTHON
+ friend class FormatNavigator<ConstString, ScriptedSyntheticChildren>;
+ friend class FormatNavigator<lldb::RegularExpressionSP, ScriptedSyntheticChildren>;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+ };
+
+} // namespace lldb_private
+
+#endif // lldb_TypeCategory_h_
diff --git a/include/lldb/DataFormatters/TypeCategoryMap.h b/include/lldb/DataFormatters/TypeCategoryMap.h
new file mode 100644
index 000000000000..c2465ad13aa7
--- /dev/null
+++ b/include/lldb/DataFormatters/TypeCategoryMap.h
@@ -0,0 +1,148 @@
+//===-- TypeCategoryMap.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_TypeCategoryMap_h_
+#define lldb_TypeCategoryMap_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/DataFormatters/FormatNavigator.h"
+#include "lldb/DataFormatters/TypeCategory.h"
+
+namespace lldb_private {
+ class TypeCategoryMap
+ {
+ private:
+ typedef ConstString KeyType;
+ typedef TypeCategoryImpl ValueType;
+ typedef ValueType::SharedPointer ValueSP;
+ typedef std::list<lldb::TypeCategoryImplSP> ActiveCategoriesList;
+ typedef ActiveCategoriesList::iterator ActiveCategoriesIterator;
+
+ public:
+ typedef std::map<KeyType, ValueSP> MapType;
+ typedef MapType::iterator MapIterator;
+ typedef bool(*CallbackType)(void*, const ValueSP&);
+ typedef uint32_t Position;
+
+ static const Position First = 0;
+ static const Position Default = 1;
+ static const Position Last = UINT32_MAX;
+
+ TypeCategoryMap (IFormatChangeListener* lst);
+
+ void
+ Add (KeyType name,
+ const ValueSP& entry);
+
+ bool
+ Delete (KeyType name);
+
+ bool
+ Enable (KeyType category_name,
+ Position pos = Default);
+
+ bool
+ Disable (KeyType category_name);
+
+ bool
+ Enable (ValueSP category,
+ Position pos = Default);
+
+ bool
+ Disable (ValueSP category);
+
+ void
+ Clear ();
+
+ bool
+ Get (KeyType name,
+ ValueSP& entry);
+
+ bool
+ Get (uint32_t pos,
+ ValueSP& entry);
+
+ void
+ LoopThrough (CallbackType callback, void* param);
+
+ lldb::TypeCategoryImplSP
+ GetAtIndex (uint32_t);
+
+ bool
+ AnyMatches (ConstString type_name,
+ TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,
+ bool only_enabled = true,
+ const char** matching_category = NULL,
+ TypeCategoryImpl::FormatCategoryItems* matching_type = NULL);
+
+ uint32_t
+ GetCount ()
+ {
+ return m_map.size();
+ }
+
+ lldb::TypeSummaryImplSP
+ GetSummaryFormat (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+
+#ifndef LLDB_DISABLE_PYTHON
+ lldb::SyntheticChildrenSP
+ GetSyntheticChildren (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+#endif
+
+ private:
+
+ class delete_matching_categories
+ {
+ lldb::TypeCategoryImplSP ptr;
+ public:
+ delete_matching_categories(lldb::TypeCategoryImplSP p) : ptr(p)
+ {}
+
+ bool operator()(const lldb::TypeCategoryImplSP& other)
+ {
+ return ptr.get() == other.get();
+ }
+ };
+
+ Mutex m_map_mutex;
+ IFormatChangeListener* listener;
+
+ MapType m_map;
+ ActiveCategoriesList m_active_categories;
+
+ MapType& map ()
+ {
+ return m_map;
+ }
+
+ ActiveCategoriesList& active_list ()
+ {
+ return m_active_categories;
+ }
+
+ Mutex& mutex ()
+ {
+ return m_map_mutex;
+ }
+
+ friend class FormatNavigator<KeyType, ValueType>;
+ friend class FormatManager;
+ };
+} // namespace lldb_private
+
+#endif // lldb_TypeCategoryMap_h_
diff --git a/include/lldb/DataFormatters/TypeFormat.h b/include/lldb/DataFormatters/TypeFormat.h
new file mode 100644
index 000000000000..77135c448ed1
--- /dev/null
+++ b/include/lldb/DataFormatters/TypeFormat.h
@@ -0,0 +1,220 @@
+//===-- TypeFormat.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_TypeFormat_h_
+#define lldb_TypeFormat_h_
+
+// C Includes
+
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/ValueObject.h"
+
+namespace lldb_private {
+ class TypeFormatImpl
+ {
+ public:
+ class Flags
+ {
+ public:
+
+ Flags () :
+ m_flags (lldb::eTypeOptionCascade)
+ {}
+
+ Flags (const Flags& other) :
+ m_flags (other.m_flags)
+ {}
+
+ Flags (uint32_t value) :
+ m_flags (value)
+ {}
+
+ Flags&
+ operator = (const Flags& rhs)
+ {
+ if (&rhs != this)
+ m_flags = rhs.m_flags;
+
+ return *this;
+ }
+
+ Flags&
+ operator = (const uint32_t& rhs)
+ {
+ m_flags = rhs;
+ return *this;
+ }
+
+ Flags&
+ Clear()
+ {
+ m_flags = 0;
+ return *this;
+ }
+
+ bool
+ GetCascades () const
+ {
+ return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
+ }
+
+ Flags&
+ SetCascades (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionCascade;
+ else
+ m_flags &= ~lldb::eTypeOptionCascade;
+ return *this;
+ }
+
+ bool
+ GetSkipPointers () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
+ }
+
+ Flags&
+ SetSkipPointers (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipPointers;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipPointers;
+ return *this;
+ }
+
+ bool
+ GetSkipReferences () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
+ }
+
+ Flags&
+ SetSkipReferences (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipReferences;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipReferences;
+ return *this;
+ }
+
+ uint32_t
+ GetValue ()
+ {
+ return m_flags;
+ }
+
+ void
+ SetValue (uint32_t value)
+ {
+ m_flags = value;
+ }
+
+ private:
+ uint32_t m_flags;
+ };
+
+ TypeFormatImpl (lldb::Format f = lldb::eFormatInvalid,
+ const Flags& flags = Flags());
+
+ typedef std::shared_ptr<TypeFormatImpl> SharedPointer;
+ typedef bool(*ValueCallback)(void*, ConstString, const lldb::TypeFormatImplSP&);
+
+ ~TypeFormatImpl ()
+ {
+ }
+
+ bool
+ Cascades () const
+ {
+ return m_flags.GetCascades();
+ }
+ bool
+ SkipsPointers () const
+ {
+ return m_flags.GetSkipPointers();
+ }
+ bool
+ SkipsReferences () const
+ {
+ return m_flags.GetSkipReferences();
+ }
+
+ void
+ SetCascades (bool value)
+ {
+ m_flags.SetCascades(value);
+ }
+
+ void
+ SetSkipsPointers (bool value)
+ {
+ m_flags.SetSkipPointers(value);
+ }
+
+ void
+ SetSkipsReferences (bool value)
+ {
+ m_flags.SetSkipReferences(value);
+ }
+
+ lldb::Format
+ GetFormat () const
+ {
+ return m_format;
+ }
+
+ void
+ SetFormat (lldb::Format fmt)
+ {
+ m_format = fmt;
+ }
+
+ uint32_t
+ GetOptions ()
+ {
+ return m_flags.GetValue();
+ }
+
+ void
+ SetOptions (uint32_t value)
+ {
+ m_flags.SetValue(value);
+ }
+
+ uint32_t&
+ GetRevision ()
+ {
+ return m_my_revision;
+ }
+
+ std::string
+ GetDescription();
+
+ protected:
+ Flags m_flags;
+ lldb::Format m_format;
+ uint32_t m_my_revision;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl);
+ };
+} // namespace lldb_private
+
+#endif // lldb_TypeFormat_h_
diff --git a/include/lldb/DataFormatters/TypeSummary.h b/include/lldb/DataFormatters/TypeSummary.h
new file mode 100644
index 000000000000..2183384b9d62
--- /dev/null
+++ b/include/lldb/DataFormatters/TypeSummary.h
@@ -0,0 +1,547 @@
+//===-- TypeSummary.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_TypeSummary_h_
+#define lldb_TypeSummary_h_
+
+// C Includes
+#include <stdint.h>
+#include <unistd.h>
+
+// C++ Includes
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
+#include "lldb/Symbol/Type.h"
+
+namespace lldb_private {
+
+ class TypeSummaryImpl
+ {
+ public:
+ class Flags
+ {
+ public:
+
+ Flags () :
+ m_flags (lldb::eTypeOptionCascade)
+ {}
+
+ Flags (const Flags& other) :
+ m_flags (other.m_flags)
+ {}
+
+ Flags (uint32_t value) :
+ m_flags (value)
+ {}
+
+ Flags&
+ operator = (const Flags& rhs)
+ {
+ if (&rhs != this)
+ m_flags = rhs.m_flags;
+
+ return *this;
+ }
+
+ Flags&
+ operator = (const uint32_t& rhs)
+ {
+ m_flags = rhs;
+ return *this;
+ }
+
+ Flags&
+ Clear()
+ {
+ m_flags = 0;
+ return *this;
+ }
+
+ bool
+ GetCascades () const
+ {
+ return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
+ }
+
+ Flags&
+ SetCascades (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionCascade;
+ else
+ m_flags &= ~lldb::eTypeOptionCascade;
+ return *this;
+ }
+
+ bool
+ GetSkipPointers () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
+ }
+
+ Flags&
+ SetSkipPointers (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipPointers;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipPointers;
+ return *this;
+ }
+
+ bool
+ GetSkipReferences () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
+ }
+
+ Flags&
+ SetSkipReferences (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipReferences;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipReferences;
+ return *this;
+ }
+
+ bool
+ GetDontShowChildren () const
+ {
+ return (m_flags & lldb::eTypeOptionHideChildren) == lldb::eTypeOptionHideChildren;
+ }
+
+ Flags&
+ SetDontShowChildren (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionHideChildren;
+ else
+ m_flags &= ~lldb::eTypeOptionHideChildren;
+ return *this;
+ }
+
+ bool
+ GetDontShowValue () const
+ {
+ return (m_flags & lldb::eTypeOptionHideValue) == lldb::eTypeOptionHideValue;
+ }
+
+ Flags&
+ SetDontShowValue (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionHideValue;
+ else
+ m_flags &= ~lldb::eTypeOptionHideValue;
+ return *this;
+ }
+
+ bool
+ GetShowMembersOneLiner () const
+ {
+ return (m_flags & lldb::eTypeOptionShowOneLiner) == lldb::eTypeOptionShowOneLiner;
+ }
+
+ Flags&
+ SetShowMembersOneLiner (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionShowOneLiner;
+ else
+ m_flags &= ~lldb::eTypeOptionShowOneLiner;
+ return *this;
+ }
+
+ bool
+ GetHideItemNames () const
+ {
+ return (m_flags & lldb::eTypeOptionHideNames) == lldb::eTypeOptionHideNames;
+ }
+
+ Flags&
+ SetHideItemNames (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionHideNames;
+ else
+ m_flags &= ~lldb::eTypeOptionHideNames;
+ return *this;
+ }
+
+ uint32_t
+ GetValue ()
+ {
+ return m_flags;
+ }
+
+ void
+ SetValue (uint32_t value)
+ {
+ m_flags = value;
+ }
+
+ private:
+ uint32_t m_flags;
+ };
+
+ typedef enum Type
+ {
+ eTypeUnknown,
+ eTypeString,
+ eTypeScript,
+ eTypeCallback
+ } Type;
+
+ TypeSummaryImpl (const TypeSummaryImpl::Flags& flags);
+
+ bool
+ Cascades () const
+ {
+ return m_flags.GetCascades();
+ }
+ bool
+ SkipsPointers () const
+ {
+ return m_flags.GetSkipPointers();
+ }
+ bool
+ SkipsReferences () const
+ {
+ return m_flags.GetSkipReferences();
+ }
+
+ bool
+ DoesPrintChildren () const
+ {
+ return !m_flags.GetDontShowChildren();
+ }
+
+ bool
+ DoesPrintValue () const
+ {
+ return !m_flags.GetDontShowValue();
+ }
+
+ bool
+ IsOneliner () const
+ {
+ return m_flags.GetShowMembersOneLiner();
+ }
+
+ bool
+ HideNames () const
+ {
+ return m_flags.GetHideItemNames();
+ }
+
+ void
+ SetCascades (bool value)
+ {
+ m_flags.SetCascades(value);
+ }
+
+ void
+ SetSkipsPointers (bool value)
+ {
+ m_flags.SetSkipPointers(value);
+ }
+
+ void
+ SetSkipsReferences (bool value)
+ {
+ m_flags.SetSkipReferences(value);
+ }
+
+ void
+ SetDoesPrintChildren (bool value)
+ {
+ m_flags.SetDontShowChildren(!value);
+ }
+
+ void
+ SetDoesPrintValue (bool value)
+ {
+ m_flags.SetDontShowValue(!value);
+ }
+
+ void
+ SetIsOneliner (bool value)
+ {
+ m_flags.SetShowMembersOneLiner(value);
+ }
+
+ void
+ SetHideNames (bool value)
+ {
+ m_flags.SetHideItemNames(value);
+ }
+
+ uint32_t
+ GetOptions ()
+ {
+ return m_flags.GetValue();
+ }
+
+ void
+ SetOptions (uint32_t value)
+ {
+ m_flags.SetValue(value);
+ }
+
+ virtual
+ ~TypeSummaryImpl ()
+ {
+ }
+
+ // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
+ // extended periods of time and we trust the ValueObject to stay around for as long as it is required
+ // for us to generate its summary
+ virtual bool
+ FormatObject (ValueObject *valobj,
+ std::string& dest) = 0;
+
+ virtual std::string
+ GetDescription () = 0;
+
+ virtual bool
+ IsScripted () = 0;
+
+ virtual Type
+ GetType () = 0;
+
+ uint32_t&
+ GetRevision ()
+ {
+ return m_my_revision;
+ }
+
+ typedef std::shared_ptr<TypeSummaryImpl> SharedPointer;
+ typedef bool(*SummaryCallback)(void*, ConstString, const lldb::TypeSummaryImplSP&);
+ typedef bool(*RegexSummaryCallback)(void*, lldb::RegularExpressionSP, const lldb::TypeSummaryImplSP&);
+
+ protected:
+ uint32_t m_my_revision;
+ Flags m_flags;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeSummaryImpl);
+ };
+
+ // simple string-based summaries, using ${var to show data
+ struct StringSummaryFormat : public TypeSummaryImpl
+ {
+ std::string m_format;
+
+ StringSummaryFormat(const TypeSummaryImpl::Flags& flags,
+ const char* f);
+
+ const char*
+ GetSummaryString () const
+ {
+ return m_format.c_str();
+ }
+
+ void
+ SetSummaryString (const char* data)
+ {
+ if (data)
+ m_format.assign(data);
+ else
+ m_format.clear();
+ }
+
+ virtual
+ ~StringSummaryFormat()
+ {
+ }
+
+ virtual bool
+ FormatObject(ValueObject *valobj,
+ std::string& dest);
+
+ virtual std::string
+ GetDescription();
+
+ virtual bool
+ IsScripted ()
+ {
+ return false;
+ }
+
+
+ virtual Type
+ GetType ()
+ {
+ return TypeSummaryImpl::eTypeString;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat);
+ };
+
+ // summaries implemented via a C++ function
+ struct CXXFunctionSummaryFormat : public TypeSummaryImpl
+ {
+
+ // we should convert these to SBValue and SBStream if we ever cross
+ // the boundary towards the external world
+ typedef bool (*Callback)(ValueObject& valobj, Stream& dest);
+
+ Callback m_impl;
+ std::string m_description;
+
+ CXXFunctionSummaryFormat (const TypeSummaryImpl::Flags& flags,
+ Callback impl,
+ const char* description);
+
+ Callback
+ GetBackendFunction () const
+ {
+ return m_impl;
+ }
+
+ const char*
+ GetTextualInfo () const
+ {
+ return m_description.c_str();
+ }
+
+ void
+ SetBackendFunction (Callback cb_func)
+ {
+ m_impl = cb_func;
+ }
+
+ void
+ SetTextualInfo (const char* descr)
+ {
+ if (descr)
+ m_description.assign(descr);
+ else
+ m_description.clear();
+ }
+
+ virtual
+ ~CXXFunctionSummaryFormat ()
+ {
+ }
+
+ virtual bool
+ FormatObject (ValueObject *valobj,
+ std::string& dest);
+
+ virtual std::string
+ GetDescription ();
+
+ virtual bool
+ IsScripted ()
+ {
+ return false;
+ }
+
+ virtual Type
+ GetType ()
+ {
+ return TypeSummaryImpl::eTypeCallback;
+ }
+
+ typedef std::shared_ptr<CXXFunctionSummaryFormat> SharedPointer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CXXFunctionSummaryFormat);
+ };
+
+#ifndef LLDB_DISABLE_PYTHON
+
+ // Python-based summaries, running script code to show data
+ struct ScriptSummaryFormat : public TypeSummaryImpl
+ {
+ std::string m_function_name;
+ std::string m_python_script;
+ lldb::ScriptInterpreterObjectSP m_script_function_sp;
+
+ ScriptSummaryFormat(const TypeSummaryImpl::Flags& flags,
+ const char *function_name,
+ const char* python_script = NULL);
+
+ const char*
+ GetFunctionName () const
+ {
+ return m_function_name.c_str();
+ }
+
+ const char*
+ GetPythonScript () const
+ {
+ return m_python_script.c_str();
+ }
+
+ void
+ SetFunctionName (const char* function_name)
+ {
+ if (function_name)
+ m_function_name.assign(function_name);
+ else
+ m_function_name.clear();
+ m_python_script.clear();
+ }
+
+ void
+ SetPythonScript (const char* script)
+ {
+ if (script)
+ m_python_script.assign(script);
+ else
+ m_python_script.clear();
+ }
+
+ virtual
+ ~ScriptSummaryFormat ()
+ {
+ }
+
+ virtual bool
+ FormatObject (ValueObject *valobj,
+ std::string& dest);
+
+ virtual std::string
+ GetDescription ();
+
+ virtual bool
+ IsScripted ()
+ {
+ return true;
+ }
+
+ virtual Type
+ GetType ()
+ {
+ return TypeSummaryImpl::eTypeScript;
+ }
+
+ typedef std::shared_ptr<ScriptSummaryFormat> SharedPointer;
+
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScriptSummaryFormat);
+ };
+#endif
+} // namespace lldb_private
+
+#endif // lldb_TypeSummary_h_
diff --git a/include/lldb/DataFormatters/TypeSynthetic.h b/include/lldb/DataFormatters/TypeSynthetic.h
new file mode 100644
index 000000000000..a32f4b761175
--- /dev/null
+++ b/include/lldb/DataFormatters/TypeSynthetic.h
@@ -0,0 +1,594 @@
+//===-- TypeSynthetic.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_TypeSynthetic_h_
+#define lldb_TypeSynthetic_h_
+
+// C Includes
+#include <stdint.h>
+#include <unistd.h>
+
+// C++ Includes
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
+#include "lldb/Symbol/Type.h"
+
+namespace lldb_private {
+ class SyntheticChildrenFrontEnd
+ {
+ protected:
+ ValueObject &m_backend;
+ public:
+
+ SyntheticChildrenFrontEnd (ValueObject &backend) :
+ m_backend(backend)
+ {}
+
+ virtual
+ ~SyntheticChildrenFrontEnd ()
+ {
+ }
+
+ virtual size_t
+ CalculateNumChildren () = 0;
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx) = 0;
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name) = 0;
+
+ // this function is assumed to always succeed and it if fails, the front-end should know to deal
+ // with it in the correct way (most probably, by refusing to return any children)
+ // the return value of Update() should actually be interpreted as "ValueObjectSyntheticFilter cache is good/bad"
+ // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached
+ // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children
+ virtual bool
+ Update () = 0;
+
+ // if this function returns false, then CalculateNumChildren() MUST return 0 since UI frontends
+ // might validly decide not to inquire for children given a false return value from this call
+ // if it returns true, then CalculateNumChildren() can return any number >= 0 (0 being valid)
+ // it should if at all possible be more efficient than CalculateNumChildren()
+ virtual bool
+ MightHaveChildren () = 0;
+
+ typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
+ typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
+ };
+
+ class SyntheticChildren
+ {
+ public:
+
+ class Flags
+ {
+ public:
+
+ Flags () :
+ m_flags (lldb::eTypeOptionCascade)
+ {}
+
+ Flags (const Flags& other) :
+ m_flags (other.m_flags)
+ {}
+
+ Flags (uint32_t value) :
+ m_flags (value)
+ {}
+
+ Flags&
+ operator = (const Flags& rhs)
+ {
+ if (&rhs != this)
+ m_flags = rhs.m_flags;
+
+ return *this;
+ }
+
+ Flags&
+ operator = (const uint32_t& rhs)
+ {
+ m_flags = rhs;
+ return *this;
+ }
+
+ Flags&
+ Clear()
+ {
+ m_flags = 0;
+ return *this;
+ }
+
+ bool
+ GetCascades () const
+ {
+ return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
+ }
+
+ Flags&
+ SetCascades (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionCascade;
+ else
+ m_flags &= ~lldb::eTypeOptionCascade;
+ return *this;
+ }
+
+ bool
+ GetSkipPointers () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
+ }
+
+ Flags&
+ SetSkipPointers (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipPointers;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipPointers;
+ return *this;
+ }
+
+ bool
+ GetSkipReferences () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
+ }
+
+ Flags&
+ SetSkipReferences (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipReferences;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipReferences;
+ return *this;
+ }
+
+ uint32_t
+ GetValue ()
+ {
+ return m_flags;
+ }
+
+ void
+ SetValue (uint32_t value)
+ {
+ m_flags = value;
+ }
+
+ private:
+ uint32_t m_flags;
+ };
+
+ SyntheticChildren (const Flags& flags) :
+ m_flags(flags)
+ {
+ }
+
+ virtual
+ ~SyntheticChildren ()
+ {
+ }
+
+ bool
+ Cascades () const
+ {
+ return m_flags.GetCascades();
+ }
+ bool
+ SkipsPointers () const
+ {
+ return m_flags.GetSkipPointers();
+ }
+ bool
+ SkipsReferences () const
+ {
+ return m_flags.GetSkipReferences();
+ }
+
+ void
+ SetCascades (bool value)
+ {
+ m_flags.SetCascades(value);
+ }
+
+ void
+ SetSkipsPointers (bool value)
+ {
+ m_flags.SetSkipPointers(value);
+ }
+
+ void
+ SetSkipsReferences (bool value)
+ {
+ m_flags.SetSkipReferences(value);
+ }
+
+ uint32_t
+ GetOptions ()
+ {
+ return m_flags.GetValue();
+ }
+
+ void
+ SetOptions (uint32_t value)
+ {
+ m_flags.SetValue(value);
+ }
+
+ virtual bool
+ IsScripted () = 0;
+
+ virtual std::string
+ GetDescription () = 0;
+
+ virtual SyntheticChildrenFrontEnd::AutoPointer
+ GetFrontEnd (ValueObject &backend) = 0;
+
+ typedef std::shared_ptr<SyntheticChildren> SharedPointer;
+ typedef bool(*SyntheticChildrenCallback)(void*, ConstString, const SyntheticChildren::SharedPointer&);
+
+ uint32_t&
+ GetRevision ()
+ {
+ return m_my_revision;
+ }
+
+ protected:
+ uint32_t m_my_revision;
+ Flags m_flags;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
+ };
+
+ class TypeFilterImpl : public SyntheticChildren
+ {
+ std::vector<std::string> m_expression_paths;
+ public:
+ TypeFilterImpl(const SyntheticChildren::Flags& flags) :
+ SyntheticChildren(flags),
+ m_expression_paths()
+ {
+ }
+
+ TypeFilterImpl(const SyntheticChildren::Flags& flags,
+ const std::initializer_list<const char*> items) :
+ SyntheticChildren(flags),
+ m_expression_paths()
+ {
+ for (auto path : items)
+ AddExpressionPath (path);
+ }
+
+ void
+ AddExpressionPath (const char* path)
+ {
+ AddExpressionPath(std::string(path));
+ }
+
+ void
+ Clear()
+ {
+ m_expression_paths.clear();
+ }
+
+ size_t
+ GetCount() const
+ {
+ return m_expression_paths.size();
+ }
+
+ const char*
+ GetExpressionPathAtIndex(size_t i) const
+ {
+ return m_expression_paths[i].c_str();
+ }
+
+ bool
+ SetExpressionPathAtIndex (size_t i, const char* path)
+ {
+ return SetExpressionPathAtIndex(i, std::string(path));
+ }
+
+ void
+ AddExpressionPath (const std::string& path)
+ {
+ bool need_add_dot = true;
+ if (path[0] == '.' ||
+ (path[0] == '-' && path[1] == '>') ||
+ path[0] == '[')
+ need_add_dot = false;
+ // add a '.' symbol to help forgetful users
+ if(!need_add_dot)
+ m_expression_paths.push_back(path);
+ else
+ m_expression_paths.push_back(std::string(".") + path);
+ }
+
+ bool
+ SetExpressionPathAtIndex (size_t i, const std::string& path)
+ {
+ if (i >= GetCount())
+ return false;
+ bool need_add_dot = true;
+ if (path[0] == '.' ||
+ (path[0] == '-' && path[1] == '>') ||
+ path[0] == '[')
+ need_add_dot = false;
+ // add a '.' symbol to help forgetful users
+ if(!need_add_dot)
+ m_expression_paths[i] = path;
+ else
+ m_expression_paths[i] = std::string(".") + path;
+ return true;
+ }
+
+ bool
+ IsScripted ()
+ {
+ return false;
+ }
+
+ std::string
+ GetDescription ();
+
+ class FrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ TypeFilterImpl* filter;
+ public:
+
+ FrontEnd(TypeFilterImpl* flt,
+ ValueObject &backend) :
+ SyntheticChildrenFrontEnd(backend),
+ filter(flt)
+ {}
+
+ virtual
+ ~FrontEnd ()
+ {
+ }
+
+ virtual size_t
+ CalculateNumChildren ()
+ {
+ return filter->GetCount();
+ }
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx)
+ {
+ if (idx >= filter->GetCount())
+ return lldb::ValueObjectSP();
+ return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
+ }
+
+ virtual bool
+ Update() { return false; }
+
+ virtual bool
+ MightHaveChildren ()
+ {
+ return filter->GetCount() > 0;
+ }
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name)
+ {
+ const char* name_cstr = name.GetCString();
+ for (size_t i = 0; i < filter->GetCount(); i++)
+ {
+ const char* expr_cstr = filter->GetExpressionPathAtIndex(i);
+ if (expr_cstr)
+ {
+ if (*expr_cstr == '.')
+ expr_cstr++;
+ else if (*expr_cstr == '-' && *(expr_cstr+1) == '>')
+ expr_cstr += 2;
+ }
+ if (!::strcmp(name_cstr, expr_cstr))
+ return i;
+ }
+ return UINT32_MAX;
+ }
+
+ typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FrontEnd);
+ };
+
+ virtual SyntheticChildrenFrontEnd::AutoPointer
+ GetFrontEnd(ValueObject &backend)
+ {
+ return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
+ };
+
+ class CXXSyntheticChildren : public SyntheticChildren
+ {
+ public:
+ typedef SyntheticChildrenFrontEnd* (*CreateFrontEndCallback) (CXXSyntheticChildren*, lldb::ValueObjectSP);
+ protected:
+ CreateFrontEndCallback m_create_callback;
+ std::string m_description;
+ public:
+ CXXSyntheticChildren (const SyntheticChildren::Flags& flags,
+ const char* description,
+ CreateFrontEndCallback callback) :
+ SyntheticChildren(flags),
+ m_create_callback(callback),
+ m_description(description ? description : "")
+ {
+ }
+
+ bool
+ IsScripted ()
+ {
+ return false;
+ }
+
+ std::string
+ GetDescription ();
+
+ virtual SyntheticChildrenFrontEnd::AutoPointer
+ GetFrontEnd (ValueObject &backend)
+ {
+ return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
+ };
+
+#ifndef LLDB_DISABLE_PYTHON
+
+ class ScriptedSyntheticChildren : public SyntheticChildren
+ {
+ std::string m_python_class;
+ std::string m_python_code;
+ public:
+
+ ScriptedSyntheticChildren (const SyntheticChildren::Flags& flags,
+ const char* pclass,
+ const char* pcode = NULL) :
+ SyntheticChildren(flags),
+ m_python_class(),
+ m_python_code()
+ {
+ if (pclass)
+ m_python_class = pclass;
+ if (pcode)
+ m_python_code = pcode;
+ }
+
+ const char*
+ GetPythonClassName ()
+ {
+ return m_python_class.c_str();
+ }
+
+ const char*
+ GetPythonCode ()
+ {
+ return m_python_code.c_str();
+ }
+
+ void
+ SetPythonClassName (const char* fname)
+ {
+ m_python_class.assign(fname);
+ m_python_code.clear();
+ }
+
+ void
+ SetPythonCode (const char* script)
+ {
+ m_python_code.assign(script);
+ }
+
+ std::string
+ GetDescription ();
+
+ bool
+ IsScripted ()
+ {
+ return true;
+ }
+
+ class FrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ std::string m_python_class;
+ lldb::ScriptInterpreterObjectSP m_wrapper_sp;
+ ScriptInterpreter *m_interpreter;
+ public:
+
+ FrontEnd (std::string pclass,
+ ValueObject &backend);
+
+ virtual
+ ~FrontEnd ();
+
+ virtual size_t
+ CalculateNumChildren ()
+ {
+ if (!m_wrapper_sp || m_interpreter == NULL)
+ return 0;
+ return m_interpreter->CalculateNumChildren(m_wrapper_sp);
+ }
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update ()
+ {
+ if (!m_wrapper_sp || m_interpreter == NULL)
+ return false;
+
+ return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
+ }
+
+ virtual bool
+ MightHaveChildren ()
+ {
+ if (!m_wrapper_sp || m_interpreter == NULL)
+ return false;
+
+ return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp);
+ }
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name)
+ {
+ if (!m_wrapper_sp || m_interpreter == NULL)
+ return UINT32_MAX;
+ return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, name.GetCString());
+ }
+
+ typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FrontEnd);
+ };
+
+ virtual SyntheticChildrenFrontEnd::AutoPointer
+ GetFrontEnd(ValueObject &backend)
+ {
+ return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(m_python_class, backend));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
+ };
+#endif
+} // namespace lldb_private
+
+#endif // lldb_TypeSynthetic_h_
diff --git a/include/lldb/Expression/ASTDumper.h b/include/lldb/Expression/ASTDumper.h
new file mode 100644
index 000000000000..47f7ea460b87
--- /dev/null
+++ b/include/lldb/Expression/ASTDumper.h
@@ -0,0 +1,43 @@
+//===-- ASTDumper.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ASTDumper_h_
+#define liblldb_ASTDumper_h_
+
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeVisitor.h"
+
+#include "lldb/Core/Stream.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace lldb_private
+{
+
+class ASTDumper
+{
+public:
+ ASTDumper (clang::Decl *decl);
+ ASTDumper (clang::DeclContext *decl_ctx);
+ ASTDumper (const clang::Type *type);
+ ASTDumper (clang::QualType type);
+ ASTDumper (lldb::clang_type_t type);
+ ASTDumper (const ClangASTType &clang_type);
+
+ const char *GetCString();
+ void ToSTDERR();
+ void ToLog(Log *log, const char *prefix);
+ void ToStream(lldb::StreamSP &stream);
+private:
+ std::string m_dump;
+};
+
+} // namespace lldb_private
+
+#endif
diff --git a/include/lldb/Expression/ASTResultSynthesizer.h b/include/lldb/Expression/ASTResultSynthesizer.h
new file mode 100644
index 000000000000..79709de3546a
--- /dev/null
+++ b/include/lldb/Expression/ASTResultSynthesizer.h
@@ -0,0 +1,184 @@
+//===-- ASTResultSynthesizer.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ASTResultSynthesizer_h_
+#define liblldb_ASTResultSynthesizer_h_
+
+#include "clang/Sema/SemaConsumer.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Symbol/TaggedASTType.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ASTResultSynthesizer ASTResultSynthesizer.h "lldb/Expression/ASTResultSynthesizer.h"
+/// @brief Adds a result variable declaration to the ASTs for an expression.
+///
+/// Users expect the expression "i + 3" to return a result, even if a result
+/// variable wasn't specifically declared. To fulfil this requirement, LLDB adds
+/// a result variable to the expression, transforming it to
+/// "int $__lldb_expr_result = i + 3." The IR transformers ensure that the
+/// resulting variable is mapped to the right piece of memory.
+/// ASTResultSynthesizer's job is to add the variable and its initialization to
+/// the ASTs for the expression, and it does so by acting as a SemaConsumer for
+/// Clang.
+//----------------------------------------------------------------------
+class ASTResultSynthesizer : public clang::SemaConsumer
+{
+public:
+ //----------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] passthrough
+ /// Since the ASTs must typically go through to the Clang code generator
+ /// in order to produce LLVM IR, this SemaConsumer must allow them to
+ /// pass to the next step in the chain after processing. Passthrough is
+ /// the next ASTConsumer, or NULL if none is required.
+ ///
+ /// @param[in] target
+ /// The target, which contains the persistent variable store and the
+ /// AST importer.
+ //----------------------------------------------------------------------
+ ASTResultSynthesizer(clang::ASTConsumer *passthrough,
+ Target &target);
+
+ //----------------------------------------------------------------------
+ /// Destructor
+ //----------------------------------------------------------------------
+ ~ASTResultSynthesizer();
+
+ //----------------------------------------------------------------------
+ /// Link this consumer with a particular AST context
+ ///
+ /// @param[in] Context
+ /// This AST context will be used for types and identifiers, and also
+ /// forwarded to the passthrough consumer, if one exists.
+ //----------------------------------------------------------------------
+ void Initialize(clang::ASTContext &Context);
+
+ //----------------------------------------------------------------------
+ /// Examine a list of Decls to find the function $__lldb_expr and
+ /// transform its code
+ ///
+ /// @param[in] D
+ /// The list of Decls to search. These may contain LinkageSpecDecls,
+ /// which need to be searched recursively. That job falls to
+ /// TransformTopLevelDecl.
+ //----------------------------------------------------------------------
+ bool HandleTopLevelDecl(clang::DeclGroupRef D);
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTranslationUnit(clang::ASTContext &Ctx);
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTagDeclDefinition(clang::TagDecl *D);
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void CompleteTentativeDefinition(clang::VarDecl *D);
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleVTable(clang::CXXRecordDecl *RD, bool DefinitionRequired);
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void PrintStats();
+
+ //----------------------------------------------------------------------
+ /// Set the Sema object to use when performing transforms, and pass it on
+ ///
+ /// @param[in] S
+ /// The Sema to use. Because Sema isn't externally visible, this class
+ /// casts it to an Action for actual use.
+ //----------------------------------------------------------------------
+ void InitializeSema(clang::Sema &S);
+
+ //----------------------------------------------------------------------
+ /// Reset the Sema to NULL now that transformations are done
+ //----------------------------------------------------------------------
+ void ForgetSema();
+private:
+ //----------------------------------------------------------------------
+ /// Hunt the given Decl for FunctionDecls named $__lldb_expr, recursing
+ /// as necessary through LinkageSpecDecls, and calling SynthesizeResult on
+ /// anything that was found
+ ///
+ /// @param[in] D
+ /// The Decl to hunt.
+ //----------------------------------------------------------------------
+ void TransformTopLevelDecl(clang::Decl *D);
+
+ //----------------------------------------------------------------------
+ /// Process an Objective-C method and produce the result variable and
+ /// initialization
+ ///
+ /// @param[in] MethodDecl
+ /// The method to process.
+ //----------------------------------------------------------------------
+ bool SynthesizeObjCMethodResult(clang::ObjCMethodDecl *MethodDecl);
+
+ //----------------------------------------------------------------------
+ /// Process a function and produce the result variable and initialization
+ ///
+ /// @param[in] FunDecl
+ /// The function to process.
+ //----------------------------------------------------------------------
+ bool SynthesizeFunctionResult(clang::FunctionDecl *FunDecl);
+
+ //----------------------------------------------------------------------
+ /// Process a function body and produce the result variable and
+ /// initialization
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ ///
+ /// @param[in] DC
+ /// The DeclContext of the function, into which the result variable
+ /// is inserted.
+ //----------------------------------------------------------------------
+ bool SynthesizeBodyResult(clang::CompoundStmt *Body,
+ clang::DeclContext *DC);
+
+ //----------------------------------------------------------------------
+ /// Given a DeclContext for a function or method, find all types
+ /// declared in the context and record any persistent types found.
+ ///
+ /// @param[in] FunDeclCtx
+ /// The context for the function to process.
+ //----------------------------------------------------------------------
+ void RecordPersistentTypes(clang::DeclContext *FunDeclCtx);
+
+ //----------------------------------------------------------------------
+ /// Given a TypeDecl, if it declares a type whose name starts with a
+ /// dollar sign, register it as a pointer type in the target's scratch
+ /// AST context.
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ //----------------------------------------------------------------------
+ void MaybeRecordPersistentType(clang::TypeDecl *D);
+
+ clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
+ clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
+ clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
+ Target &m_target; ///< The target, which contains the persistent variable store and the
+ clang::Sema *m_sema; ///< The Sema to use.
+};
+
+}
+
+#endif
diff --git a/include/lldb/Expression/ASTStructExtractor.h b/include/lldb/Expression/ASTStructExtractor.h
new file mode 100644
index 000000000000..a1518de83d6d
--- /dev/null
+++ b/include/lldb/Expression/ASTStructExtractor.h
@@ -0,0 +1,156 @@
+//===-- ASTStructExtractor.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ASTStructExtractor_h_
+#define liblldb_ASTStructExtractor_h_
+
+#include "clang/Sema/SemaConsumer.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Expression/ClangExpressionVariable.h"
+#include "lldb/Expression/ClangFunction.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ASTStructExtractor ASTStructExtractor.h "lldb/Expression/ASTStructExtractor.h"
+/// @brief Extracts and describes the argument structure for a wrapped function.
+///
+/// This pass integrates with ClangFunction, which calls functions with custom
+/// sets of arguments. To avoid having to implement the full calling convention
+/// for the target's architecture, ClangFunction writes a simple wrapper
+/// function that takes a pointer to an argument structure that contains room
+/// for the address of the function to be called, the values of all its
+/// arguments, and room for the function's return value.
+///
+/// The definition of this struct is itself in the body of the wrapper function,
+/// so Clang does the structure layout itself. ASTStructExtractor reads through
+/// the AST for the wrapper funtion and finds the struct.
+//----------------------------------------------------------------------
+class ASTStructExtractor : public clang::SemaConsumer
+{
+public:
+ //----------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] passthrough
+ /// Since the ASTs must typically go through to the Clang code generator
+ /// in order to produce LLVM IR, this SemaConsumer must allow them to
+ /// pass to the next step in the chain after processing. Passthrough is
+ /// the next ASTConsumer, or NULL if none is required.
+ ///
+ /// @param[in] struct_name
+ /// The name of the structure to extract from the wrapper function.
+ ///
+ /// @param[in] function
+ /// The caller object whose members should be populated with information
+ /// about the argument struct. ClangFunction friends ASTStructExtractor
+ /// for this purpose.
+ //----------------------------------------------------------------------
+ ASTStructExtractor(clang::ASTConsumer *passthrough,
+ const char *struct_name,
+ ClangFunction &function);
+
+ //----------------------------------------------------------------------
+ /// Destructor
+ //----------------------------------------------------------------------
+ virtual ~ASTStructExtractor();
+
+ //----------------------------------------------------------------------
+ /// Link this consumer with a particular AST context
+ ///
+ /// @param[in] Context
+ /// This AST context will be used for types and identifiers, and also
+ /// forwarded to the passthrough consumer, if one exists.
+ //----------------------------------------------------------------------
+ void Initialize(clang::ASTContext &Context);
+
+ //----------------------------------------------------------------------
+ /// Examine a list of Decls to find the function $__lldb_expr and
+ /// transform its code
+ ///
+ /// @param[in] D
+ /// The list of Decls to search. These may contain LinkageSpecDecls,
+ /// which need to be searched recursively. That job falls to
+ /// TransformTopLevelDecl.
+ //----------------------------------------------------------------------
+ bool HandleTopLevelDecl(clang::DeclGroupRef D);
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTranslationUnit(clang::ASTContext &Ctx);
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTagDeclDefinition(clang::TagDecl *D);
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void CompleteTentativeDefinition(clang::VarDecl *D);
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleVTable(clang::CXXRecordDecl *RD, bool DefinitionRequired);
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void PrintStats();
+
+ //----------------------------------------------------------------------
+ /// Set the Sema object to use when performing transforms, and pass it on
+ ///
+ /// @param[in] S
+ /// The Sema to use. Because Sema isn't externally visible, this class
+ /// casts it to an Action for actual use.
+ //----------------------------------------------------------------------
+ void InitializeSema(clang::Sema &S);
+
+ //----------------------------------------------------------------------
+ /// Reset the Sema to NULL now that transformations are done
+ //----------------------------------------------------------------------
+ void ForgetSema();
+private:
+ //----------------------------------------------------------------------
+ /// Hunt the given FunctionDecl for the argument struct and place
+ /// information about it into m_function
+ ///
+ /// @param[in] F
+ /// The FunctionDecl to hunt.
+ //----------------------------------------------------------------------
+ void
+ ExtractFromFunctionDecl(clang::FunctionDecl* F);
+
+ //----------------------------------------------------------------------
+ /// Hunt the given Decl for FunctionDecls named the same as the wrapper
+ /// function name, recursing as necessary through LinkageSpecDecls, and
+ /// calling ExtractFromFunctionDecl on anything that was found
+ ///
+ /// @param[in] D
+ /// The Decl to hunt.
+ //----------------------------------------------------------------------
+ void
+ ExtractFromTopLevelDecl(clang::Decl* D);
+
+ clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
+ clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
+ clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
+ clang::Sema *m_sema; ///< The Sema to use.
+ clang::Action *m_action; ///< The Sema to use, cast to an Action so it's usable.
+
+ ClangFunction &m_function; ///< The function to populate with information about the argument structure.
+ std::string m_struct_name; ///< The name of the structure to extract.
+};
+
+}
+
+#endif
diff --git a/include/lldb/Expression/ClangASTSource.h b/include/lldb/Expression/ClangASTSource.h
new file mode 100644
index 000000000000..3e41a9e69e9b
--- /dev/null
+++ b/include/lldb/Expression/ClangASTSource.h
@@ -0,0 +1,530 @@
+//===-- ClangASTSource.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangASTSource_h_
+#define liblldb_ClangASTSource_h_
+
+#include <set>
+
+#include "clang/Basic/IdentifierTable.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Target/Target.h"
+
+#include "llvm/ADT/SmallSet.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
+/// @brief Provider for named objects defined in the debug info for Clang
+///
+/// As Clang parses an expression, it may encounter names that are not
+/// defined inside the expression, including variables, functions, and
+/// types. Clang knows the name it is looking for, but nothing else.
+/// The ExternalSemaSource class provides Decls (VarDecl, FunDecl, TypeDecl)
+/// to Clang for these names, consulting the ClangExpressionDeclMap to do
+/// the actual lookups.
+//----------------------------------------------------------------------
+class ClangASTSource :
+ public ClangExternalASTSourceCommon,
+ public ClangASTImporter::MapCompleter
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] declMap
+ /// A reference to the LLDB object that handles entity lookup.
+ //------------------------------------------------------------------
+ ClangASTSource (const lldb::TargetSP &target) :
+ m_import_in_progress (false),
+ m_lookups_enabled (false),
+ m_target (target),
+ m_ast_context (NULL),
+ m_active_lookups ()
+ {
+ m_ast_importer = m_target->GetClangASTImporter();
+ }
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangASTSource();
+
+ //------------------------------------------------------------------
+ /// Interface stubs.
+ //------------------------------------------------------------------
+ clang::Decl *GetExternalDecl (uint32_t) { return NULL; }
+ clang::Stmt *GetExternalDeclStmt (uint64_t) { return NULL; }
+ clang::Selector GetExternalSelector (uint32_t) { return clang::Selector(); }
+ uint32_t GetNumExternalSelectors () { return 0; }
+ clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset)
+ { return NULL; }
+ void MaterializeVisibleDecls (const clang::DeclContext *DC)
+ { return; }
+
+ void InstallASTContext (clang::ASTContext *ast_context)
+ {
+ m_ast_context = ast_context;
+ m_ast_importer->InstallMapCompleter(ast_context, *this);
+ }
+
+ //
+ // APIs for ExternalASTSource
+ //
+
+ //------------------------------------------------------------------
+ /// Look up all Decls that match a particular name. Only handles
+ /// Identifiers and DeclContexts that are either NamespaceDecls or
+ /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with
+ /// the result.
+ ///
+ /// The work for this function is done by
+ /// void FindExternalVisibleDecls (NameSearchContext &);
+ ///
+ /// @param[in] DC
+ /// The DeclContext to register the found Decls in.
+ ///
+ /// @param[in] Name
+ /// The name to find entries for.
+ ///
+ /// @return
+ /// Whatever SetExternalVisibleDeclsForName returns.
+ //------------------------------------------------------------------
+ bool
+ FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
+ clang::DeclarationName Name);
+
+ //------------------------------------------------------------------
+ /// Enumerate all Decls in a given lexical context.
+ ///
+ /// @param[in] DC
+ /// The DeclContext being searched.
+ ///
+ /// @param[in] isKindWeWant
+ /// If non-NULL, a callback function that returns true given the
+ /// DeclKinds of desired Decls, and false otherwise.
+ ///
+ /// @param[in] Decls
+ /// A vector that is filled in with matching Decls.
+ //------------------------------------------------------------------
+ clang::ExternalLoadResult
+ FindExternalLexicalDecls (const clang::DeclContext *DC,
+ bool (*isKindWeWant)(clang::Decl::Kind),
+ llvm::SmallVectorImpl<clang::Decl*> &Decls);
+
+ //------------------------------------------------------------------
+ /// Specify the layout of the contents of a RecordDecl.
+ ///
+ /// @param[in] Record
+ /// The record (in the parser's AST context) that needs to be
+ /// laid out.
+ ///
+ /// @param[out] Size
+ /// The total size of the record in bits.
+ ///
+ /// @param[out] Alignment
+ /// The alignment of the record in bits.
+ ///
+ /// @param[in] FieldOffsets
+ /// A map that must be populated with pairs of the record's
+ /// fields (in the parser's AST context) and their offsets
+ /// (measured in bits).
+ ///
+ /// @param[in] BaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ concrete base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// @param[in] VirtualBaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ virtual base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// @return
+ /// True <=> the layout is valid.
+ //-----------------------------------------------------------------
+ bool
+ layoutRecordType(const clang::RecordDecl *Record,
+ uint64_t &Size,
+ uint64_t &Alignment,
+ llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets);
+
+ //------------------------------------------------------------------
+ /// Complete a TagDecl.
+ ///
+ /// @param[in] Tag
+ /// The Decl to be completed in place.
+ //------------------------------------------------------------------
+ virtual void
+ CompleteType (clang::TagDecl *Tag);
+
+ //------------------------------------------------------------------
+ /// Complete an ObjCInterfaceDecl.
+ ///
+ /// @param[in] Class
+ /// The Decl to be completed in place.
+ //------------------------------------------------------------------
+ virtual void
+ CompleteType (clang::ObjCInterfaceDecl *Class);
+
+ //------------------------------------------------------------------
+ /// Called on entering a translation unit. Tells Clang by calling
+ /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
+ /// that this object has something to say about undefined names.
+ ///
+ /// @param[in] ASTConsumer
+ /// Unused.
+ //------------------------------------------------------------------
+ void StartTranslationUnit (clang::ASTConsumer *Consumer);
+
+ //
+ // APIs for NamespaceMapCompleter
+ //
+
+ //------------------------------------------------------------------
+ /// Look up the modules containing a given namespace and put the
+ /// appropriate entries in the namespace map.
+ ///
+ /// @param[in] namespace_map
+ /// The map to be completed.
+ ///
+ /// @param[in] name
+ /// The name of the namespace to be found.
+ ///
+ /// @param[in] parent_map
+ /// The map for the namespace's parent namespace, if there is
+ /// one.
+ //------------------------------------------------------------------
+ void CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
+ const ConstString &name,
+ ClangASTImporter::NamespaceMapSP &parent_map) const;
+
+ //
+ // Helper APIs
+ //
+
+ clang::NamespaceDecl *
+ AddNamespace (NameSearchContext &context,
+ ClangASTImporter::NamespaceMapSP &namespace_decls);
+
+ //------------------------------------------------------------------
+ /// The worker function for FindExternalVisibleDeclsByName.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when filing results.
+ //------------------------------------------------------------------
+ virtual void FindExternalVisibleDecls (NameSearchContext &context);
+
+ void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; }
+ bool GetImportInProgress () { return m_import_in_progress; }
+
+ void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; }
+ bool GetLookupsEnabled () { return m_lookups_enabled; }
+
+ //----------------------------------------------------------------------
+ /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h"
+ /// @brief Proxy for ClangASTSource
+ ///
+ /// Clang AST contexts like to own their AST sources, so this is a
+ /// state-free proxy object.
+ //----------------------------------------------------------------------
+ class ClangASTSourceProxy : public ClangExternalASTSourceCommon
+ {
+ public:
+ ClangASTSourceProxy (ClangASTSource &original) :
+ m_original(original)
+ {
+ }
+
+ bool
+ FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
+ clang::DeclarationName Name)
+ {
+ return m_original.FindExternalVisibleDeclsByName(DC, Name);
+ }
+
+ clang::ExternalLoadResult
+ FindExternalLexicalDecls (const clang::DeclContext *DC,
+ bool (*isKindWeWant)(clang::Decl::Kind),
+ llvm::SmallVectorImpl<clang::Decl*> &Decls)
+ {
+ return m_original.FindExternalLexicalDecls(DC, isKindWeWant, Decls);
+ }
+
+ void
+ CompleteType (clang::TagDecl *Tag)
+ {
+ return m_original.CompleteType(Tag);
+ }
+
+ void
+ CompleteType (clang::ObjCInterfaceDecl *Class)
+ {
+ return m_original.CompleteType(Class);
+ }
+
+ bool
+ layoutRecordType(const clang::RecordDecl *Record,
+ uint64_t &Size,
+ uint64_t &Alignment,
+ llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets)
+ {
+ return m_original.layoutRecordType(Record,
+ Size,
+ Alignment,
+ FieldOffsets,
+ BaseOffsets,
+ VirtualBaseOffsets);
+ }
+
+ void StartTranslationUnit (clang::ASTConsumer *Consumer)
+ {
+ return m_original.StartTranslationUnit(Consumer);
+ }
+
+ ClangASTMetadata *
+ GetMetadata(const void * object)
+ {
+ return m_original.GetMetadata(object);
+ }
+
+ void
+ SetMetadata(const void * object, ClangASTMetadata &metadata)
+ {
+ return m_original.SetMetadata(object, metadata);
+ }
+
+ bool
+ HasMetadata(const void * object)
+ {
+ return m_original.HasMetadata(object);
+ }
+ private:
+ ClangASTSource &m_original;
+ };
+
+ clang::ExternalASTSource *CreateProxy()
+ {
+ return new ClangASTSourceProxy(*this);
+ }
+
+protected:
+ //------------------------------------------------------------------
+ /// Look for the complete version of an Objective-C interface, and
+ /// return it if found.
+ ///
+ /// @param[in] interface_decl
+ /// An ObjCInterfaceDecl that may not be the complete one.
+ ///
+ /// @return
+ /// NULL if the complete interface couldn't be found;
+ /// the complete interface otherwise.
+ //------------------------------------------------------------------
+ clang::ObjCInterfaceDecl *
+ GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl);
+
+ //------------------------------------------------------------------
+ /// Find all entities matching a given name in a given module,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to query.
+ ///
+ /// @param[in] namespace_decl
+ /// If valid and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] current_id
+ /// The ID for the current FindExternalVisibleDecls invocation,
+ /// for logging purposes.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void
+ FindExternalVisibleDecls (NameSearchContext &context,
+ lldb::ModuleSP module,
+ ClangNamespaceDecl &namespace_decl,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Find all Objective-C methods matching a given selector.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ /// Its m_decl_name contains the selector and its m_decl_context
+ /// is the containing object.
+ //------------------------------------------------------------------
+ void
+ FindObjCMethodDecls (NameSearchContext &context);
+
+ //------------------------------------------------------------------
+ /// Find all Objective-C properties and ivars with a given name.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ /// Its m_decl_name contains the name and its m_decl_context
+ /// is the containing object.
+ //------------------------------------------------------------------
+ void
+ FindObjCPropertyAndIvarDecls (NameSearchContext &context);
+
+ //------------------------------------------------------------------
+ /// A wrapper for ClangASTContext::CopyType that sets a flag that
+ /// indicates that we should not respond to queries during import.
+ ///
+ /// @param[in] dest_context
+ /// The target AST context, typically the parser's AST context.
+ ///
+ /// @param[in] source_context
+ /// The source AST context, typically the AST context of whatever
+ /// symbol file the type was found in.
+ ///
+ /// @param[in] clang_type
+ /// The source type.
+ ///
+ /// @return
+ /// The imported type.
+ //------------------------------------------------------------------
+ ClangASTType
+ GuardedCopyType (const ClangASTType &src_type);
+
+ friend struct NameSearchContext;
+
+ bool m_import_in_progress;
+ bool m_lookups_enabled;
+
+ const lldb::TargetSP m_target; ///< The target to use in finding variables and types.
+ clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for.
+ ClangASTImporter *m_ast_importer; ///< The target's AST importer.
+ std::set<const char *> m_active_lookups;
+};
+
+//----------------------------------------------------------------------
+/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
+/// @brief Container for all objects relevant to a single name lookup
+///
+/// LLDB needs to create Decls for entities it finds. This class communicates
+/// what name is being searched for and provides helper functions to construct
+/// Decls given appropriate type information.
+//----------------------------------------------------------------------
+struct NameSearchContext {
+ ClangASTSource &m_ast_source; ///< The AST source making the request
+ llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed
+ ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules
+ const clang::DeclarationName &m_decl_name; ///< The name being looked for
+ const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into
+ llvm::SmallSet <ClangASTType, 5> m_function_types; ///< All the types of functions that have been reported, so we don't report conflicts
+
+ struct {
+ bool variable : 1;
+ bool function_with_type_info : 1;
+ bool function : 1;
+ } m_found;
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] astSource
+ /// A reference to the AST source making a request.
+ ///
+ /// @param[in] decls
+ /// A reference to a list into which new Decls will be placed. This
+ /// list is typically empty when the function is called.
+ ///
+ /// @param[in] name
+ /// The name being searched for (always an Identifier).
+ ///
+ /// @param[in] dc
+ /// The DeclContext to register Decls in.
+ //------------------------------------------------------------------
+ NameSearchContext (ClangASTSource &astSource,
+ llvm::SmallVectorImpl<clang::NamedDecl*> &decls,
+ clang::DeclarationName &name,
+ const clang::DeclContext *dc) :
+ m_ast_source(astSource),
+ m_decls(decls),
+ m_decl_name(name),
+ m_decl_context(dc)
+ {
+ memset(&m_found, 0, sizeof(m_found));
+ }
+
+ //------------------------------------------------------------------
+ /// Create a VarDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] type
+ /// The opaque QualType for the VarDecl being registered.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddVarDecl(const ClangASTType &type);
+
+ //------------------------------------------------------------------
+ /// Create a FunDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] type
+ /// The opaque QualType for the FunDecl being registered.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddFunDecl(const ClangASTType &type);
+
+ //------------------------------------------------------------------
+ /// Create a FunDecl with the name being searched for and generic
+ /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
+ /// right places.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddGenericFunDecl();
+
+ //------------------------------------------------------------------
+ /// Create a TypeDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] type
+ /// The opaque QualType for the TypeDecl being registered.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddTypeDecl(const ClangASTType &clang_type);
+
+
+ //------------------------------------------------------------------
+ /// Add Decls from the provided DeclContextLookupResult to the list
+ /// of results.
+ ///
+ /// @param[in] result
+ /// The DeclContextLookupResult, usually returned as the result
+ /// of querying a DeclContext.
+ //------------------------------------------------------------------
+ void AddLookupResult (clang::DeclContextLookupConstResult result);
+
+ //------------------------------------------------------------------
+ /// Add a NamedDecl to the list of results.
+ ///
+ /// @param[in] decl
+ /// The NamedDecl, usually returned as the result
+ /// of querying a DeclContext.
+ //------------------------------------------------------------------
+ void AddNamedDecl (clang::NamedDecl *decl);
+};
+
+}
+
+#endif
diff --git a/include/lldb/Expression/ClangExpression.h b/include/lldb/Expression/ClangExpression.h
new file mode 100644
index 000000000000..6e831e4471e8
--- /dev/null
+++ b/include/lldb/Expression/ClangExpression.h
@@ -0,0 +1,153 @@
+//===-- ClangExpression.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangExpression_h_
+#define liblldb_ClangExpression_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Target/Process.h"
+
+namespace lldb_private {
+
+class RecordingMemoryManager;
+
+//----------------------------------------------------------------------
+/// @class ClangExpression ClangExpression.h "lldb/Expression/ClangExpression.h"
+/// @brief Encapsulates a single expression for use with Clang
+///
+/// LLDB uses expressions for various purposes, notably to call functions
+/// and as a backend for the expr command. ClangExpression encapsulates
+/// the objects needed to parse and interpret or JIT an expression. It
+/// uses the Clang parser to produce LLVM IR from the expression.
+//----------------------------------------------------------------------
+class ClangExpression
+{
+public:
+ enum ResultType {
+ eResultTypeAny,
+ eResultTypeId
+ };
+
+ ClangExpression () :
+ m_jit_process_wp(),
+ m_jit_start_addr (LLDB_INVALID_ADDRESS),
+ m_jit_end_addr (LLDB_INVALID_ADDRESS)
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual ~ClangExpression ()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Return the string that the parser should parse. Must be a full
+ /// translation unit.
+ //------------------------------------------------------------------
+ virtual const char *
+ Text () = 0;
+
+ //------------------------------------------------------------------
+ /// Return the function name that should be used for executing the
+ /// expression. Text() should contain the definition of this
+ /// function.
+ //------------------------------------------------------------------
+ virtual const char *
+ FunctionName () = 0;
+
+ //------------------------------------------------------------------
+ /// Return the language that should be used when parsing. To use
+ /// the default, return eLanguageTypeUnknown.
+ //------------------------------------------------------------------
+ virtual lldb::LanguageType
+ Language ()
+ {
+ return lldb::eLanguageTypeUnknown;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
+ //------------------------------------------------------------------
+ virtual ClangExpressionDeclMap *
+ DeclMap () = 0;
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ virtual clang::ASTConsumer *
+ ASTTransformer (clang::ASTConsumer *passthrough) = 0;
+
+ //------------------------------------------------------------------
+ /// Return the desired result type of the function, or
+ /// eResultTypeAny if indifferent.
+ //------------------------------------------------------------------
+ virtual ResultType
+ DesiredResultType ()
+ {
+ return eResultTypeAny;
+ }
+
+ //------------------------------------------------------------------
+ /// Flags
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Return true if validation code should be inserted into the
+ /// expression.
+ //------------------------------------------------------------------
+ virtual bool
+ NeedsValidation () = 0;
+
+ //------------------------------------------------------------------
+ /// Return true if external variables in the expression should be
+ /// resolved.
+ //------------------------------------------------------------------
+ virtual bool
+ NeedsVariableResolution () = 0;
+
+ //------------------------------------------------------------------
+ /// Return the address of the function's JIT-compiled code, or
+ /// LLDB_INVALID_ADDRESS if the function is not JIT compiled
+ //------------------------------------------------------------------
+ lldb::addr_t
+ StartAddress ()
+ {
+ return m_jit_start_addr;
+ }
+
+protected:
+
+ lldb::ProcessWP m_jit_process_wp;
+ lldb::addr_t m_jit_start_addr; ///< The address of the JITted function within the JIT allocation. LLDB_INVALID_ADDRESS if invalid.
+ lldb::addr_t m_jit_end_addr; ///< The address of the JITted function within the JIT allocation. LLDB_INVALID_ADDRESS if invalid.
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangExpression_h_
diff --git a/include/lldb/Expression/ClangExpressionDeclMap.h b/include/lldb/Expression/ClangExpressionDeclMap.h
new file mode 100644
index 000000000000..b2a43e0ac75f
--- /dev/null
+++ b/include/lldb/Expression/ClangExpressionDeclMap.h
@@ -0,0 +1,698 @@
+//===-- ClangExpressionDeclMap.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangExpressionDeclMap_h_
+#define liblldb_ClangExpressionDeclMap_h_
+
+// C Includes
+#include <signal.h>
+#include <stdint.h>
+
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "clang/AST/Decl.h"
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Expression/ClangASTSource.h"
+#include "lldb/Expression/ClangExpressionVariable.h"
+#include "lldb/Expression/Materializer.h"
+#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/ExecutionContext.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ClangExpressionDeclMap ClangExpressionDeclMap.h "lldb/Expression/ClangExpressionDeclMap.h"
+/// @brief Manages named entities that are defined in LLDB's debug information.
+///
+/// The Clang parser uses the ClangASTSource as an interface to request named
+/// entities from outside an expression. The ClangASTSource reports back, listing
+/// all possible objects corresponding to a particular name. But it in turn
+/// relies on ClangExpressionDeclMap, which performs several important functions.
+///
+/// First, it records what variables and functions were looked up and what Decls
+/// were returned for them.
+///
+/// Second, it constructs a struct on behalf of IRForTarget, recording which
+/// variables should be placed where and relaying this information back so that
+/// IRForTarget can generate context-independent code.
+///
+/// Third, it "materializes" this struct on behalf of the expression command,
+/// finding the current values of each variable and placing them into the
+/// struct so that it can be passed to the JITted version of the IR.
+///
+/// Fourth and finally, it "dematerializes" the struct after the JITted code has
+/// has executed, placing the new values back where it found the old ones.
+//----------------------------------------------------------------------
+class ClangExpressionDeclMap :
+ public ClangASTSource
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] keep_result_in_memory
+ /// If true, inhibits the normal deallocation of the memory for
+ /// the result persistent variable, and instead marks the variable
+ /// as persisting.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when parsing.
+ //------------------------------------------------------------------
+ ClangExpressionDeclMap (bool keep_result_in_memory,
+ ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangExpressionDeclMap ();
+
+ //------------------------------------------------------------------
+ /// Enable the state needed for parsing and IR transformation.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when finding types for variables.
+ /// Also used to find a "scratch" AST context to store result types.
+ ///
+ /// @param[in] materializer
+ /// If non-NULL, the materializer to populate with information about
+ /// the variables to use
+ ///
+ /// @return
+ /// True if parsing is possible; false if it is unsafe to continue.
+ //------------------------------------------------------------------
+ bool
+ WillParse (ExecutionContext &exe_ctx,
+ Materializer *materializer);
+
+ //------------------------------------------------------------------
+ /// [Used by ClangExpressionParser] For each variable that had an unknown
+ /// type at the beginning of parsing, determine its final type now.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ResolveUnknownTypes();
+
+ //------------------------------------------------------------------
+ /// Disable the state needed for parsing and IR transformation.
+ //------------------------------------------------------------------
+ void
+ DidParse ();
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Add a variable to the list of persistent
+ /// variables for the process.
+ ///
+ /// @param[in] decl
+ /// The Clang declaration for the persistent variable, used for
+ /// lookup during parsing.
+ ///
+ /// @param[in] name
+ /// The name of the persistent variable, usually $something.
+ ///
+ /// @param[in] type
+ /// The type of the variable, in the Clang parser's context.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ AddPersistentVariable (const clang::NamedDecl *decl,
+ const ConstString &name,
+ TypeFromParser type,
+ bool is_result,
+ bool is_lvalue);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Add a variable to the struct that needs to
+ /// be materialized each time the expression runs.
+ ///
+ /// @param[in] decl
+ /// The Clang declaration for the variable.
+ ///
+ /// @param[in] name
+ /// The name of the variable.
+ ///
+ /// @param[in] value
+ /// The LLVM IR value for this variable.
+ ///
+ /// @param[in] size
+ /// The size of the variable in bytes.
+ ///
+ /// @param[in] alignment
+ /// The required alignment of the variable in bytes.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ AddValueToStruct (const clang::NamedDecl *decl,
+ const ConstString &name,
+ llvm::Value *value,
+ size_t size,
+ off_t alignment);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Finalize the struct, laying out the position
+ /// of each object in it.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ DoStructLayout ();
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get general information about the laid-out
+ /// struct after DoStructLayout() has been called.
+ ///
+ /// @param[out] num_elements
+ /// The number of elements in the struct.
+ ///
+ /// @param[out] size
+ /// The size of the struct, in bytes.
+ ///
+ /// @param[out] alignment
+ /// The alignment of the struct, in bytes.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetStructInfo (uint32_t &num_elements,
+ size_t &size,
+ off_t &alignment);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get specific information about one field
+ /// of the laid-out struct after DoStructLayout() has been called.
+ ///
+ /// @param[out] decl
+ /// The parsed Decl for the field, as generated by ClangASTSource
+ /// on ClangExpressionDeclMap's behalf. In the case of the result
+ /// value, this will have the name $__lldb_result even if the
+ /// result value ends up having the name $1. This is an
+ /// implementation detail of IRForTarget.
+ ///
+ /// @param[out] value
+ /// The IR value for the field (usually a GlobalVariable). In
+ /// the case of the result value, this will have the correct
+ /// name ($1, for instance). This is an implementation detail
+ /// of IRForTarget.
+ ///
+ /// @param[out] offset
+ /// The offset of the field from the beginning of the struct.
+ /// As long as the struct is aligned according to its required
+ /// alignment, this offset will align the field correctly.
+ ///
+ /// @param[out] name
+ /// The name of the field as used in materialization.
+ ///
+ /// @param[in] index
+ /// The index of the field about which information is requested.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetStructElement (const clang::NamedDecl *&decl,
+ llvm::Value *&value,
+ off_t &offset,
+ ConstString &name,
+ uint32_t index);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get information about a function given its
+ /// Decl.
+ ///
+ /// @param[in] decl
+ /// The parsed Decl for the Function, as generated by ClangASTSource
+ /// on ClangExpressionDeclMap's behalf.
+ ///
+ /// @param[out] ptr
+ /// The absolute address of the function in the target.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetFunctionInfo (const clang::NamedDecl *decl,
+ uint64_t &ptr);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get the address of a function given nothing
+ /// but its name. Some functions are needed but didn't get Decls made
+ /// during parsing -- specifically, sel_registerName is never called
+ /// in the generated IR but we need to call it nonetheless.
+ ///
+ /// @param[in] name
+ /// The name of the function.
+ ///
+ /// @param[out] ptr
+ /// The absolute address of the function in the target.
+ ///
+ /// @return
+ /// True if the address could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetFunctionAddress (const ConstString &name,
+ uint64_t &ptr);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get the address of a symbol given nothing
+ /// but its name.
+ ///
+ /// @param[in] target
+ /// The target to find the symbol in. If not provided,
+ /// then the current parsing context's Target.
+ ///
+ /// @param[in] process
+ /// The process to use. For Objective-C symbols, the process's
+ /// Objective-C language runtime may be queried if the process
+ /// is non-NULL.
+ ///
+ /// @param[in] name
+ /// The name of the symbol.
+ ///
+ /// @return
+ /// Valid load address for the symbol
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetSymbolAddress (Target &target,
+ Process *process,
+ const ConstString &name,
+ lldb::SymbolType symbol_type);
+
+ lldb::addr_t
+ GetSymbolAddress (const ConstString &name,
+ lldb::SymbolType symbol_type);
+
+ //------------------------------------------------------------------
+ /// [Used by IRInterpreter] Get basic target information.
+ ///
+ /// @param[out] byte_order
+ /// The byte order of the target.
+ ///
+ /// @param[out] address_byte_size
+ /// The size of a pointer in bytes.
+ ///
+ /// @return
+ /// True if the information could be determined; false
+ /// otherwise.
+ //------------------------------------------------------------------
+ struct TargetInfo
+ {
+ lldb::ByteOrder byte_order;
+ size_t address_byte_size;
+
+ TargetInfo() :
+ byte_order(lldb::eByteOrderInvalid),
+ address_byte_size(0)
+ {
+ }
+
+ bool IsValid()
+ {
+ return (byte_order != lldb::eByteOrderInvalid &&
+ address_byte_size != 0);
+ }
+ };
+ TargetInfo GetTargetInfo();
+
+ //------------------------------------------------------------------
+ /// [Used by ClangASTSource] Find all entities matching a given name,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void
+ FindExternalVisibleDecls (NameSearchContext &context);
+
+ //------------------------------------------------------------------
+ /// Find all entities matching a given name in a given module/namespace,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to query.
+ ///
+ /// @param[in] namespace_decl
+ /// If valid and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string. The NameSearchContext contains
+ /// a DeclarationName for the name so at first the name may seem
+ /// redundant, but ClangExpressionDeclMap operates in RTTI land so
+ /// it can't access DeclarationName.
+ ///
+ /// @param[in] current_id
+ /// The ID for the current FindExternalVisibleDecls invocation,
+ /// for logging purposes.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void
+ FindExternalVisibleDecls (NameSearchContext &context,
+ lldb::ModuleSP module,
+ ClangNamespaceDecl &namespace_decl,
+ unsigned int current_id);
+private:
+ ClangExpressionVariableList m_found_entities; ///< All entities that were looked up for the parser.
+ ClangExpressionVariableList m_struct_members; ///< All entities that need to be placed in the struct.
+ bool m_keep_result_in_memory; ///< True if result persistent variables generated by this expression should stay in memory.
+
+ //----------------------------------------------------------------------
+ /// The following values should not live beyond parsing
+ //----------------------------------------------------------------------
+ class ParserVars
+ {
+ public:
+ ParserVars(ClangExpressionDeclMap &decl_map) :
+ m_exe_ctx(),
+ m_sym_ctx(),
+ m_persistent_vars(NULL),
+ m_enable_lookups(false),
+ m_materializer(NULL),
+ m_decl_map(decl_map)
+ {
+ }
+
+ Target *
+ GetTarget()
+ {
+ if (m_exe_ctx.GetTargetPtr())
+ return m_exe_ctx.GetTargetPtr();
+ else if (m_sym_ctx.target_sp)
+ m_sym_ctx.target_sp.get();
+ return NULL;
+ }
+
+ ExecutionContext m_exe_ctx; ///< The execution context to use when parsing.
+ SymbolContext m_sym_ctx; ///< The symbol context to use in finding variables and types.
+ ClangPersistentVariables *m_persistent_vars; ///< The persistent variables for the process.
+ bool m_enable_lookups; ///< Set to true during parsing if we have found the first "$__lldb" name.
+ TargetInfo m_target_info; ///< Basic information about the target.
+ Materializer *m_materializer; ///< If non-NULL, the materializer to use when reporting used variables.
+ private:
+ ClangExpressionDeclMap &m_decl_map;
+ DISALLOW_COPY_AND_ASSIGN (ParserVars);
+ };
+
+ std::unique_ptr<ParserVars> m_parser_vars;
+
+ //----------------------------------------------------------------------
+ /// Activate parser-specific variables
+ //----------------------------------------------------------------------
+ void
+ EnableParserVars()
+ {
+ if (!m_parser_vars.get())
+ m_parser_vars.reset(new ParserVars(*this));
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate parser-specific variables
+ //----------------------------------------------------------------------
+ void
+ DisableParserVars()
+ {
+ m_parser_vars.reset();
+ }
+
+ //----------------------------------------------------------------------
+ /// The following values contain layout information for the materialized
+ /// struct, but are not specific to a single materialization
+ //----------------------------------------------------------------------
+ struct StructVars {
+ StructVars() :
+ m_struct_alignment(0),
+ m_struct_size(0),
+ m_struct_laid_out(false),
+ m_result_name(),
+ m_object_pointer_type(NULL, NULL)
+ {
+ }
+
+ off_t m_struct_alignment; ///< The alignment of the struct in bytes.
+ size_t m_struct_size; ///< The size of the struct in bytes.
+ bool m_struct_laid_out; ///< True if the struct has been laid out and the layout is valid (that is, no new fields have been added since).
+ ConstString m_result_name; ///< The name of the result variable ($1, for example)
+ TypeFromUser m_object_pointer_type; ///< The type of the "this" variable, if one exists
+ };
+
+ std::unique_ptr<StructVars> m_struct_vars;
+
+ //----------------------------------------------------------------------
+ /// Activate struct variables
+ //----------------------------------------------------------------------
+ void
+ EnableStructVars()
+ {
+ if (!m_struct_vars.get())
+ m_struct_vars.reset(new struct StructVars);
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate struct variables
+ //----------------------------------------------------------------------
+ void
+ DisableStructVars()
+ {
+ m_struct_vars.reset();
+ }
+
+ //----------------------------------------------------------------------
+ /// Get this parser's ID for use in extracting parser- and JIT-specific
+ /// data from persistent variables.
+ //----------------------------------------------------------------------
+ uint64_t
+ GetParserID()
+ {
+ return (uint64_t)this;
+ }
+
+ //------------------------------------------------------------------
+ /// Given a target, find a data symbol that has the given name.
+ ///
+ /// @param[in] target
+ /// The target to use as the basis for the search.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string.
+ ///
+ /// @return
+ /// The LLDB Symbol found, or NULL if none was found.
+ //---------------------------------------------------------
+ const Symbol *
+ FindGlobalDataSymbol (Target &target,
+ const ConstString &name);
+
+ //------------------------------------------------------------------
+ /// Given a target, find a variable that matches the given name and
+ /// type.
+ ///
+ /// @param[in] target
+ /// The target to use as a basis for finding the variable.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to search.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string.
+ ///
+ /// @param[in] namespace_decl
+ /// If non-NULL and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] type
+ /// The required type for the variable. This function may be called
+ /// during parsing, in which case we don't know its type; hence the
+ /// default.
+ ///
+ /// @return
+ /// The LLDB Variable found, or NULL if none was found.
+ //------------------------------------------------------------------
+ lldb::VariableSP
+ FindGlobalVariable (Target &target,
+ lldb::ModuleSP &module,
+ const ConstString &name,
+ ClangNamespaceDecl *namespace_decl,
+ TypeFromUser *type = NULL);
+
+ //------------------------------------------------------------------
+ /// Get the value of a variable in a given execution context and return
+ /// the associated Types if needed.
+ ///
+ /// @param[in] var
+ /// The variable to evaluate.
+ ///
+ /// @param[out] var_location
+ /// The variable location value to fill in
+ ///
+ /// @param[out] found_type
+ /// The type of the found value, as it was found in the user process.
+ /// This is only useful when the variable is being inspected on behalf
+ /// of the parser, hence the default.
+ ///
+ /// @param[out] parser_type
+ /// The type of the found value, as it was copied into the parser's
+ /// AST context. This is only useful when the variable is being
+ /// inspected on behalf of the parser, hence the default.
+ ///
+ /// @param[in] decl
+ /// The Decl to be looked up.
+ ///
+ /// @return
+ /// Return true if the value was successfully filled in.
+ //------------------------------------------------------------------
+ bool
+ GetVariableValue (lldb::VariableSP &var,
+ lldb_private::Value &var_location,
+ TypeFromUser *found_type = NULL,
+ TypeFromParser *parser_type = NULL);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given LLDB
+ /// Variable, and put it in the Tuple list.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] var
+ /// The LLDB Variable that needs a Decl.
+ ///
+ /// @param[in] valobj
+ /// The LLDB ValueObject for that variable.
+ //------------------------------------------------------------------
+ void
+ AddOneVariable (NameSearchContext &context,
+ lldb::VariableSP var,
+ lldb::ValueObjectSP valobj,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// persistent variable, and put it in the list of found entities.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] pvar
+ /// The persistent variable that needs a Decl.
+ ///
+ /// @param[in] current_id
+ /// The ID of the current invocation of FindExternalVisibleDecls
+ /// for logging purposes.
+ //------------------------------------------------------------------
+ void
+ AddOneVariable (NameSearchContext &context,
+ lldb::ClangExpressionVariableSP &pvar_sp,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given LLDB
+ /// symbol (treated as a variable), and put it in the list of found
+ /// entities.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] var
+ /// The LLDB Variable that needs a Decl.
+ //------------------------------------------------------------------
+ void
+ AddOneGenericVariable (NameSearchContext &context,
+ const Symbol &symbol,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// function. (Functions are not placed in the Tuple list.) Can
+ /// handle both fully typed functions and generic functions.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] fun
+ /// The Function that needs to be created. If non-NULL, this is
+ /// a fully-typed function.
+ ///
+ /// @param[in] sym
+ /// The Symbol that corresponds to a function that needs to be
+ /// created with generic type (unitptr_t foo(...)).
+ //------------------------------------------------------------------
+ void
+ AddOneFunction (NameSearchContext &context,
+ Function *fun,
+ Symbol *sym,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// register.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] reg_info
+ /// The information corresponding to that register.
+ //------------------------------------------------------------------
+ void
+ AddOneRegister (NameSearchContext &context,
+ const RegisterInfo *reg_info,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// type. (Types are not placed in the Tuple list.)
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] type
+ /// The type that needs to be created.
+ //------------------------------------------------------------------
+ void
+ AddOneType (NameSearchContext &context,
+ TypeFromUser &type,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Copy a C++ class type into the parser's AST context and add a
+ /// member function declaration to it for the expression.
+ ///
+ /// @param[in] type
+ /// The type that needs to be created.
+ //------------------------------------------------------------------
+
+ TypeFromParser
+ CopyClassType(TypeFromUser &type,
+ unsigned int current_id);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangExpressionDeclMap_h_
diff --git a/include/lldb/Expression/ClangExpressionParser.h b/include/lldb/Expression/ClangExpressionParser.h
new file mode 100644
index 000000000000..3247f2094ba6
--- /dev/null
+++ b/include/lldb/Expression/ClangExpressionParser.h
@@ -0,0 +1,151 @@
+//===-- ClangExpressionParser.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangExpressionParser_h_
+#define liblldb_ClangExpressionParser_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/IRForTarget.h"
+
+#include <string>
+#include <vector>
+
+namespace lldb_private
+{
+
+class IRExecutionUnit;
+
+//----------------------------------------------------------------------
+/// @class ClangExpressionParser ClangExpressionParser.h "lldb/Expression/ClangExpressionParser.h"
+/// @brief Encapsulates an instance of Clang that can parse expressions.
+///
+/// ClangExpressionParser is responsible for preparing an instance of
+/// ClangExpression for execution. ClangExpressionParser uses ClangExpression
+/// as a glorified parameter list, performing the required parsing and
+/// conversion to formats (DWARF bytecode, or JIT compiled machine code)
+/// that can be executed.
+//----------------------------------------------------------------------
+class ClangExpressionParser
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variabes.
+ ///
+ /// @param[in] exe_scope,
+ /// If non-NULL, an execution context scope that can help to
+ /// correctly create an expression with a valid process for
+ /// optional tuning Objective-C runtime support. Can be NULL.
+ ///
+ /// @param[in] expr
+ /// The expression to be parsed.
+ //------------------------------------------------------------------
+ ClangExpressionParser (ExecutionContextScope *exe_scope,
+ ClangExpression &expr);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangExpressionParser ();
+
+ //------------------------------------------------------------------
+ /// Parse a single expression and convert it to IR using Clang. Don't
+ /// wrap the expression in anything at all.
+ ///
+ /// @param[in] stream
+ /// The stream to print errors to.
+ ///
+ /// @return
+ /// The number of errors encountered during parsing. 0 means
+ /// success.
+ //------------------------------------------------------------------
+ unsigned
+ Parse (Stream &stream);
+
+ //------------------------------------------------------------------
+ /// Ready an already-parsed expression for execution, possibly
+ /// evaluating it statically.
+ ///
+ /// @param[out] func_addr
+ /// The address to which the function has been written.
+ ///
+ /// @param[out] func_end
+ /// The end of the function's allocated memory region. (func_addr
+ /// and func_end do not delimit an allocated region; the allocated
+ /// region may begin before func_addr.)
+ ///
+ /// @param[in] execution_unit_ap
+ /// After parsing, ownership of the execution unit for
+ /// for the expression is handed to this unique pointer.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to write the function into.
+ ///
+ /// @param[out] evaluated_statically
+ /// Set to true if the expression could be interpreted statically;
+ /// untouched otherwise.
+ ///
+ /// @param[out] const_result
+ /// If the result of the expression is constant, and the
+ /// expression has no side effects, this is set to the result of the
+ /// expression.
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether the expression must be JIT-compiled, must be
+ /// evaluated statically, or whether this decision may be made
+ /// opportunistically.
+ ///
+ /// @return
+ /// An error code indicating the success or failure of the operation.
+ /// Test with Success().
+ //------------------------------------------------------------------
+ Error
+ PrepareForExecution (lldb::addr_t &func_addr,
+ lldb::addr_t &func_end,
+ std::unique_ptr<IRExecutionUnit> &execution_unit_ap,
+ ExecutionContext &exe_ctx,
+ bool &can_interpret,
+ lldb_private::ExecutionPolicy execution_policy);
+
+ //------------------------------------------------------------------
+ /// Disassemble the machine code for a JITted function from the target
+ /// process's memory and print the result to a stream.
+ ///
+ /// @param[in] stream
+ /// The stream to print disassembly to.
+ ///
+ /// @param[in] exc_context
+ /// The execution context to get the machine code from.
+ ///
+ /// @return
+ /// The error generated. If .Success() is true, disassembly succeeded.
+ //------------------------------------------------------------------
+ Error
+ DisassembleFunction (Stream &stream,
+ ExecutionContext &exe_ctx);
+
+private:
+ ClangExpression & m_expr; ///< The expression to be parsed
+ std::unique_ptr<llvm::LLVMContext> m_llvm_context; ///< The LLVM context to generate IR into
+ std::unique_ptr<clang::FileManager> m_file_manager; ///< The Clang file manager object used by the compiler
+ std::unique_ptr<clang::CompilerInstance> m_compiler; ///< The Clang compiler used to parse expressions into IR
+ std::unique_ptr<clang::Builtin::Context> m_builtin_context; ///< Context for Clang built-ins
+ std::unique_ptr<clang::SelectorTable> m_selector_table; ///< Selector table for Objective-C methods
+ std::unique_ptr<clang::ASTContext> m_ast_context; ///< The AST context used to hold types and names for the parser
+ std::unique_ptr<clang::CodeGenerator> m_code_generator; ///< The Clang object that generates IR
+ std::unique_ptr<IRExecutionUnit> m_execution_unit; ///< The container for the finished Module
+};
+
+}
+
+#endif // liblldb_ClangExpressionParser_h_
diff --git a/include/lldb/Expression/ClangExpressionVariable.h b/include/lldb/Expression/ClangExpressionVariable.h
new file mode 100644
index 000000000000..620e604fb18c
--- /dev/null
+++ b/include/lldb/Expression/ClangExpressionVariable.h
@@ -0,0 +1,451 @@
+//===-- ClangExpressionVariable.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangExpressionVariable_h_
+#define liblldb_ClangExpressionVariable_h_
+
+// C Includes
+#include <signal.h>
+#include <stdint.h>
+#include <string.h>
+
+// C++ Includes
+#include <map>
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Symbol/TaggedASTType.h"
+
+namespace llvm {
+ class Value;
+}
+
+namespace lldb_private {
+
+class ClangExpressionVariableList;
+class ValueObjectConstResult;
+
+//----------------------------------------------------------------------
+/// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
+/// @brief Encapsulates one variable for the expression parser.
+///
+/// The expression parser uses variables in three different contexts:
+///
+/// First, it stores persistent variables along with the process for use
+/// in expressions. These persistent variables contain their own data
+/// and are typed.
+///
+/// Second, in an interpreted expression, it stores the local variables
+/// for the expression along with the expression. These variables
+/// contain their own data and are typed.
+///
+/// Third, in a JIT-compiled expression, it stores the variables that
+/// the expression needs to have materialized and dematerialized at each
+/// execution. These do not contain their own data but are named and
+/// typed.
+///
+/// This class supports all of these use cases using simple type
+/// polymorphism, and provides necessary support methods. Its interface
+/// is RTTI-neutral.
+//----------------------------------------------------------------------
+class ClangExpressionVariable
+{
+public:
+ ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size);
+
+ ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);
+
+ //----------------------------------------------------------------------
+ /// If the variable contains its own data, make a Value point at it.
+ /// If \a exe_ctx in not NULL, the value will be resolved in with
+ /// that execution context.
+ ///
+ /// @param[in] value
+ /// The value to point at the data.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use to resolve \a value.
+ ///
+ /// @return
+ /// True on success; false otherwise (in particular, if this variable
+ /// does not contain its own data).
+ //----------------------------------------------------------------------
+ bool
+ PointValueAtData(Value &value, ExecutionContext *exe_ctx);
+
+ lldb::ValueObjectSP
+ GetValueObject();
+
+ //----------------------------------------------------------------------
+ /// The following values should not live beyond parsing
+ //----------------------------------------------------------------------
+ class ParserVars
+ {
+ public:
+
+ ParserVars() :
+ m_parser_type(),
+ m_named_decl (NULL),
+ m_llvm_value (NULL),
+ m_lldb_value (),
+ m_lldb_var (),
+ m_lldb_sym (NULL)
+ {
+ }
+
+ TypeFromParser m_parser_type; ///< The type of the variable according to the parser
+ const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable
+ llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue
+ lldb_private::Value m_lldb_value; ///< The value found in LLDB for this variable
+ lldb::VariableSP m_lldb_var; ///< The original variable for this variable
+ const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol
+ };
+
+private:
+ typedef std::map <uint64_t, ParserVars> ParserVarMap;
+ ParserVarMap m_parser_vars;
+
+public:
+ //----------------------------------------------------------------------
+ /// Make this variable usable by the parser by allocating space for
+ /// parser-specific variables
+ //----------------------------------------------------------------------
+ void
+ EnableParserVars(uint64_t parser_id)
+ {
+ m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate parser-specific variables
+ //----------------------------------------------------------------------
+ void
+ DisableParserVars(uint64_t parser_id)
+ {
+ m_parser_vars.erase(parser_id);
+ }
+
+ //----------------------------------------------------------------------
+ /// Access parser-specific variables
+ //----------------------------------------------------------------------
+ ParserVars *
+ GetParserVars(uint64_t parser_id)
+ {
+ ParserVarMap::iterator i = m_parser_vars.find(parser_id);
+
+ if (i == m_parser_vars.end())
+ return NULL;
+ else
+ return &i->second;
+ }
+
+ //----------------------------------------------------------------------
+ /// The following values are valid if the variable is used by JIT code
+ //----------------------------------------------------------------------
+ struct JITVars {
+ JITVars () :
+ m_alignment (0),
+ m_size (0),
+ m_offset (0)
+ {
+ }
+
+ off_t m_alignment; ///< The required alignment of the variable, in bytes
+ size_t m_size; ///< The space required for the variable, in bytes
+ off_t m_offset; ///< The offset of the variable in the struct, in bytes
+ };
+
+private:
+ typedef std::map <uint64_t, JITVars> JITVarMap;
+ JITVarMap m_jit_vars;
+
+public:
+ //----------------------------------------------------------------------
+ /// Make this variable usable for materializing for the JIT by allocating
+ /// space for JIT-specific variables
+ //----------------------------------------------------------------------
+ void
+ EnableJITVars(uint64_t parser_id)
+ {
+ m_jit_vars.insert(std::make_pair(parser_id, JITVars()));
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate JIT-specific variables
+ //----------------------------------------------------------------------
+ void
+ DisableJITVars(uint64_t parser_id)
+ {
+ m_jit_vars.erase(parser_id);
+ }
+
+ JITVars *GetJITVars(uint64_t parser_id)
+ {
+ JITVarMap::iterator i = m_jit_vars.find(parser_id);
+
+ if (i == m_jit_vars.end())
+ return NULL;
+ else
+ return &i->second;
+ }
+
+ //----------------------------------------------------------------------
+ /// Return the variable's size in bytes
+ //----------------------------------------------------------------------
+ size_t
+ GetByteSize ();
+
+ const ConstString &
+ GetName();
+
+ RegisterInfo *
+ GetRegisterInfo();
+
+ void
+ SetRegisterInfo (const RegisterInfo *reg_info);
+
+ ClangASTType
+ GetClangType ();
+
+ void
+ SetClangType (const ClangASTType &clang_type);
+
+ TypeFromUser
+ GetTypeFromUser ();
+
+ uint8_t *
+ GetValueBytes ();
+
+ void
+ SetName (const ConstString &name);
+
+ void
+ ValueUpdated ();
+
+ // this function is used to copy the address-of m_live_sp into m_frozen_sp
+ // this is necessary because the results of certain cast and pointer-arithmetic
+ // operations (such as those described in bugzilla issues 11588 and 11618) generate
+ // frozen objcts that do not have a valid address-of, which can be troublesome when
+ // using synthetic children providers. transferring the address-of the live object
+ // solves these issues and provides the expected user-level behavior
+ void
+ TransferAddress (bool force = false);
+
+ typedef std::shared_ptr<ValueObjectConstResult> ValueObjectConstResultSP;
+
+ //----------------------------------------------------------------------
+ /// Members
+ //----------------------------------------------------------------------
+ enum Flags
+ {
+ EVNone = 0,
+ EVIsLLDBAllocated = 1 << 0, ///< This variable is resident in a location specifically allocated for it by LLDB in the target process
+ EVIsProgramReference = 1 << 1, ///< This variable is a reference to a (possibly invalid) area managed by the target program
+ EVNeedsAllocation = 1 << 2, ///< Space for this variable has yet to be allocated in the target process
+ EVIsFreezeDried = 1 << 3, ///< This variable's authoritative version is in m_frozen_sp (for example, for statically-computed results)
+ EVNeedsFreezeDry = 1 << 4, ///< Copy from m_live_sp to m_frozen_sp during dematerialization
+ EVKeepInTarget = 1 << 5, ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it
+ EVTypeIsReference = 1 << 6, ///< The original type of this variable is a reference, so materialize the value rather than the location
+ EVUnknownType = 1 << 7, ///< This is a symbol of unknown type, and the type must be resolved after parsing is complete
+ EVBareRegister = 1 << 8 ///< This variable is a direct reference to $pc or some other entity.
+ };
+
+ typedef uint16_t FlagType;
+
+ FlagType m_flags; // takes elements of Flags
+
+ lldb::ValueObjectSP m_frozen_sp;
+ lldb::ValueObjectSP m_live_sp;
+
+ DISALLOW_COPY_AND_ASSIGN (ClangExpressionVariable);
+};
+
+//----------------------------------------------------------------------
+/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
+/// @brief A list of variable references.
+///
+/// This class stores variables internally, acting as the permanent store.
+//----------------------------------------------------------------------
+class ClangExpressionVariableList
+{
+public:
+ //----------------------------------------------------------------------
+ /// Implementation of methods in ClangExpressionVariableListBase
+ //----------------------------------------------------------------------
+ size_t
+ GetSize()
+ {
+ return m_variables.size();
+ }
+
+ lldb::ClangExpressionVariableSP
+ GetVariableAtIndex(size_t index)
+ {
+ lldb::ClangExpressionVariableSP var_sp;
+ if (index < m_variables.size())
+ var_sp = m_variables[index];
+ return var_sp;
+ }
+
+ size_t
+ AddVariable (const lldb::ClangExpressionVariableSP &var_sp)
+ {
+ m_variables.push_back(var_sp);
+ return m_variables.size() - 1;
+ }
+
+ bool
+ ContainsVariable (const lldb::ClangExpressionVariableSP &var_sp)
+ {
+ const size_t size = m_variables.size();
+ for (size_t index = 0; index < size; ++index)
+ {
+ if (m_variables[index].get() == var_sp.get())
+ return true;
+ }
+ return false;
+ }
+
+ //----------------------------------------------------------------------
+ /// Finds a variable by name in the list.
+ ///
+ /// @param[in] name
+ /// The name of the requested variable.
+ ///
+ /// @return
+ /// The variable requested, or NULL if that variable is not in the list.
+ //----------------------------------------------------------------------
+ lldb::ClangExpressionVariableSP
+ GetVariable (const ConstString &name)
+ {
+ lldb::ClangExpressionVariableSP var_sp;
+ for (size_t index = 0, size = GetSize(); index < size; ++index)
+ {
+ var_sp = GetVariableAtIndex(index);
+ if (var_sp->GetName() == name)
+ return var_sp;
+ }
+ var_sp.reset();
+ return var_sp;
+ }
+
+ lldb::ClangExpressionVariableSP
+ GetVariable (const char *name)
+ {
+ lldb::ClangExpressionVariableSP var_sp;
+ if (name && name[0])
+ {
+ for (size_t index = 0, size = GetSize(); index < size; ++index)
+ {
+ var_sp = GetVariableAtIndex(index);
+ const char *var_name_cstr = var_sp->GetName().GetCString();
+ if (!var_name_cstr || !name)
+ continue;
+ if (::strcmp (var_name_cstr, name) == 0)
+ return var_sp;
+ }
+ var_sp.reset();
+ }
+ return var_sp;
+ }
+
+ //----------------------------------------------------------------------
+ /// Finds a variable by NamedDecl in the list.
+ ///
+ /// @param[in] name
+ /// The name of the requested variable.
+ ///
+ /// @return
+ /// The variable requested, or NULL if that variable is not in the list.
+ //----------------------------------------------------------------------
+ lldb::ClangExpressionVariableSP
+ GetVariable (const clang::NamedDecl *decl, uint64_t parser_id)
+ {
+ lldb::ClangExpressionVariableSP var_sp;
+ for (size_t index = 0, size = GetSize(); index < size; ++index)
+ {
+ var_sp = GetVariableAtIndex(index);
+
+ ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(parser_id);
+
+ if (parser_vars && parser_vars->m_named_decl == decl)
+ return var_sp;
+ }
+ var_sp.reset();
+ return var_sp;
+ }
+
+ //----------------------------------------------------------------------
+ /// Create a new variable in the list and return its index
+ //----------------------------------------------------------------------
+ lldb::ClangExpressionVariableSP
+ CreateVariable (ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size)
+ {
+ lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
+ m_variables.push_back(var_sp);
+ return var_sp;
+ }
+
+ lldb::ClangExpressionVariableSP
+ CreateVariable(const lldb::ValueObjectSP &valobj_sp)
+ {
+ lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(valobj_sp));
+ m_variables.push_back(var_sp);
+ return var_sp;
+ }
+
+ lldb::ClangExpressionVariableSP
+ CreateVariable (ExecutionContextScope *exe_scope,
+ const ConstString &name,
+ const TypeFromUser& user_type,
+ lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size)
+ {
+ lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
+ var_sp->SetName (name);
+ var_sp->SetClangType (user_type);
+ m_variables.push_back(var_sp);
+ return var_sp;
+ }
+
+ void
+ RemoveVariable (lldb::ClangExpressionVariableSP var_sp)
+ {
+ for (std::vector<lldb::ClangExpressionVariableSP>::iterator vi = m_variables.begin(), ve = m_variables.end();
+ vi != ve;
+ ++vi)
+ {
+ if (vi->get() == var_sp.get())
+ {
+ m_variables.erase(vi);
+ return;
+ }
+ }
+ }
+
+ void
+ Clear()
+ {
+ m_variables.clear();
+ }
+
+private:
+ std::vector <lldb::ClangExpressionVariableSP> m_variables;
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangExpressionVariable_h_
diff --git a/include/lldb/Expression/ClangFunction.h b/include/lldb/Expression/ClangFunction.h
new file mode 100644
index 000000000000..3f96f7bd3117
--- /dev/null
+++ b/include/lldb/Expression/ClangFunction.h
@@ -0,0 +1,652 @@
+//===-- ClangFunction.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_ClangFunction_h_
+#define lldb_ClangFunction_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+#include <list>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Target/Process.h"
+
+namespace lldb_private
+{
+
+class ASTStructExtractor;
+class ClangExpressionParser;
+
+//----------------------------------------------------------------------
+/// @class ClangFunction ClangFunction.h "lldb/Expression/ClangFunction.h"
+/// @brief Encapsulates a function that can be called.
+///
+/// A given ClangFunction object can handle a single function signature.
+/// Once constructed, it can set up any number of concurrent calls to
+/// functions with that signature.
+///
+/// It performs the call by synthesizing a structure that contains the pointer
+/// to the function and the arguments that should be passed to that function,
+/// and producing a special-purpose JIT-compiled function that accepts a void*
+/// pointing to this struct as its only argument and calls the function in the
+/// struct with the written arguments. This method lets Clang handle the
+/// vagaries of function calling conventions.
+///
+/// The simplest use of the ClangFunction is to construct it with a
+/// function representative of the signature you want to use, then call
+/// ExecuteFunction(ExecutionContext &, Stream &, Value &).
+///
+/// If you need to reuse the arguments for several calls, you can call
+/// InsertFunction() followed by WriteFunctionArguments(), which will return
+/// the location of the args struct for the wrapper function in args_addr_ref.
+///
+/// If you need to call the function on the thread plan stack, you can also
+/// call InsertFunction() followed by GetThreadPlanToCallFunction().
+///
+/// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed
+/// a pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated
+/// and its address returned in that variable.
+///
+/// Any of the methods that take arg_addr_ptr can be passed NULL, and the
+/// argument space will be managed for you.
+//----------------------------------------------------------------------
+class ClangFunction : public ClangExpression
+{
+ friend class ASTStructExtractor;
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] exe_scope
+ /// An execution context scope that gets us at least a target and
+ /// process.
+ ///
+ /// @param[in] function_ptr
+ /// The default function to be called. Can be overridden using
+ /// WriteFunctionArguments().
+ ///
+ /// @param[in] ast_context
+ /// The AST context to evaluate argument types in.
+ ///
+ /// @param[in] arg_value_list
+ /// The default values to use when calling this function. Can
+ /// be overridden using WriteFunctionArguments().
+ //------------------------------------------------------------------
+ ClangFunction (ExecutionContextScope &exe_scope,
+ Function &function_ptr,
+ ClangASTContext *ast_context,
+ const ValueList &arg_value_list);
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] exe_scope
+ /// An execution context scope that gets us at least a target and
+ /// process.
+ ///
+ /// @param[in] ast_context
+ /// The AST context to evaluate argument types in.
+ ///
+ /// @param[in] return_qualtype
+ /// An opaque Clang QualType for the function result. Should be
+ /// defined in ast_context.
+ ///
+ /// @param[in] function_address
+ /// The address of the function to call.
+ ///
+ /// @param[in] arg_value_list
+ /// The default values to use when calling this function. Can
+ /// be overridden using WriteFunctionArguments().
+ //------------------------------------------------------------------
+ ClangFunction (ExecutionContextScope &exe_scope,
+ const ClangASTType &return_type,
+ const Address& function_address,
+ const ValueList &arg_value_list);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual
+ ~ClangFunction();
+
+ //------------------------------------------------------------------
+ /// Compile the wrapper function
+ ///
+ /// @param[in] errors
+ /// The stream to print parser errors to.
+ ///
+ /// @return
+ /// The number of errors.
+ //------------------------------------------------------------------
+ unsigned
+ CompileFunction (Stream &errors);
+
+ //------------------------------------------------------------------
+ /// Insert the default function wrapper and its default argument struct
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to insert the function and its arguments
+ /// into.
+ ///
+ /// @param[in,out] args_addr_ref
+ /// The address of the structure to write the arguments into. May
+ /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
+ /// and args_addr_ref is pointed to it.
+ ///
+ /// @param[in] errors
+ /// The stream to write errors to.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ InsertFunction (ExecutionContext &exe_ctx,
+ lldb::addr_t &args_addr_ref,
+ Stream &errors);
+
+ //------------------------------------------------------------------
+ /// Insert the default function wrapper (using the JIT)
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to insert the function and its arguments
+ /// into.
+ ///
+ /// @param[in] errors
+ /// The stream to write errors to.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool WriteFunctionWrapper (ExecutionContext &exe_ctx,
+ Stream &errors);
+
+ //------------------------------------------------------------------
+ /// Insert the default function argument struct
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to insert the function and its arguments
+ /// into.
+ ///
+ /// @param[in,out] args_addr_ref
+ /// The address of the structure to write the arguments into. May
+ /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
+ /// and args_addr_ref is pointed to it.
+ ///
+ /// @param[in] errors
+ /// The stream to write errors to.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool WriteFunctionArguments (ExecutionContext &exe_ctx,
+ lldb::addr_t &args_addr_ref,
+ Stream &errors);
+
+ //------------------------------------------------------------------
+ /// Insert an argument struct with a non-default function address and
+ /// non-default argument values
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to insert the function and its arguments
+ /// into.
+ ///
+ /// @param[in,out] args_addr_ref
+ /// The address of the structure to write the arguments into. May
+ /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
+ /// and args_addr_ref is pointed to it.
+ ///
+ /// @param[in] function_address
+ /// The address of the function to call.
+ ///
+ /// @param[in] arg_values
+ /// The values of the function's arguments.
+ ///
+ /// @param[in] errors
+ /// The stream to write errors to.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool WriteFunctionArguments (ExecutionContext &exe_ctx,
+ lldb::addr_t &args_addr_ref,
+ Address function_address,
+ ValueList &arg_values,
+ Stream &errors);
+
+ //------------------------------------------------------------------
+ /// [Static] Execute a function, passing it a single void* parameter.
+ /// ClangFunction uses this to call the wrapper function.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to insert the function and its arguments
+ /// into.
+ ///
+ /// @param[in] function_address
+ /// The address of the function in the target process.
+ ///
+ /// @param[in] void_arg
+ /// The value of the void* parameter.
+ ///
+ /// @param[in] stop_others
+ /// True if other threads should pause during execution.
+ ///
+ /// @param[in] try_all_threads
+ /// If the timeout expires, true if other threads should run. If
+ /// the function may try to take locks, this is useful.
+ ///
+ /// @param[in] unwind_on_error
+ /// If true, and the execution stops before completion, we unwind the
+ /// function call, and return the program state to what it was before the
+ /// execution. If false, we leave the program in the stopped state.
+ ///
+ /// @param[in] timeout_usec
+ /// Timeout value (0 for no timeout). If try_all_threads is true, then we
+ /// will try on one thread for the lesser of .25 sec and half the total timeout.
+ /// then switch to running all threads, otherwise this will be the total timeout.
+ ///
+ /// @param[in] errors
+ /// The stream to write errors to.
+ ///
+ /// @param[in] this_arg
+ /// If non-NULL, the function is invoked like a C++ method, with the
+ /// value pointed to by the pointer as its 'this' argument.
+ ///
+ /// @return
+ /// Returns one of the ExecutionResults enum indicating function call status.
+ //------------------------------------------------------------------
+ static ExecutionResults
+ ExecuteFunction (ExecutionContext &exe_ctx,
+ lldb::addr_t function_address,
+ lldb::addr_t &void_arg,
+ bool stop_others,
+ bool try_all_threads,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
+ uint32_t timeout_usec,
+ Stream &errors,
+ lldb::addr_t* this_arg = 0);
+
+ //------------------------------------------------------------------
+ /// Run the function this ClangFunction was created with.
+ ///
+ /// This simple version will run the function stopping other threads
+ /// for a fixed timeout period (1000 usec) and if it does not complete,
+ /// we halt the process and try with all threads running.
+ ///
+ /// @param[in] exe_ctx
+ /// The thread & process in which this function will run.
+ ///
+ /// @param[in] errors
+ /// Errors will be written here if there are any.
+ ///
+ /// @param[out] results
+ /// The result value will be put here after running the function.
+ ///
+ /// @return
+ /// Returns one of the ExecutionResults enum indicating function call status.
+ //------------------------------------------------------------------
+ ExecutionResults
+ ExecuteFunction(ExecutionContext &exe_ctx,
+ Stream &errors,
+ Value &results);
+
+ //------------------------------------------------------------------
+ /// Run the function this ClangFunction was created with.
+ ///
+ /// This simple version will run the function obeying the stop_others
+ /// argument. There is no timeout.
+ ///
+ /// @param[in] exe_ctx
+ /// The thread & process in which this function will run.
+ ///
+ /// @param[in] errors
+ /// Errors will be written here if there are any.
+ ///
+ /// @param[in] stop_others
+ /// If \b true, run only this thread, if \b false let all threads run.
+ ///
+ /// @param[out] results
+ /// The result value will be put here after running the function.
+ ///
+ /// @return
+ /// Returns one of the ExecutionResults enum indicating function call status.
+ //------------------------------------------------------------------
+ ExecutionResults
+ ExecuteFunction(ExecutionContext &exe_ctx,
+ Stream &errors, bool stop_others,
+ Value &results);
+
+ //------------------------------------------------------------------
+ /// Run the function this ClangFunction was created with.
+ ///
+ /// This simple version will run the function on one thread. If \a timeout_usec
+ /// is not zero, we time out after that timeout. If \a try_all_threads is true, then we will
+ /// resume with all threads on, otherwise we halt the process, and eExecutionInterrupted will be returned.
+ ///
+ /// @param[in] exe_ctx
+ /// The thread & process in which this function will run.
+ ///
+ /// @param[in] errors
+ /// Errors will be written here if there are any.
+ ///
+ /// @param[in] timeout_usec
+ /// Timeout value (0 for no timeout). If try_all_threads is true, then we
+ /// will try on one thread for the lesser of .25 sec and half the total timeout.
+ /// then switch to running all threads, otherwise this will be the total timeout.
+ ///
+ /// @param[in] try_all_threads
+ /// If \b true, run only this thread, if \b false let all threads run.
+ ///
+ /// @param[out] results
+ /// The result value will be put here after running the function.
+ ///
+ /// @return
+ /// Returns one of the ExecutionResults enum indicating function call status.
+ //------------------------------------------------------------------
+ ExecutionResults
+ ExecuteFunction(ExecutionContext &exe_ctx,
+ Stream &errors,
+ uint32_t single_thread_timeout_usec,
+ bool try_all_threads,
+ Value &results);
+
+ //------------------------------------------------------------------
+ /// Run the function this ClangFunction was created with.
+ ///
+ /// This is the full version.
+ ///
+ /// @param[in] exe_ctx
+ /// The thread & process in which this function will run.
+ ///
+ /// @param[in] args_addr_ptr
+ /// If NULL, the function will take care of allocating & deallocating the wrapper
+ /// args structure. Otherwise, if set to LLDB_INVALID_ADDRESS, a new structure
+ /// will be allocated, filled and the address returned to you. You are responsible
+ /// for deallocating it. And if passed in with a value other than LLDB_INVALID_ADDRESS,
+ /// this should point to an already allocated structure with the values already written.
+ ///
+ /// @param[in] errors
+ /// Errors will be written here if there are any.
+ ///
+ /// @param[in] stop_others
+ /// If \b true, run only this thread, if \b false let all threads run.
+ ///
+ /// @param[in] timeout_usec
+ /// Timeout value (0 for no timeout). If try_all_threads is true, then we
+ /// will try on one thread for the lesser of .25 sec and half the total timeout.
+ /// then switch to running all threads, otherwise this will be the total timeout.
+ ///
+ ///
+ /// @param[in] try_all_threads
+ /// If \b true, run only this thread, if \b false let all threads run.
+ ///
+ /// @param[out] results
+ /// The result value will be put here after running the function.
+ ///
+ /// @return
+ /// Returns one of the ExecutionResults enum indicating function call status.
+ //------------------------------------------------------------------
+ ExecutionResults
+ ExecuteFunction(ExecutionContext &exe_ctx,
+ lldb::addr_t *args_addr_ptr,
+ Stream &errors,
+ bool stop_others,
+ uint32_t timeout_usec,
+ bool try_all_threads,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
+ Value &results);
+
+ //------------------------------------------------------------------
+ /// [static] Get a thread plan to run a function.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to insert the function and its arguments
+ /// into.
+ ///
+ /// @param[in] func_addr
+ /// The address of the function in the target process.
+ ///
+ /// @param[in] args_addr_ref
+ /// The value of the void* parameter.
+ ///
+ /// @param[in] errors
+ /// The stream to write errors to.
+ ///
+ /// @param[in] stop_others
+ /// True if other threads should pause during execution.
+ ///
+ /// @param[in] unwind_on_error
+ /// True if the thread plan may simply be discarded if an error occurs.
+ ///
+ /// @param[in] ignore_breakpoints
+ /// True if the expression execution will ignore breakpoint hits and continue executing.
+ ///
+ /// @param[in] this_arg
+ /// If non-NULL (and cmd_arg is NULL), the function is invoked like a C++
+ /// method, with the value pointed to by the pointer as its 'this'
+ /// argument.
+ ///
+ /// @param[in] cmd_arg
+ /// If non-NULL, the function is invoked like an Objective-C method, with
+ /// this_arg in the 'self' slot and cmd_arg in the '_cmd' slot
+ ///
+ /// @return
+ /// A ThreadPlan for executing the function.
+ //------------------------------------------------------------------
+ static ThreadPlan *
+ GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
+ lldb::addr_t func_addr,
+ lldb::addr_t &args_addr_ref,
+ Stream &errors,
+ bool stop_others,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
+ lldb::addr_t *this_arg = 0,
+ lldb::addr_t *cmd_arg = 0);
+
+ //------------------------------------------------------------------
+ /// Get a thread plan to run the function this ClangFunction was created with.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to insert the function and its arguments
+ /// into.
+ ///
+ /// @param[in] func_addr
+ /// The address of the function in the target process.
+ ///
+ /// @param[in] args_addr_ref
+ /// The value of the void* parameter.
+ ///
+ /// @param[in] errors
+ /// The stream to write errors to.
+ ///
+ /// @param[in] stop_others
+ /// True if other threads should pause during execution.
+ ///
+ /// @param[in] unwind_on_error
+ /// True if the thread plan may simply be discarded if an error occurs.
+ ///
+ /// @return
+ /// A ThreadPlan for executing the function.
+ //------------------------------------------------------------------
+ ThreadPlan *
+ GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
+ lldb::addr_t &args_addr_ref,
+ Stream &errors,
+ bool stop_others,
+ bool unwind_on_error = true,
+ bool ignore_breakpoints = true)
+ {
+ return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
+ m_jit_start_addr,
+ args_addr_ref,
+ errors,
+ stop_others,
+ unwind_on_error,
+ ignore_breakpoints);
+ }
+
+ //------------------------------------------------------------------
+ /// Get the result of the function from its struct
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to retrieve the result from.
+ ///
+ /// @param[in] args_addr
+ /// The address of the argument struct.
+ ///
+ /// @param[in] ret_value
+ /// The value returned by the function.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool FetchFunctionResults (ExecutionContext &exe_ctx,
+ lldb::addr_t args_addr,
+ Value &ret_value);
+
+ //------------------------------------------------------------------
+ /// Deallocate the arguments structure
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to insert the function and its arguments
+ /// into.
+ ///
+ /// @param[in] args_addr
+ /// The address of the argument struct.
+ //------------------------------------------------------------------
+ void DeallocateFunctionResults (ExecutionContext &exe_ctx,
+ lldb::addr_t args_addr);
+
+ //------------------------------------------------------------------
+ /// Interface for ClangExpression
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Return the string that the parser should parse. Must be a full
+ /// translation unit.
+ //------------------------------------------------------------------
+ const char *
+ Text ()
+ {
+ return m_wrapper_function_text.c_str();
+ }
+
+ //------------------------------------------------------------------
+ /// Return the function name that should be used for executing the
+ /// expression. Text() should contain the definition of this
+ /// function.
+ //------------------------------------------------------------------
+ const char *
+ FunctionName ()
+ {
+ return m_wrapper_function_name.c_str();
+ }
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
+ //------------------------------------------------------------------
+ ClangExpressionDeclMap *
+ DeclMap ()
+ {
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when registering
+ /// local variables. May be NULL if the Expression doesn't care.
+ //------------------------------------------------------------------
+ ClangExpressionVariableList *
+ LocalVariables ()
+ {
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ clang::ASTConsumer *
+ ASTTransformer (clang::ASTConsumer *passthrough);
+
+ //------------------------------------------------------------------
+ /// Return true if validation code should be inserted into the
+ /// expression.
+ //------------------------------------------------------------------
+ bool
+ NeedsValidation ()
+ {
+ return false;
+ }
+
+ //------------------------------------------------------------------
+ /// Return true if external variables in the expression should be
+ /// resolved.
+ //------------------------------------------------------------------
+ bool
+ NeedsVariableResolution ()
+ {
+ return false;
+ }
+
+ ValueList
+ GetArgumentValues () const
+ {
+ return m_arg_values;
+ }
+private:
+ //------------------------------------------------------------------
+ // For ClangFunction only
+ //------------------------------------------------------------------
+
+ std::unique_ptr<ClangExpressionParser> m_parser; ///< The parser responsible for compiling the function.
+ std::unique_ptr<IRExecutionUnit> m_execution_unit_ap;
+
+ Function *m_function_ptr; ///< The function we're going to call. May be NULL if we don't have debug info for the function.
+ Address m_function_addr; ///< If we don't have the FunctionSP, we at least need the address & return type.
+ ClangASTType m_function_return_type; ///< The opaque clang qual type for the function return type.
+ ClangASTContext *m_clang_ast_context; ///< This is the clang_ast_context that we're getting types from the and value, and the function return the function pointer is NULL.
+
+ std::string m_wrapper_function_name; ///< The name of the wrapper function.
+ std::string m_wrapper_function_text; ///< The contents of the wrapper function.
+ std::string m_wrapper_struct_name; ///< The name of the struct that contains the target function address, arguments, and result.
+ std::list<lldb::addr_t> m_wrapper_args_addrs; ///< The addresses of the arguments to the wrapper function.
+
+ bool m_struct_valid; ///< True if the ASTStructExtractor has populated the variables below.
+
+ //------------------------------------------------------------------
+ /// These values are populated by the ASTStructExtractor
+ size_t m_struct_size; ///< The size of the argument struct, in bytes.
+ std::vector<uint64_t> m_member_offsets; ///< The offset of each member in the struct, in bytes.
+ uint64_t m_return_size; ///< The size of the result variable, in bytes.
+ uint64_t m_return_offset; ///< The offset of the result variable in the struct, in bytes.
+ //------------------------------------------------------------------
+
+ ValueList m_arg_values; ///< The default values of the arguments.
+
+ bool m_compiled; ///< True if the wrapper function has already been parsed.
+ bool m_JITted; ///< True if the wrapper function has already been JIT-compiled.
+};
+
+} // Namespace lldb_private
+
+#endif // lldb_ClangFunction_h_
diff --git a/include/lldb/Expression/ClangPersistentVariables.h b/include/lldb/Expression/ClangPersistentVariables.h
new file mode 100644
index 000000000000..6d9dae954734
--- /dev/null
+++ b/include/lldb/Expression/ClangPersistentVariables.h
@@ -0,0 +1,75 @@
+//===-- ClangPersistentVariables.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangPersistentVariables_h_
+#define liblldb_ClangPersistentVariables_h_
+
+#include "lldb/Expression/ClangExpressionVariable.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class ClangPersistentVariables ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h"
+/// @brief Manages persistent values that need to be preserved between expression invocations.
+///
+/// A list of variables that can be accessed and updated by any expression. See
+/// ClangPersistentVariable for more discussion. Also provides an increasing,
+/// 0-based counter for naming result variables.
+//----------------------------------------------------------------------
+class ClangPersistentVariables : public ClangExpressionVariableList
+{
+public:
+
+ //----------------------------------------------------------------------
+ /// Constructor
+ //----------------------------------------------------------------------
+ ClangPersistentVariables ();
+
+ lldb::ClangExpressionVariableSP
+ CreatePersistentVariable (const lldb::ValueObjectSP &valobj_sp);
+
+ lldb::ClangExpressionVariableSP
+ CreatePersistentVariable (ExecutionContextScope *exe_scope,
+ const ConstString &name,
+ const TypeFromUser& user_type,
+ lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size);
+
+ //----------------------------------------------------------------------
+ /// Return the next entry in the sequence of strings "$0", "$1", ... for
+ /// use naming persistent expression convenience variables.
+ ///
+ /// @return
+ /// A string that contains the next persistent variable name.
+ //----------------------------------------------------------------------
+ ConstString
+ GetNextPersistentVariableName ();
+
+ void
+ RemovePersistentVariable (lldb::ClangExpressionVariableSP variable);
+
+ void
+ RegisterPersistentType (const ConstString &name,
+ clang::TypeDecl *tag_decl);
+
+ clang::TypeDecl *
+ GetPersistentType (const ConstString &name);
+
+private:
+ uint32_t m_next_persistent_variable_id; ///< The counter used by GetNextResultName().
+
+ typedef llvm::DenseMap<const char *, clang::TypeDecl *> PersistentTypeMap;
+ PersistentTypeMap m_persistent_types; ///< The persistent types declared by the user.
+};
+
+}
+
+#endif
diff --git a/include/lldb/Expression/ClangUserExpression.h b/include/lldb/Expression/ClangUserExpression.h
new file mode 100644
index 000000000000..47bfebb46648
--- /dev/null
+++ b/include/lldb/Expression/ClangUserExpression.h
@@ -0,0 +1,432 @@
+//===-- ClangUserExpression.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangUserExpression_h_
+#define liblldb_ClangUserExpression_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangExpressionVariable.h"
+#include "lldb/Expression/IRForTarget.h"
+#include "lldb/Expression/Materializer.h"
+#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/Target/ExecutionContext.h"
+
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class ClangUserExpression ClangUserExpression.h "lldb/Expression/ClangUserExpression.h"
+/// @brief Encapsulates a single expression for use with Clang
+///
+/// LLDB uses expressions for various purposes, notably to call functions
+/// and as a backend for the expr command. ClangUserExpression encapsulates
+/// the objects needed to parse and interpret or JIT an expression. It
+/// uses the Clang parser to produce LLVM IR from the expression.
+//----------------------------------------------------------------------
+class ClangUserExpression : public ClangExpression
+{
+public:
+ typedef std::shared_ptr<ClangUserExpression> ClangUserExpressionSP;
+
+ enum { kDefaultTimeout = 500000u };
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] expr
+ /// The expression to parse.
+ ///
+ /// @param[in] expr_prefix
+ /// If non-NULL, a C string containing translation-unit level
+ /// definitions to be included when the expression is parsed.
+ ///
+ /// @param[in] language
+ /// If not eLanguageTypeUnknown, a language to use when parsing
+ /// the expression. Currently restricted to those languages
+ /// supported by Clang.
+ ///
+ /// @param[in] desired_type
+ /// If not eResultTypeAny, the type to use for the expression
+ /// result.
+ //------------------------------------------------------------------
+ ClangUserExpression (const char *expr,
+ const char *expr_prefix,
+ lldb::LanguageType language,
+ ResultType desired_type);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual
+ ~ClangUserExpression ();
+
+ //------------------------------------------------------------------
+ /// Parse the expression
+ ///
+ /// @param[in] error_stream
+ /// A stream to print parse errors and warnings to.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when looking up entities that
+ /// are needed for parsing (locations of functions, types of
+ /// variables, persistent variables, etc.)
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether interpretation is possible or mandatory.
+ ///
+ /// @param[in] keep_result_in_memory
+ /// True if the resulting persistent variable should reside in
+ /// target memory, if applicable.
+ ///
+ /// @return
+ /// True on success (no errors); false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Parse (Stream &error_stream,
+ ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ bool keep_result_in_memory);
+
+ bool
+ CanInterpret ()
+ {
+ return m_can_interpret;
+ }
+
+ bool
+ MatchesContext (ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Execute the parsed expression
+ ///
+ /// @param[in] error_stream
+ /// A stream to print errors to.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when looking up entities that
+ /// are needed for parsing (locations of variables, etc.)
+ ///
+ /// @param[in] unwind_on_error
+ /// If true, and the execution stops before completion, we unwind the
+ /// function call, and return the program state to what it was before the
+ /// execution. If false, we leave the program in the stopped state.
+ ///
+ /// @param[in] ignore_breakpoints
+ /// If true, ignore breakpoints while executing the expression.
+ ///
+ /// @param[in] shared_ptr_to_me
+ /// This is a shared pointer to this ClangUserExpression. This is
+ /// needed because Execute can push a thread plan that will hold onto
+ /// the ClangUserExpression for an unbounded period of time. So you
+ /// need to give the thread plan a reference to this object that can
+ /// keep it alive.
+ ///
+ /// @param[in] result
+ /// A pointer to direct at the persistent variable in which the
+ /// expression's result is stored.
+ ///
+ /// @param[in] try_all_threads
+ /// If true, then we will try to run all threads if the function doesn't complete on
+ /// one thread. See timeout_usec for the interaction of this variable and
+ /// the timeout.
+ ///
+ /// @param[in] timeout_usec
+ /// Timeout value (0 for no timeout). If try_all_threads is true, then we
+ /// will try on one thread for the lesser of .25 sec and half the total timeout.
+ /// then switch to running all threads, otherwise this will be the total timeout.
+ ///
+ ///
+ /// @return
+ /// A Process::Execution results value.
+ //------------------------------------------------------------------
+ ExecutionResults
+ Execute (Stream &error_stream,
+ ExecutionContext &exe_ctx,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
+ ClangUserExpressionSP &shared_ptr_to_me,
+ lldb::ClangExpressionVariableSP &result,
+ bool try_all_threads,
+ uint32_t timeout_usec);
+
+ ThreadPlan *
+ GetThreadPlanToExecuteJITExpression (Stream &error_stream,
+ ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Apply the side effects of the function to program state.
+ ///
+ /// @param[in] error_stream
+ /// A stream to print errors to.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when looking up entities that
+ /// are needed for parsing (locations of variables, etc.)
+ ///
+ /// @param[in] result
+ /// A pointer to direct at the persistent variable in which the
+ /// expression's result is stored.
+ ///
+ /// @param[in] function_stack_pointer
+ /// A pointer to the base of the function's stack frame. This
+ /// is used to determine whether the expession result resides in
+ /// memory that will still be valid, or whether it needs to be
+ /// treated as homeless for the purpose of future expressions.
+ ///
+ /// @return
+ /// A Process::Execution results value.
+ //------------------------------------------------------------------
+ bool
+ FinalizeJITExecution (Stream &error_stream,
+ ExecutionContext &exe_ctx,
+ lldb::ClangExpressionVariableSP &result,
+ lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
+ lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS);
+
+ //------------------------------------------------------------------
+ /// Return the string that the parser should parse. Must be a full
+ /// translation unit.
+ //------------------------------------------------------------------
+ const char *
+ Text ()
+ {
+ return m_transformed_text.c_str();
+ }
+
+ //------------------------------------------------------------------
+ /// Return the string that the user typed.
+ //------------------------------------------------------------------
+ const char *
+ GetUserText ()
+ {
+ return m_expr_text.c_str();
+ }
+
+ //------------------------------------------------------------------
+ /// Return the function name that should be used for executing the
+ /// expression. Text() should contain the definition of this
+ /// function.
+ //------------------------------------------------------------------
+ const char *
+ FunctionName ()
+ {
+ return "$__lldb_expr";
+ }
+
+ //------------------------------------------------------------------
+ /// Return the language that should be used when parsing. To use
+ /// the default, return eLanguageTypeUnknown.
+ //------------------------------------------------------------------
+ virtual lldb::LanguageType
+ Language ()
+ {
+ return m_language;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
+ //------------------------------------------------------------------
+ ClangExpressionDeclMap *
+ DeclMap ()
+ {
+ return m_expr_decl_map.get();
+ }
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ clang::ASTConsumer *
+ ASTTransformer (clang::ASTConsumer *passthrough);
+
+ //------------------------------------------------------------------
+ /// Return the desired result type of the function, or
+ /// eResultTypeAny if indifferent.
+ //------------------------------------------------------------------
+ virtual ResultType
+ DesiredResultType ()
+ {
+ return m_desired_type;
+ }
+
+ //------------------------------------------------------------------
+ /// Return true if validation code should be inserted into the
+ /// expression.
+ //------------------------------------------------------------------
+ bool
+ NeedsValidation ()
+ {
+ return true;
+ }
+
+ //------------------------------------------------------------------
+ /// Return true if external variables in the expression should be
+ /// resolved.
+ //------------------------------------------------------------------
+ bool
+ NeedsVariableResolution ()
+ {
+ return true;
+ }
+
+ //------------------------------------------------------------------
+ /// Evaluate one expression and return its result.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when evaluating the expression.
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether or not to try using the IR interpreter to
+ /// avoid running the expression on the parser.
+ ///
+ /// @param[in] language
+ /// If not eLanguageTypeUnknown, a language to use when parsing
+ /// the expression. Currently restricted to those languages
+ /// supported by Clang.
+ ///
+ /// @param[in] unwind_on_error
+ /// True if the thread's state should be restored in the case
+ /// of an error.
+ ///
+ /// @param[in] ignore_breakpoints
+ /// If true, ignore breakpoints while executing the expression.
+ ///
+ /// @param[in] result_type
+ /// If not eResultTypeAny, the type of the desired result. Will
+ /// result in parse errors if impossible.
+ ///
+ /// @param[in] expr_cstr
+ /// A C string containing the expression to be evaluated.
+ ///
+ /// @param[in] expr_prefix
+ /// If non-NULL, a C string containing translation-unit level
+ /// definitions to be included when the expression is parsed.
+ ///
+ /// @param[in/out] result_valobj_sp
+ /// If execution is successful, the result valobj is placed here.
+ ///
+ /// @param[in] try_all_threads
+ /// If true, then we will try to run all threads if the function doesn't complete on
+ /// one thread. See timeout_usec for the interaction of this variable and
+ /// the timeout.
+ ///
+ /// @param[in] timeout_usec
+ /// Timeout value (0 for no timeout). If try_all_threads is true, then we
+ /// will try on one thread for the lesser of .25 sec and half the total timeout.
+ /// then switch to running all threads, otherwise this will be the total timeout.
+ ///
+ /// @result
+ /// A Process::ExecutionResults value. eExecutionCompleted for success.
+ //------------------------------------------------------------------
+ static ExecutionResults
+ Evaluate (ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ lldb::LanguageType language,
+ ResultType desired_type,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
+ const char *expr_cstr,
+ const char *expr_prefix,
+ lldb::ValueObjectSP &result_valobj_sp,
+ bool try_all_threads,
+ uint32_t timeout_usec);
+
+ static ExecutionResults
+ EvaluateWithError (ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ lldb::LanguageType language,
+ ResultType desired_type,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
+ const char *expr_cstr,
+ const char *expr_prefix,
+ lldb::ValueObjectSP &result_valobj_sp,
+ Error &error,
+ bool try_all_threads,
+ uint32_t timeout_usec);
+
+ static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression.
+private:
+ //------------------------------------------------------------------
+ /// Populate m_cplusplus and m_objetivec based on the environment.
+ //------------------------------------------------------------------
+
+ void
+ ScanContext (ExecutionContext &exe_ctx,
+ lldb_private::Error &err);
+
+ bool
+ PrepareToExecuteJITExpression (Stream &error_stream,
+ ExecutionContext &exe_ctx,
+ lldb::addr_t &struct_address,
+ lldb::addr_t &object_ptr,
+ lldb::addr_t &cmd_ptr);
+
+ void
+ InstallContext (ExecutionContext &exe_ctx);
+
+ bool
+ LockAndCheckContext (ExecutionContext &exe_ctx,
+ lldb::TargetSP &target_sp,
+ lldb::ProcessSP &process_sp,
+ lldb::StackFrameSP &frame_sp);
+
+ lldb::ProcessWP m_process_wp; ///< The process used as the context for the expression.
+ Address m_address; ///< The address the process is stopped in.
+ lldb::addr_t m_stack_frame_bottom; ///< The bottom of the allocated stack frame.
+ lldb::addr_t m_stack_frame_top; ///< The top of the allocated stack frame.
+
+ std::string m_expr_text; ///< The text of the expression, as typed by the user
+ std::string m_expr_prefix; ///< The text of the translation-level definitions, as provided by the user
+ lldb::LanguageType m_language; ///< The language to use when parsing (eLanguageTypeUnknown means use defaults)
+ bool m_allow_cxx; ///< True if the language allows C++.
+ bool m_allow_objc; ///< True if the language allows Objective-C.
+ std::string m_transformed_text; ///< The text of the expression, as send to the parser
+ ResultType m_desired_type; ///< The type to coerce the expression's result to. If eResultTypeAny, inferred from the expression.
+
+ std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map; ///< The map to use when parsing the expression.
+ std::unique_ptr<IRExecutionUnit> m_execution_unit_ap; ///< The execution unit the expression is stored in.
+ std::unique_ptr<Materializer> m_materializer_ap; ///< The materializer to use when running the expression.
+ std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer; ///< The result synthesizer, if one is needed.
+
+ bool m_enforce_valid_object; ///< True if the expression parser should enforce the presence of a valid class pointer in order to generate the expression as a method.
+ bool m_cplusplus; ///< True if the expression is compiled as a C++ member function (true if it was parsed when exe_ctx was in a C++ method).
+ bool m_objectivec; ///< True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was in an Objective-C method).
+ bool m_static_method; ///< True if the expression is compiled as a static (or class) method (currently true if it was parsed when exe_ctx was in an Objective-C class method).
+ bool m_needs_object_ptr; ///< True if "this" or "self" must be looked up and passed in. False if the expression doesn't really use them and they can be NULL.
+ bool m_const_object; ///< True if "this" is const.
+ Target *m_target; ///< The target for storing persistent data like types and variables.
+
+ bool m_can_interpret; ///< True if the expression could be evaluated statically; false otherwise.
+ lldb::addr_t m_materialized_address; ///< The address at which the arguments to the expression have been materialized.
+ Materializer::DematerializerSP m_dematerializer_sp; ///< The dematerializer.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangUserExpression_h_
diff --git a/include/lldb/Expression/ClangUtilityFunction.h b/include/lldb/Expression/ClangUtilityFunction.h
new file mode 100644
index 000000000000..6da8e5ec3a8b
--- /dev/null
+++ b/include/lldb/Expression/ClangUtilityFunction.h
@@ -0,0 +1,179 @@
+//===-- ClangUtilityFunction.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangUtilityFunction_h_
+#define liblldb_ClangUtilityFunction_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Expression/ClangExpression.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class ClangUtilityFunction ClangUtilityFunction.h "lldb/Expression/ClangUtilityFunction.h"
+/// @brief Encapsulates a single expression for use with Clang
+///
+/// LLDB uses expressions for various purposes, notably to call functions
+/// and as a backend for the expr command. ClangUtilityFunction encapsulates
+/// a self-contained function meant to be used from other code. Utility
+/// functions can perform error-checking for ClangUserExpressions,
+//----------------------------------------------------------------------
+class ClangUtilityFunction : public ClangExpression
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] text
+ /// The text of the function. Must be a full translation unit.
+ ///
+ /// @param[in] name
+ /// The name of the function, as used in the text.
+ //------------------------------------------------------------------
+ ClangUtilityFunction (const char *text,
+ const char *name);
+
+ virtual
+ ~ClangUtilityFunction ();
+
+ //------------------------------------------------------------------
+ /// Install the utility function into a process
+ ///
+ /// @param[in] error_stream
+ /// A stream to print parse errors and warnings to.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to install the utility function to.
+ ///
+ /// @return
+ /// True on success (no errors); false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Install (Stream &error_stream, ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Check whether the given PC is inside the function
+ ///
+ /// Especially useful if the function dereferences NULL to indicate a failed
+ /// assert.
+ ///
+ /// @param[in] pc
+ /// The program counter to check.
+ ///
+ /// @return
+ /// True if the program counter falls within the function's bounds;
+ /// false if not (or the function is not JIT compiled)
+ //------------------------------------------------------------------
+ bool
+ ContainsAddress (lldb::addr_t address)
+ {
+ // nothing is both >= LLDB_INVALID_ADDRESS and < LLDB_INVALID_ADDRESS,
+ // so this always returns false if the function is not JIT compiled yet
+ return (address >= m_jit_start_addr && address < m_jit_end_addr);
+ }
+
+
+ //------------------------------------------------------------------
+ /// Return the string that the parser should parse. Must be a full
+ /// translation unit.
+ //------------------------------------------------------------------
+ const char *
+ Text ()
+ {
+ return m_function_text.c_str();
+ }
+
+ //------------------------------------------------------------------
+ /// Return the function name that should be used for executing the
+ /// expression. Text() should contain the definition of this
+ /// function.
+ //------------------------------------------------------------------
+ const char *
+ FunctionName ()
+ {
+ return m_function_name.c_str();
+ }
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
+ //------------------------------------------------------------------
+ ClangExpressionDeclMap *
+ DeclMap ()
+ {
+ return m_expr_decl_map.get();
+ }
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when registering
+ /// local variables. May be NULL if the Expression doesn't care.
+ //------------------------------------------------------------------
+ ClangExpressionVariableList *
+ LocalVariables ()
+ {
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ clang::ASTConsumer *
+ ASTTransformer (clang::ASTConsumer *passthrough)
+ {
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Return true if validation code should be inserted into the
+ /// expression.
+ //------------------------------------------------------------------
+ bool
+ NeedsValidation ()
+ {
+ return false;
+ }
+
+ //------------------------------------------------------------------
+ /// Return true if external variables in the expression should be
+ /// resolved.
+ //------------------------------------------------------------------
+ bool
+ NeedsVariableResolution ()
+ {
+ return false;
+ }
+
+private:
+ std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map; ///< The map to use when parsing and materializing the expression.
+ std::unique_ptr<IRExecutionUnit> m_execution_unit_ap;
+
+ std::string m_function_text; ///< The text of the function. Must be a well-formed translation unit.
+ std::string m_function_name; ///< The name of the function.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangUtilityFunction_h_
diff --git a/include/lldb/Expression/DWARFExpression.h b/include/lldb/Expression/DWARFExpression.h
new file mode 100644
index 000000000000..2692831ecc84
--- /dev/null
+++ b/include/lldb/Expression/DWARFExpression.h
@@ -0,0 +1,424 @@
+//===-- DWARFExpression.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFExpression_h_
+#define liblldb_DWARFExpression_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Scalar.h"
+
+namespace lldb_private {
+
+class ClangExpressionVariable;
+class ClangExpressionVariableList;
+
+class ClangExpressionDeclMap;
+
+//----------------------------------------------------------------------
+/// @class DWARFExpression DWARFExpression.h "lldb/Expression/DWARFExpression.h"
+/// @brief Encapsulates a DWARF location expression and interprets it.
+///
+/// DWARF location expressions are used in two ways by LLDB. The first
+/// use is to find entities specified in the debug information, since
+/// their locations are specified in precisely this language. The second
+/// is to interpret expressions without having to run the target in cases
+/// where the overhead from copying JIT-compiled code into the target is
+/// too high or where the target cannot be run. This class encapsulates
+/// a single DWARF location expression or a location list and interprets
+/// it.
+//----------------------------------------------------------------------
+class DWARFExpression
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ //------------------------------------------------------------------
+ DWARFExpression();
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] data
+ /// A data extractor configured to read the DWARF location expression's
+ /// bytecode.
+ ///
+ /// @param[in] data_offset
+ /// The offset of the location expression in the extractor.
+ ///
+ /// @param[in] data_length
+ /// The byte length of the location expression.
+ //------------------------------------------------------------------
+ DWARFExpression(const DataExtractor& data,
+ lldb::offset_t data_offset,
+ lldb::offset_t data_length);
+
+ //------------------------------------------------------------------
+ /// Copy constructor
+ //------------------------------------------------------------------
+ DWARFExpression(const DWARFExpression& rhs);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual
+ ~DWARFExpression();
+
+ //------------------------------------------------------------------
+ /// Print the description of the expression to a stream
+ ///
+ /// @param[in] s
+ /// The stream to print to.
+ ///
+ /// @param[in] level
+ /// The level of verbosity to use.
+ ///
+ /// @param[in] location_list_base_addr
+ /// If this is a location list based expression, this is the
+ /// address of the object that owns it. NOTE: this value is
+ /// different from the DWARF version of the location list base
+ /// address which is compile unit relative. This base address
+ /// is the address of the object that owns the location list.
+ ///
+ /// @param[in] abi
+ /// An optional ABI plug-in that can be used to resolve register
+ /// names.
+ //------------------------------------------------------------------
+ void
+ GetDescription (Stream *s,
+ lldb::DescriptionLevel level,
+ lldb::addr_t location_list_base_addr,
+ ABI *abi) const;
+
+ //------------------------------------------------------------------
+ /// Return true if the location expression contains data
+ //------------------------------------------------------------------
+ bool
+ IsValid() const;
+
+ //------------------------------------------------------------------
+ /// Return true if a location list was provided
+ //------------------------------------------------------------------
+ bool
+ IsLocationList() const;
+
+ //------------------------------------------------------------------
+ /// Search for a load address in the location list
+ ///
+ /// @param[in] process
+ /// The process to use when resolving the load address
+ ///
+ /// @param[in] addr
+ /// The address to resolve
+ ///
+ /// @return
+ /// True if IsLocationList() is true and the address was found;
+ /// false otherwise.
+ //------------------------------------------------------------------
+// bool
+// LocationListContainsLoadAddress (Process* process, const Address &addr) const;
+//
+ bool
+ LocationListContainsAddress (lldb::addr_t loclist_base_addr, lldb::addr_t addr) const;
+
+ //------------------------------------------------------------------
+ /// If a location is not a location list, return true if the location
+ /// contains a DW_OP_addr () opcode in the stream that matches \a
+ /// file_addr. If file_addr is LLDB_INVALID_ADDRESS, the this
+ /// function will return true if the variable there is any DW_OP_addr
+ /// in a location that (yet still is NOT a location list). This helps
+ /// us detect if a variable is a global or static variable since
+ /// there is no other indication from DWARF debug info.
+ ///
+ /// @param[in] op_addr_idx
+ /// The DW_OP_addr index to retrieve in case there is more than
+ /// one DW_OP_addr opcode in the location byte stream.
+ ///
+ /// @param[out] error
+ /// If the location stream contains unknown DW_OP opcodes or the
+ /// data is missing, \a error will be set to \b true.
+ ///
+ /// @return
+ /// LLDB_INVALID_ADDRESS if the location doesn't contain a
+ /// DW_OP_addr for \a op_addr_idx, otherwise a valid file address
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const;
+
+ bool
+ Update_DW_OP_addr (lldb::addr_t file_addr);
+
+ //------------------------------------------------------------------
+ /// Make the expression parser read its location information from a
+ /// given data source. Does not change the offset and length
+ ///
+ /// @param[in] data
+ /// A data extractor configured to read the DWARF location expression's
+ /// bytecode.
+ //------------------------------------------------------------------
+ void
+ SetOpcodeData(const DataExtractor& data);
+
+ //------------------------------------------------------------------
+ /// Make the expression parser read its location information from a
+ /// given data source
+ ///
+ /// @param[in] data
+ /// A data extractor configured to read the DWARF location expression's
+ /// bytecode.
+ ///
+ /// @param[in] data_offset
+ /// The offset of the location expression in the extractor.
+ ///
+ /// @param[in] data_length
+ /// The byte length of the location expression.
+ //------------------------------------------------------------------
+ void
+ SetOpcodeData(const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length);
+
+ //------------------------------------------------------------------
+ /// Copy the DWARF location expression into a local buffer.
+ ///
+ /// It is a good idea to copy the data so we don't keep the entire
+ /// object file worth of data around just for a few bytes of location
+ /// expression. LLDB typically will mmap the entire contents of debug
+ /// information files, and if we use SetOpcodeData, it will get a
+ /// shared reference to all of this data for the and cause the object
+ /// file to have to stay around. Even worse, a very very large ".a"
+ /// that contains one or more .o files could end up being referenced.
+ /// Location lists are typically small so even though we are copying
+ /// the data, it shouldn't amount to that much for the variables we
+ /// end up parsing.
+ ///
+ /// @param[in] data
+ /// A data extractor configured to read and copy the DWARF
+ /// location expression's bytecode.
+ ///
+ /// @param[in] data_offset
+ /// The offset of the location expression in the extractor.
+ ///
+ /// @param[in] data_length
+ /// The byte length of the location expression.
+ //------------------------------------------------------------------
+ void
+ CopyOpcodeData (const DataExtractor& data,
+ lldb::offset_t data_offset,
+ lldb::offset_t data_length);
+
+
+ //------------------------------------------------------------------
+ /// Tells the expression that it refers to a location list.
+ ///
+ /// @param[in] slide
+ /// This value should be a slide that is applied to any values
+ /// in the location list data so the values become zero based
+ /// offsets into the object that owns the location list. We need
+ /// to make location lists relative to the objects that own them
+ /// so we can relink addresses on the fly.
+ //------------------------------------------------------------------
+ void
+ SetLocationListSlide (lldb::addr_t slide);
+
+ //------------------------------------------------------------------
+ /// Return the call-frame-info style register kind
+ //------------------------------------------------------------------
+ int
+ GetRegisterKind ();
+
+ //------------------------------------------------------------------
+ /// Set the call-frame-info style register kind
+ ///
+ /// @param[in] reg_kind
+ /// The register kind.
+ //------------------------------------------------------------------
+ void
+ SetRegisterKind (lldb::RegisterKind reg_kind);
+
+ //------------------------------------------------------------------
+ /// Wrapper for the static evaluate function that accepts an
+ /// ExecutionContextScope instead of an ExecutionContext and uses
+ /// member variables to populate many operands
+ //------------------------------------------------------------------
+ bool
+ Evaluate (ExecutionContextScope *exe_scope,
+ ClangExpressionVariableList *expr_locals,
+ ClangExpressionDeclMap *decl_map,
+ lldb::addr_t loclist_base_load_addr,
+ const Value* initial_value_ptr,
+ Value& result,
+ Error *error_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Wrapper for the static evaluate function that uses member
+ /// variables to populate many operands
+ //------------------------------------------------------------------
+ bool
+ Evaluate (ExecutionContext *exe_ctx,
+ ClangExpressionVariableList *expr_locals,
+ ClangExpressionDeclMap *decl_map,
+ RegisterContext *reg_ctx,
+ lldb::addr_t loclist_base_load_addr,
+ const Value* initial_value_ptr,
+ Value& result,
+ Error *error_ptr) const;
+
+ //------------------------------------------------------------------
+ /// Evaluate a DWARF location expression in a particular context
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context in which to evaluate the location
+ /// expression. The location expression may access the target's
+ /// memory, especially if it comes from the expression parser.
+ ///
+ /// @param[in] opcodes
+ /// This is a static method so the opcodes need to be provided
+ /// explicitly.
+ ///
+ /// @param[in] expr_locals
+ /// If the location expression was produced by the expression parser,
+ /// the list of local variables referenced by the DWARF expression.
+ /// This list should already have been populated during parsing;
+ /// the DWARF expression refers to variables by index. Can be NULL if
+ /// the location expression uses no locals.
+ ///
+ /// @param[in] decl_map
+ /// If the location expression was produced by the expression parser,
+ /// the list of external variables referenced by the location
+ /// expression. Can be NULL if the location expression uses no
+ /// external variables.
+ ///
+ /// @param[in] reg_ctx
+ /// An optional parameter which provides a RegisterContext for use
+ /// when evaluating the expression (i.e. for fetching register values).
+ /// Normally this will come from the ExecutionContext's StackFrame but
+ /// in the case where an expression needs to be evaluated while building
+ /// the stack frame list, this short-cut is available.
+ ///
+ /// @param[in] offset
+ /// The offset of the location expression in the data extractor.
+ ///
+ /// @param[in] length
+ /// The length in bytes of the location expression.
+ ///
+ /// @param[in] reg_set
+ /// The call-frame-info style register kind.
+ ///
+ /// @param[in] initial_value_ptr
+ /// A value to put on top of the interpreter stack before evaluating
+ /// the expression, if the expression is parametrized. Can be NULL.
+ ///
+ /// @param[in] result
+ /// A value into which the result of evaluating the expression is
+ /// to be placed.
+ ///
+ /// @param[in] error_ptr
+ /// If non-NULL, used to report errors in expression evaluation.
+ ///
+ /// @return
+ /// True on success; false otherwise. If error_ptr is non-NULL,
+ /// details of the failure are provided through it.
+ //------------------------------------------------------------------
+ static bool
+ Evaluate (ExecutionContext *exe_ctx,
+ ClangExpressionVariableList *expr_locals,
+ ClangExpressionDeclMap *decl_map,
+ RegisterContext *reg_ctx,
+ const DataExtractor& opcodes,
+ const lldb::offset_t offset,
+ const lldb::offset_t length,
+ const uint32_t reg_set,
+ const Value* initial_value_ptr,
+ Value& result,
+ Error *error_ptr);
+
+ //------------------------------------------------------------------
+ /// Loads a ClangExpressionVariableList into the object
+ ///
+ /// @param[in] locals
+ /// If non-NULL, the list of locals used by this expression.
+ /// See Evaluate().
+ //------------------------------------------------------------------
+ void
+ SetExpressionLocalVariableList (ClangExpressionVariableList *locals);
+
+ //------------------------------------------------------------------
+ /// Loads a ClangExpressionDeclMap into the object
+ ///
+ /// @param[in] locals
+ /// If non-NULL, the list of external variables used by this
+ /// expression. See Evaluate().
+ //------------------------------------------------------------------
+ void
+ SetExpressionDeclMap (ClangExpressionDeclMap *decl_map);
+
+ bool
+ GetExpressionData (DataExtractor &data) const
+ {
+ data = m_data;
+ return data.GetByteSize() > 0;
+ }
+
+ bool
+ DumpLocationForAddress (Stream *s,
+ lldb::DescriptionLevel level,
+ lldb::addr_t loclist_base_load_addr,
+ lldb::addr_t address,
+ ABI *abi);
+
+protected:
+ //------------------------------------------------------------------
+ /// Pretty-prints the location expression to a stream
+ ///
+ /// @param[in] stream
+ /// The stream to use for pretty-printing.
+ ///
+ /// @param[in] offset
+ /// The offset into the data buffer of the opcodes to be printed.
+ ///
+ /// @param[in] length
+ /// The length in bytes of the opcodes to be printed.
+ ///
+ /// @param[in] level
+ /// The level of detail to use in pretty-printing.
+ ///
+ /// @param[in] abi
+ /// An optional ABI plug-in that can be used to resolve register
+ /// names.
+ //------------------------------------------------------------------
+ void
+ DumpLocation(Stream *s,
+ lldb::offset_t offset,
+ lldb::offset_t length,
+ lldb::DescriptionLevel level,
+ ABI *abi) const;
+
+ bool
+ GetLocation (lldb::addr_t base_addr,
+ lldb::addr_t pc,
+ lldb::offset_t &offset,
+ lldb::offset_t &len);
+
+ //------------------------------------------------------------------
+ /// Classes that inherit from DWARFExpression can see and modify these
+ //------------------------------------------------------------------
+
+ DataExtractor m_data; ///< A data extractor capable of reading opcode bytes
+ lldb::RegisterKind m_reg_kind; ///< One of the defines that starts with LLDB_REGKIND_
+ lldb::addr_t m_loclist_slide; ///< A value used to slide the location list offsets so that
+ ///< they are relative to the object that owns the location list
+ ///< (the function for frame base and variable location lists)
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_DWARFExpression_h_
diff --git a/include/lldb/Expression/ExpressionSourceCode.h b/include/lldb/Expression/ExpressionSourceCode.h
new file mode 100644
index 000000000000..be1014ae3047
--- /dev/null
+++ b/include/lldb/Expression/ExpressionSourceCode.h
@@ -0,0 +1,78 @@
+//===-- ExpressionSourceCode.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ExpressionSourceCode_h
+#define liblldb_ExpressionSourceCode_h
+
+#include "lldb/lldb-enumerations.h"
+
+#include <string>
+
+namespace lldb_private
+{
+
+class ExpressionSourceCode
+{
+public:
+ static const char * g_expression_prefix;
+
+ static ExpressionSourceCode *CreateWrapped (const char *prefix,
+ const char *body)
+ {
+ return new ExpressionSourceCode ("$__lldb_expr",
+ prefix,
+ body,
+ true);
+ }
+
+ static ExpressionSourceCode *CreateUnwrapped (const char *name,
+ const char *body)
+ {
+ return new ExpressionSourceCode (name,
+ "",
+ body,
+ false);
+ }
+
+ bool NeedsWrapping () const
+ {
+ return m_wrap;
+ }
+
+ const char *GetName () const
+ {
+ return m_name.c_str();
+ }
+
+ bool GetText (std::string &text,
+ lldb::LanguageType wrapping_language,
+ bool const_object,
+ bool static_method) const;
+
+private:
+ ExpressionSourceCode (const char *name,
+ const char *prefix,
+ const char *body,
+ bool wrap) :
+ m_name(name),
+ m_prefix(prefix),
+ m_body(body),
+ m_wrap(wrap)
+ {
+ }
+
+ std::string m_name;
+ std::string m_prefix;
+ std::string m_body;
+ bool m_wrap;
+};
+
+} // namespace lldb_private
+
+#endif
diff --git a/include/lldb/Expression/IRDynamicChecks.h b/include/lldb/Expression/IRDynamicChecks.h
new file mode 100644
index 000000000000..226f5c94e98c
--- /dev/null
+++ b/include/lldb/Expression/IRDynamicChecks.h
@@ -0,0 +1,169 @@
+//===-- IRDynamicChecks.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_IRDynamicChecks_h_
+#define liblldb_IRDynamicChecks_h_
+
+#include "lldb/lldb-types.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ class BasicBlock;
+ class CallInst;
+ class Constant;
+ class Function;
+ class Instruction;
+ class Module;
+ class DataLayout;
+ class Value;
+}
+
+namespace lldb_private
+{
+
+class ClangExpressionDeclMap;
+class ClangUtilityFunction;
+class ExecutionContext;
+class Stream;
+
+//----------------------------------------------------------------------
+/// @class DynamicCheckerFunctions IRDynamicChecks.h "lldb/Expression/IRDynamicChecks.h"
+/// @brief Encapsulates dynamic check functions used by expressions.
+///
+/// Each of the utility functions encapsulated in this class is responsible
+/// for validating some data that an expression is about to use. Examples are:
+///
+/// a = *b; // check that b is a valid pointer
+/// [b init]; // check that b is a valid object to send "init" to
+///
+/// The class installs each checker function into the target process and
+/// makes it available to IRDynamicChecks to use.
+//----------------------------------------------------------------------
+class DynamicCheckerFunctions
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ //------------------------------------------------------------------
+ DynamicCheckerFunctions ();
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~DynamicCheckerFunctions ();
+
+ //------------------------------------------------------------------
+ /// Install the utility functions into a process. This binds the
+ /// instance of DynamicCheckerFunctions to that process.
+ ///
+ /// @param[in] error_stream
+ /// A stream to print errors on.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to install the functions into.
+ ///
+ /// @return
+ /// True on success; false on failure, or if the functions have
+ /// already been installed.
+ //------------------------------------------------------------------
+ bool Install (Stream &error_stream,
+ ExecutionContext &exe_ctx);
+
+ bool DoCheckersExplainStop (lldb::addr_t addr, Stream &message);
+
+ std::unique_ptr<ClangUtilityFunction> m_valid_pointer_check;
+ std::unique_ptr<ClangUtilityFunction> m_objc_object_check;
+};
+
+//----------------------------------------------------------------------
+/// @class IRDynamicChecks IRDynamicChecks.h "lldb/Expression/IRDynamicChecks.h"
+/// @brief Adds dynamic checks to a user-entered expression to reduce its likelihood of crashing
+///
+/// When an IR function is executed in the target process, it may cause
+/// crashes or hangs by dereferencing NULL pointers, trying to call Objective-C
+/// methods on objects that do not respond to them, and so forth.
+///
+/// IRDynamicChecks adds calls to the functions in DynamicCheckerFunctions
+/// to appropriate locations in an expression's IR.
+//----------------------------------------------------------------------
+class IRDynamicChecks : public llvm::ModulePass
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] checker_functions
+ /// The checker functions for the target process.
+ ///
+ /// @param[in] func_name
+ /// The name of the function to prepare for execution in the target.
+ ///
+ /// @param[in] decl_map
+ /// The mapping used to look up entities in the target process. In
+ /// this case, used to find objc_msgSend
+ //------------------------------------------------------------------
+ IRDynamicChecks (DynamicCheckerFunctions &checker_functions,
+ const char* func_name = "$__lldb_expr");
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual ~IRDynamicChecks();
+
+ //------------------------------------------------------------------
+ /// Run this IR transformer on a single module
+ ///
+ /// @param[in] M
+ /// The module to run on. This module is searched for the function
+ /// $__lldb_expr, and that function is passed to the passes one by
+ /// one.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool runOnModule(llvm::Module &M);
+
+ //------------------------------------------------------------------
+ /// Interface stub
+ //------------------------------------------------------------------
+ void assignPassManager(llvm::PMStack &PMS,
+ llvm::PassManagerType T = llvm::PMT_ModulePassManager);
+
+ //------------------------------------------------------------------
+ /// Returns PMT_ModulePassManager
+ //------------------------------------------------------------------
+ llvm::PassManagerType getPotentialPassManagerType() const;
+private:
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all pointer dereferences and
+ /// validate them before use.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] M
+ /// The module currently being processed.
+ ///
+ /// @param[in] BB
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool FindDataLoads(llvm::Module &M,
+ llvm::BasicBlock &BB);
+
+ std::string m_func_name; ///< The name of the function to add checks to
+ DynamicCheckerFunctions &m_checker_functions; ///< The checker functions for the process
+};
+
+}
+
+#endif
diff --git a/include/lldb/Expression/IRExecutionUnit.h b/include/lldb/Expression/IRExecutionUnit.h
new file mode 100644
index 000000000000..885b6516b0c6
--- /dev/null
+++ b/include/lldb/Expression/IRExecutionUnit.h
@@ -0,0 +1,495 @@
+//===-- IRExecutionUnit.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_IRExecutionUnit_h_
+#define lldb_IRExecutionUnit_h_
+
+// C Includes
+// C++ Includes
+#include <atomic>
+#include <string>
+#include <vector>
+#include <map>
+
+// Other libraries and framework includes
+#include "llvm/IR/Module.h"
+
+// Project includes
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangExpressionParser.h"
+#include "lldb/Expression/IRMemoryMap.h"
+#include "lldb/Host/Mutex.h"
+
+namespace llvm {
+
+class Module;
+class ExecutionEngine;
+
+}
+
+namespace lldb_private {
+
+class Error;
+
+//----------------------------------------------------------------------
+/// @class IRExecutionUnit IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
+/// @brief Contains the IR and, optionally, JIT-compiled code for a module.
+///
+/// This class encapsulates the compiled version of an expression, in IR
+/// form (for interpretation purposes) and in raw machine code form (for
+/// execution in the target).
+///
+/// This object wraps an IR module that comes from the expression parser,
+/// and knows how to use the JIT to make it into executable code. It can
+/// then be used as input to the IR interpreter, or the address of the
+/// executable code can be passed to a thread plan to run in the target.
+///
+/// This class creates a subclass of LLVM's JITMemoryManager, because that is
+/// how the JIT emits code. Because LLDB needs to move JIT-compiled code
+/// into the target process, the IRExecutionUnit knows how to copy the
+/// emitted code into the target process.
+//----------------------------------------------------------------------
+class IRExecutionUnit : public IRMemoryMap
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ //------------------------------------------------------------------
+ IRExecutionUnit (std::unique_ptr<llvm::LLVMContext> &context_ap,
+ std::unique_ptr<llvm::Module> &module_ap,
+ ConstString &name,
+ const lldb::TargetSP &target_sp,
+ std::vector<std::string> &cpu_features);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~IRExecutionUnit();
+
+ llvm::Module *GetModule()
+ {
+ return m_module;
+ }
+
+ llvm::Function *GetFunction()
+ {
+ if (m_module)
+ return m_module->getFunction (m_name.AsCString());
+ else
+ return NULL;
+ }
+
+ void GetRunnableInfo(Error &error,
+ lldb::addr_t &func_addr,
+ lldb::addr_t &func_end);
+
+ //------------------------------------------------------------------
+ /// Accessors for IRForTarget and other clients that may want binary
+ /// data placed on their behalf. The binary data is owned by the
+ /// IRExecutionUnit unless the client explicitly chooses to free it.
+ //------------------------------------------------------------------
+
+ lldb::addr_t WriteNow(const uint8_t *bytes,
+ size_t size,
+ Error &error);
+
+ void FreeNow(lldb::addr_t allocation);
+
+private:
+ //------------------------------------------------------------------
+ /// Look up the object in m_address_map that contains a given address,
+ /// find where it was copied to, and return the remote address at the
+ /// same offset into the copied entity
+ ///
+ /// @param[in] local_address
+ /// The address in the debugger.
+ ///
+ /// @return
+ /// The address in the target process.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetRemoteAddressForLocal (lldb::addr_t local_address);
+
+ //------------------------------------------------------------------
+ /// Look up the object in m_address_map that contains a given address,
+ /// find where it was copied to, and return its address range in the
+ /// target process
+ ///
+ /// @param[in] local_address
+ /// The address in the debugger.
+ ///
+ /// @return
+ /// The range of the containing object in the target process.
+ //------------------------------------------------------------------
+ typedef std::pair <lldb::addr_t, uintptr_t> AddrRange;
+ AddrRange
+ GetRemoteRangeForLocal (lldb::addr_t local_address);
+
+ //------------------------------------------------------------------
+ /// Commit all allocations to the process and record where they were stored.
+ ///
+ /// @param[in] process
+ /// The process to allocate memory in.
+ ///
+ /// @return
+ /// True <=> all allocations were performed successfully.
+ /// This method will attempt to free allocated memory if the
+ /// operation fails.
+ //------------------------------------------------------------------
+ bool
+ CommitAllocations (lldb::ProcessSP &process_sp);
+
+ //------------------------------------------------------------------
+ /// Report all committed allocations to the execution engine.
+ ///
+ /// @param[in] engine
+ /// The execution engine to notify.
+ //------------------------------------------------------------------
+ void
+ ReportAllocations (llvm::ExecutionEngine &engine);
+
+ //------------------------------------------------------------------
+ /// Write the contents of all allocations to the process.
+ ///
+ /// @param[in] local_address
+ /// The process containing the allocations.
+ ///
+ /// @return
+ /// True <=> all allocations were performed successfully.
+ //------------------------------------------------------------------
+ bool
+ WriteData (lldb::ProcessSP &process_sp);
+
+ Error
+ DisassembleFunction (Stream &stream,
+ lldb::ProcessSP &process_sp);
+
+ class MemoryManager : public llvm::JITMemoryManager
+ {
+ public:
+ MemoryManager (IRExecutionUnit &parent);
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual void setMemoryWritable ();
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual void setMemoryExecutable ();
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual void setPoisonMemory (bool poison)
+ {
+ m_default_mm_ap->setPoisonMemory (poison);
+ }
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual void AllocateGOT()
+ {
+ m_default_mm_ap->AllocateGOT();
+ }
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual uint8_t *getGOTBase() const
+ {
+ return m_default_mm_ap->getGOTBase();
+ }
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual uint8_t *startFunctionBody(const llvm::Function *F,
+ uintptr_t &ActualSize);
+
+ //------------------------------------------------------------------
+ /// Allocate room for a dyld stub for a lazy-referenced function,
+ /// and add it to the m_stubs map
+ ///
+ /// @param[in] F
+ /// The function being referenced.
+ ///
+ /// @param[in] StubSize
+ /// The size of the stub.
+ ///
+ /// @param[in] Alignment
+ /// The required alignment of the stub.
+ ///
+ /// @return
+ /// Allocated space for the stub.
+ //------------------------------------------------------------------
+ virtual uint8_t *allocateStub(const llvm::GlobalValue* F,
+ unsigned StubSize,
+ unsigned Alignment);
+
+ //------------------------------------------------------------------
+ /// Complete the body of a function, and add it to the m_functions map
+ ///
+ /// @param[in] F
+ /// The function being completed.
+ ///
+ /// @param[in] FunctionStart
+ /// The first instruction of the function.
+ ///
+ /// @param[in] FunctionEnd
+ /// The last byte of the last instruction of the function.
+ //------------------------------------------------------------------
+ virtual void endFunctionBody(const llvm::Function *F,
+ uint8_t *FunctionStart,
+ uint8_t *FunctionEnd);
+ //------------------------------------------------------------------
+ /// Allocate space for an unspecified purpose, and add it to the
+ /// m_spaceBlocks map
+ ///
+ /// @param[in] Size
+ /// The size of the area.
+ ///
+ /// @param[in] Alignment
+ /// The required alignment of the area.
+ ///
+ /// @return
+ /// Allocated space.
+ //------------------------------------------------------------------
+ virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
+
+ //------------------------------------------------------------------
+ /// Allocate space for executable code, and add it to the
+ /// m_spaceBlocks map
+ ///
+ /// @param[in] Size
+ /// The size of the area.
+ ///
+ /// @param[in] Alignment
+ /// The required alignment of the area.
+ ///
+ /// @param[in] SectionID
+ /// A unique identifier for the section.
+ ///
+ /// @return
+ /// Allocated space.
+ //------------------------------------------------------------------
+ virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID);
+
+ //------------------------------------------------------------------
+ /// Allocate space for data, and add it to the m_spaceBlocks map
+ ///
+ /// @param[in] Size
+ /// The size of the area.
+ ///
+ /// @param[in] Alignment
+ /// The required alignment of the area.
+ ///
+ /// @param[in] SectionID
+ /// A unique identifier for the section.
+ ///
+ /// @param[in] IsReadOnly
+ /// Flag indicating the section is read-only.
+ ///
+ /// @return
+ /// Allocated space.
+ //------------------------------------------------------------------
+ virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID, bool IsReadOnly);
+
+ //------------------------------------------------------------------
+ /// Allocate space for a global variable, and add it to the
+ /// m_spaceBlocks map
+ ///
+ /// @param[in] Size
+ /// The size of the variable.
+ ///
+ /// @param[in] Alignment
+ /// The required alignment of the variable.
+ ///
+ /// @return
+ /// Allocated space for the global.
+ //------------------------------------------------------------------
+ virtual uint8_t *allocateGlobal(uintptr_t Size,
+ unsigned Alignment);
+
+ //------------------------------------------------------------------
+ /// Called when object loading is complete and section page
+ /// permissions can be applied. Currently unimplemented for LLDB.
+ ///
+ /// @param[out] ErrMsg
+ /// The error that prevented the page protection from succeeding.
+ ///
+ /// @return
+ /// True in case of failure, false in case of success.
+ //------------------------------------------------------------------
+ virtual bool finalizeMemory(std::string *ErrMsg) {
+ // TODO: Ensure that the instruction cache is flushed because
+ // relocations are updated by dy-load. See:
+ // sys::Memory::InvalidateInstructionCache
+ // llvm::SectionMemoryManager
+ return false;
+ }
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual void deallocateFunctionBody(void *Body);
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual size_t GetDefaultCodeSlabSize() {
+ return m_default_mm_ap->GetDefaultCodeSlabSize();
+ }
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual size_t GetDefaultDataSlabSize() {
+ return m_default_mm_ap->GetDefaultDataSlabSize();
+ }
+
+ virtual size_t GetDefaultStubSlabSize() {
+ return m_default_mm_ap->GetDefaultStubSlabSize();
+ }
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual unsigned GetNumCodeSlabs() {
+ return m_default_mm_ap->GetNumCodeSlabs();
+ }
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual unsigned GetNumDataSlabs() {
+ return m_default_mm_ap->GetNumDataSlabs();
+ }
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual unsigned GetNumStubSlabs() {
+ return m_default_mm_ap->GetNumStubSlabs();
+ }
+
+ //------------------------------------------------------------------
+ /// Passthrough interface stub
+ //------------------------------------------------------------------
+ virtual void *getPointerToNamedFunction(const std::string &Name,
+ bool AbortOnFailure = true) {
+ return m_default_mm_ap->getPointerToNamedFunction(Name, AbortOnFailure);
+ }
+ private:
+ std::unique_ptr<JITMemoryManager> m_default_mm_ap; ///< The memory allocator to use in actually creating space. All calls are passed through to it.
+ IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
+ };
+
+ //----------------------------------------------------------------------
+ /// @class JittedFunction IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
+ /// @brief Encapsulates a single function that has been generated by the JIT.
+ ///
+ /// Functions that have been generated by the JIT are first resident in the
+ /// local process, and then placed in the target process. JittedFunction
+ /// represents a function possibly resident in both.
+ //----------------------------------------------------------------------
+ struct JittedFunction {
+ std::string m_name; ///< The function's name
+ lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory
+ lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variabes.
+ ///
+ /// @param[in] name
+ /// The name of the function.
+ ///
+ /// @param[in] local_addr
+ /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
+ /// it is not present in LLDB's memory.
+ ///
+ /// @param[in] remote_addr
+ /// The address of the function in the target, or LLDB_INVALID_ADDRESS
+ /// if it is not present in the target's memory.
+ //------------------------------------------------------------------
+ JittedFunction (const char *name,
+ lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
+ lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
+ m_name (name),
+ m_local_addr (local_addr),
+ m_remote_addr (remote_addr)
+ {
+ }
+ };
+
+ static const unsigned eSectionIDInvalid = (unsigned)-1;
+
+ //----------------------------------------------------------------------
+ /// @class AllocationRecord IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
+ /// @brief Enacpsulates a single allocation request made by the JIT.
+ ///
+ /// Allocations made by the JIT are first queued up and then applied in
+ /// bulk to the underlying process.
+ //----------------------------------------------------------------------
+ struct AllocationRecord {
+ lldb::addr_t m_process_address;
+ uintptr_t m_host_address;
+ uint32_t m_permissions;
+ size_t m_size;
+ unsigned m_alignment;
+ unsigned m_section_id;
+
+ AllocationRecord (uintptr_t host_address,
+ uint32_t permissions,
+ size_t size,
+ unsigned alignment,
+ unsigned section_id = eSectionIDInvalid) :
+ m_process_address(LLDB_INVALID_ADDRESS),
+ m_host_address(host_address),
+ m_permissions(permissions),
+ m_size(size),
+ m_alignment(alignment),
+ m_section_id(section_id)
+ {
+ }
+
+ void dump (Log *log);
+ };
+
+ typedef std::vector<AllocationRecord> RecordVector;
+ RecordVector m_records;
+
+ std::unique_ptr<llvm::LLVMContext> m_context_ap;
+ std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_ap;
+ std::unique_ptr<llvm::Module> m_module_ap; ///< Holder for the module until it's been handed off
+ llvm::Module *m_module; ///< Owned by the execution engine
+ std::vector<std::string> m_cpu_features;
+ llvm::SmallVector<JittedFunction, 1> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code
+ const ConstString m_name;
+
+ std::atomic<bool> m_did_jit;
+
+ lldb::addr_t m_function_load_addr;
+ lldb::addr_t m_function_end_load_addr;
+};
+
+} // namespace lldb_private
+
+#endif // lldb_IRExecutionUnit_h_
diff --git a/include/lldb/Expression/IRForTarget.h b/include/lldb/Expression/IRForTarget.h
new file mode 100644
index 000000000000..151bf2ab4774
--- /dev/null
+++ b/include/lldb/Expression/IRForTarget.h
@@ -0,0 +1,733 @@
+//===-- IRForTarget.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_IRForTarget_h_
+#define liblldb_IRForTarget_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Symbol/TaggedASTType.h"
+#include "llvm/Pass.h"
+
+#include <map>
+
+namespace llvm {
+ class BasicBlock;
+ class CallInst;
+ class Constant;
+ class ConstantInt;
+ class Function;
+ class GlobalValue;
+ class GlobalVariable;
+ class Instruction;
+ class Module;
+ class StoreInst;
+ class DataLayout;
+ class Type;
+ class Value;
+}
+
+namespace lldb_private {
+ class ClangExpressionDeclMap;
+ class IRExecutionUnit;
+ class IRMemoryMap;
+}
+
+//----------------------------------------------------------------------
+/// @class IRForTarget IRForTarget.h "lldb/Expression/IRForTarget.h"
+/// @brief Transforms the IR for a function to run in the target
+///
+/// Once an expression has been parsed and converted to IR, it can run
+/// in two contexts: interpreted by LLDB as a DWARF location expression,
+/// or compiled by the JIT and inserted into the target process for
+/// execution.
+///
+/// IRForTarget makes the second possible, by applying a series of
+/// transformations to the IR which make it relocatable. These
+/// transformations are discussed in more detail next to their relevant
+/// functions.
+//----------------------------------------------------------------------
+class IRForTarget : public llvm::ModulePass
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] decl_map
+ /// The list of externally-referenced variables for the expression,
+ /// for use in looking up globals and allocating the argument
+ /// struct. See the documentation for ClangExpressionDeclMap.
+ ///
+ /// @param[in] resolve_vars
+ /// True if the external variable references (including persistent
+ /// variables) should be resolved. If not, only external functions
+ /// are resolved.
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether an IR interpreter can be used to statically
+ /// evaluate the expression.
+ ///
+ /// @param[in] const_result
+ /// This variable is populated with the statically-computed result
+ /// of the function, if it has no side-effects and the result can
+ /// be computed statically.
+ ///
+ /// @param[in] execution_unit
+ /// The holder for raw data associated with the expression.
+ ///
+ /// @param[in] error_stream
+ /// If non-NULL, a stream on which errors can be printed.
+ ///
+ /// @param[in] func_name
+ /// The name of the function to prepare for execution in the target.
+ //------------------------------------------------------------------
+ IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
+ bool resolve_vars,
+ lldb_private::IRExecutionUnit &execution_unit,
+ lldb_private::Stream *error_stream,
+ const char* func_name = "$__lldb_expr");
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual ~IRForTarget();
+
+ //------------------------------------------------------------------
+ /// Run this IR transformer on a single module
+ ///
+ /// Implementation of the llvm::ModulePass::runOnModule() function.
+ ///
+ /// @param[in] llvm_module
+ /// The module to run on. This module is searched for the function
+ /// $__lldb_expr, and that function is passed to the passes one by
+ /// one.
+ ///
+ /// @param[in] interpreter_error
+ /// An error. If the expression fails to be interpreted, this error
+ /// is set to a reason why.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ virtual bool
+ runOnModule (llvm::Module &llvm_module);
+
+ //------------------------------------------------------------------
+ /// Interface stub
+ ///
+ /// Implementation of the llvm::ModulePass::assignPassManager()
+ /// function.
+ //------------------------------------------------------------------
+ virtual void
+ assignPassManager (llvm::PMStack &pass_mgr_stack,
+ llvm::PassManagerType pass_mgr_type = llvm::PMT_ModulePassManager);
+
+ //------------------------------------------------------------------
+ /// Returns PMT_ModulePassManager
+ ///
+ /// Implementation of the llvm::ModulePass::getPotentialPassManagerType()
+ /// function.
+ //------------------------------------------------------------------
+ virtual llvm::PassManagerType
+ getPotentialPassManagerType() const;
+
+private:
+ //------------------------------------------------------------------
+ /// Ensures that the current function's linkage is set to external.
+ /// Otherwise the JIT may not return an address for it.
+ ///
+ /// @param[in] llvm_function
+ /// The function whose linkage is to be fixed.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ FixFunctionLinkage (llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to replace all function pointers with their
+ /// integer equivalents.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_module
+ /// The module currently being processed.
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ HasSideEffects (llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to check whether the function has side
+ /// effects.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Get the address of a fuction, and a location to put the complete
+ /// Value of the function if one is available.
+ ///
+ /// @param[in] function
+ /// The function to find the location of.
+ ///
+ /// @param[out] ptr
+ /// The location of the function in the target.
+ ///
+ /// @param[out] name
+ /// The resolved name of the function (matters for intrinsics).
+ ///
+ /// @param[out] value_ptr
+ /// A variable to put the function's completed Value* in, or NULL
+ /// if the Value* shouldn't be stored anywhere.
+ ///
+ /// @return
+ /// The pointer.
+ //------------------------------------------------------------------
+ bool
+ GetFunctionAddress (llvm::Function *function,
+ uint64_t &ptr,
+ lldb_private::ConstString &name,
+ llvm::Constant **&value_ptr);
+
+ //------------------------------------------------------------------
+ /// Build a function pointer given a type and a raw pointer.
+ ///
+ /// @param[in] type
+ /// The type of the function pointer to be built.
+ ///
+ /// @param[in] ptr
+ /// The value of the pointer.
+ ///
+ /// @return
+ /// The pointer.
+ //------------------------------------------------------------------
+ llvm::Constant *
+ BuildFunctionPointer (llvm::Type *type,
+ uint64_t ptr);
+
+ void
+ RegisterFunctionMetadata (llvm::LLVMContext &context,
+ llvm::Value *function_ptr,
+ const char *name);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True if the function has side effects (or if this cannot
+ /// be determined); false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ResolveFunctionPointers (llvm::Module &llvm_module);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to take the generated global value
+ /// $__lldb_expr_result and make it into a persistent variable.
+ /// Also see ASTResultSynthesizer.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Find the NamedDecl corresponding to a Value. This interface is
+ /// exposed for the IR interpreter.
+ ///
+ /// @param[in] module
+ /// The module containing metadata to search
+ ///
+ /// @param[in] global
+ /// The global entity to search for
+ ///
+ /// @return
+ /// The corresponding variable declaration
+ //------------------------------------------------------------------
+public:
+ static clang::NamedDecl *
+ DeclForGlobal (const llvm::GlobalValue *global_val, llvm::Module *module);
+private:
+ clang::NamedDecl *
+ DeclForGlobal (llvm::GlobalValue *global);
+
+ //------------------------------------------------------------------
+ /// Set the constant result variable m_const_result to the provided
+ /// constant, assuming it can be evaluated. The result variable
+ /// will be reset to NULL later if the expression has side effects.
+ ///
+ /// @param[in] initializer
+ /// The constant initializer for the variable.
+ ///
+ /// @param[in] name
+ /// The name of the result variable.
+ ///
+ /// @param[in] type
+ /// The Clang type of the result variable.
+ //------------------------------------------------------------------
+ void
+ MaybeSetConstantResult (llvm::Constant *initializer,
+ const lldb_private::ConstString &name,
+ lldb_private::TypeFromParser type);
+
+ //------------------------------------------------------------------
+ /// If the IR represents a cast of a variable, set m_const_result
+ /// to the result of the cast. The result variable will be reset to
+ /// NULL latger if the expression has side effects.
+ ///
+ /// @param[in] type
+ /// The Clang type of the result variable.
+ //------------------------------------------------------------------
+ void
+ MaybeSetCastResult (lldb_private::TypeFromParser type);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ CreateResultVariable (llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to find Objective-C constant strings and
+ /// transform them to calls to CFStringCreateWithBytes.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Rewrite a single Objective-C constant string.
+ ///
+ /// @param[in] NSStr
+ /// The constant NSString to be transformed
+ ///
+ /// @param[in] CStr
+ /// The constant C string inside the NSString. This will be
+ /// passed as the bytes argument to CFStringCreateWithBytes.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RewriteObjCConstString (llvm::GlobalVariable *NSStr,
+ llvm::GlobalVariable *CStr);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RewriteObjCConstStrings ();
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all Objective-C method calls and
+ /// rewrite them to use sel_registerName instead of statically allocated
+ /// selectors. The reason is that the selectors are created on the
+ /// assumption that the Objective-C runtime will scan the appropriate
+ /// section and prepare them. This doesn't happen when code is copied
+ /// into the target, though, and there's no easy way to induce the
+ /// runtime to scan them. So instead we get our selectors from
+ /// sel_registerName.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Replace a single selector reference
+ ///
+ /// @param[in] selector_load
+ /// The load of the statically-allocated selector.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RewriteObjCSelector (llvm::Instruction* selector_load);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RewriteObjCSelectors (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all newly-declared persistent
+ /// variables and register them with the ClangExprDeclMap. This
+ /// allows them to be materialized and dematerialized like normal
+ /// external variables. Before transformation, these persistent
+ /// variables look like normal locals, so they have an allocation.
+ /// This pass excises these allocations and makes references look
+ /// like external references where they will be resolved -- like all
+ /// other external references -- by ResolveExternals().
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Handle a single allocation of a persistent variable
+ ///
+ /// @param[in] persistent_alloc
+ /// The allocation of the persistent variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RewritePersistentAlloc (llvm::Instruction *persistent_alloc);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ //------------------------------------------------------------------
+ bool
+ RewritePersistentAllocs (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to find all external variables and functions
+ /// used in the IR. Each found external variable is added to the
+ /// struct, and each external function is resolved in place, its call
+ /// replaced with a call to a function pointer whose value is the
+ /// address of the function in the target process.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Write an initializer to a memory array of assumed sufficient
+ /// size.
+ ///
+ /// @param[in] data
+ /// A pointer to the data to write to.
+ ///
+ /// @param[in] initializer
+ /// The initializer itself.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ MaterializeInitializer (uint8_t *data, llvm::Constant *initializer);
+
+ //------------------------------------------------------------------
+ /// Move an internal variable into the static allocation section.
+ ///
+ /// @param[in] global_variable
+ /// The variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ MaterializeInternalVariable (llvm::GlobalVariable *global_variable);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined variable
+ ///
+ /// @param[in] value
+ /// The variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ MaybeHandleVariable (llvm::Value *value);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined symbol
+ ///
+ /// @param[in] symbol
+ /// The symbol.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ HandleSymbol (llvm::Value *symbol);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined Objective-C class
+ ///
+ /// @param[in] classlist_reference
+ /// The reference, usually "01L_OBJC_CLASSLIST_REFERENCES_$_n"
+ /// where n (if present) is an index.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ HandleObjCClass(llvm::Value *classlist_reference);
+
+ //------------------------------------------------------------------
+ /// Handle all the arguments to a function call
+ ///
+ /// @param[in] C
+ /// The call instruction.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ MaybeHandleCallArguments (llvm::CallInst *call_inst);
+
+ //------------------------------------------------------------------
+ /// Resolve variable references in calls to external functions
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ ResolveCalls (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// Remove calls to __cxa_atexit, which should never be generated by
+ /// expressions.
+ ///
+ /// @param[in] call_inst
+ /// The call instruction.
+ ///
+ /// @return
+ /// True if the scan was successful; false if some operation
+ /// failed
+ //------------------------------------------------------------------
+ bool
+ RemoveCXAAtExit (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ ResolveExternals (llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to excise guard variables from the code.
+ /// The result for the function is passed through Clang as a static
+ /// variable. Static variables normally have guard variables to
+ /// ensure that they are only initialized once.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Rewrite a load to a guard variable to return constant 0.
+ ///
+ /// @param[in] guard_load
+ /// The load instruction to zero out.
+ //------------------------------------------------------------------
+ void
+ TurnGuardLoadIntoZero(llvm::Instruction* guard_load);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ RemoveGuards (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to allocate all string literals in a separate
+ /// allocation and redirect references to them.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ ReplaceStrings ();
+
+ //------------------------------------------------------------------
+ /// A basick block-level pass to find all literals that will be
+ /// allocated as statics by the JIT (in contrast to the Strings,
+ /// which already are statics) and synthesize loads for them.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ ReplaceStaticLiterals (llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to make all external variable references
+ /// point at the correct offsets from the void* passed into the
+ /// function. ClangExpressionDeclMap::DoStructLayout() must be called
+ /// beforehand, so that the offsets are valid.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ ReplaceVariables (llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to remove all global variables from the
+ /// module since it no longer should export or import any symbols.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_module
+ /// The module currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ StripAllGVs (llvm::Module &llvm_module);
+
+ class StaticDataAllocator {
+ public:
+ StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit);
+ lldb_private::StreamString &GetStream()
+ {
+ return m_stream_string;
+ }
+ lldb::addr_t Allocate();
+ private:
+ lldb_private::IRExecutionUnit &m_execution_unit;
+ lldb_private::StreamString m_stream_string;
+ lldb::addr_t m_allocation;
+ };
+
+ /// Flags
+ bool m_resolve_vars; ///< True if external variable references and persistent variable references should be resolved
+ std::string m_func_name; ///< The name of the function to translate
+ lldb_private::ConstString m_result_name; ///< The name of the result variable ($0, $1, ...)
+ lldb_private::TypeFromParser m_result_type; ///< The type of the result variable.
+ llvm::Module *m_module; ///< The module being processed, or NULL if that has not been determined yet.
+ std::unique_ptr<llvm::DataLayout> m_target_data; ///< The target data for the module being processed, or NULL if there is no module.
+ lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls
+ StaticDataAllocator m_data_allocator; ///< The allocator to use for constant strings
+ llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the appropriate function pointer type
+ llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate function pointer type
+ lldb_private::Stream *m_error_stream; ///< If non-NULL, the stream on which errors should be printed
+
+ llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If m_has_side_effects is true, this is NULL.
+ bool m_result_is_pointer; ///< True if the function's result in the AST is a pointer (see comments in ASTResultSynthesizer::SynthesizeBodyResult)
+
+ llvm::GlobalVariable *m_reloc_placeholder; ///< A placeholder that will be replaced by a pointer to the final location of the static allocation.
+
+ //------------------------------------------------------------------
+ /// UnfoldConstant operates on a constant [Old] which has just been
+ /// replaced with a value [New]. We assume that new_value has
+ /// been properly placed early in the function, in front of the
+ /// first instruction in the entry basic block
+ /// [FirstEntryInstruction].
+ ///
+ /// UnfoldConstant reads through the uses of Old and replaces Old
+ /// in those uses with New. Where those uses are constants, the
+ /// function generates new instructions to compute the result of the
+ /// new, non-constant expression and places them before
+ /// FirstEntryInstruction. These instructions replace the constant
+ /// uses, so UnfoldConstant calls itself recursively for those.
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+
+ class FunctionValueCache {
+ public:
+ typedef std::function <llvm::Value *(llvm::Function *)> Maker;
+
+ FunctionValueCache (Maker const &maker);
+ ~FunctionValueCache ();
+ llvm::Value *GetValue (llvm::Function *function);
+ private:
+ Maker const m_maker;
+ typedef std::map<llvm::Function *, llvm::Value *> FunctionValueMap;
+ FunctionValueMap m_values;
+ };
+
+ FunctionValueCache m_entry_instruction_finder;
+
+ static bool
+ UnfoldConstant (llvm::Constant *old_constant,
+ FunctionValueCache &value_maker,
+ FunctionValueCache &entry_instruction_finder);
+
+ //------------------------------------------------------------------
+ /// Construct a reference to m_reloc_placeholder with a given type
+ /// and offset. This typically happens after inserting data into
+ /// m_data_allocator.
+ ///
+ /// @param[in] type
+ /// The type of the value being loaded.
+ ///
+ /// @param[in] offset
+ /// The offset of the value from the base of m_data_allocator.
+ ///
+ /// @return
+ /// The Constant for the reference, usually a ConstantExpr.
+ //------------------------------------------------------------------
+ llvm::Constant *
+ BuildRelocation(llvm::Type *type,
+ uint64_t offset);
+
+ //------------------------------------------------------------------
+ /// Commit the allocation in m_data_allocator and use its final
+ /// location to replace m_reloc_placeholder.
+ ///
+ /// @param[in] module
+ /// The module that m_data_allocator resides in
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool
+ CompleteDataAllocation ();
+
+};
+
+#endif
diff --git a/include/lldb/Expression/IRInterpreter.h b/include/lldb/Expression/IRInterpreter.h
new file mode 100644
index 000000000000..5defa8dd2026
--- /dev/null
+++ b/include/lldb/Expression/IRInterpreter.h
@@ -0,0 +1,64 @@
+//===-- IRInterpreter.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_IRInterpreter_h_
+#define liblldb_IRInterpreter_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Symbol/TaggedASTType.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ class Function;
+ class Module;
+}
+
+namespace lldb_private {
+
+class ClangExpressionDeclMap;
+class IRMemoryMap;
+
+}
+
+//----------------------------------------------------------------------
+/// @class IRInterpreter IRInterpreter.h "lldb/Expression/IRInterpreter.h"
+/// @brief Attempt to interpret the function's code if it does not require
+/// running the target.
+///
+/// In some cases, the IR for an expression can be evaluated entirely
+/// in the debugger, manipulating variables but not executing any code
+/// in the target. The IRInterpreter attempts to do this.
+//----------------------------------------------------------------------
+class IRInterpreter
+{
+public:
+ static bool
+ CanInterpret (llvm::Module &module,
+ llvm::Function &function,
+ lldb_private::Error &error);
+
+ static bool
+ Interpret (llvm::Module &module,
+ llvm::Function &function,
+ llvm::ArrayRef<lldb::addr_t> args,
+ lldb_private::IRMemoryMap &memory_map,
+ lldb_private::Error &error,
+ lldb::addr_t stack_frame_bottom,
+ lldb::addr_t stack_frame_top);
+
+private:
+ static bool
+ supportsFunction (llvm::Function &llvm_function,
+ lldb_private::Error &err);
+};
+
+#endif
diff --git a/include/lldb/Expression/IRMemoryMap.h b/include/lldb/Expression/IRMemoryMap.h
new file mode 100644
index 000000000000..affe19350e3f
--- /dev/null
+++ b/include/lldb/Expression/IRMemoryMap.h
@@ -0,0 +1,126 @@
+//===-- IRExecutionUnit.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_IRMemoryMap_h_
+#define lldb_IRMemoryMap_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/UserID.h"
+
+#include <map>
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class IRMemoryMap IRMemoryMap.h "lldb/Expression/IRMemoryMap.h"
+/// @brief Encapsulates memory that may exist in the process but must
+/// also be available in the host process.
+///
+/// This class encapsulates a group of memory objects that must be readable
+/// or writable from the host process regardless of whether the process
+/// exists. This allows the IR interpreter as well as JITted code to access
+/// the same memory.
+///
+/// Point queries against this group of memory objects can be made by the
+/// address in the tar at which they reside. If the inferior does not
+/// exist, allocations still get made-up addresses. If an inferior appears
+/// at some point, then those addresses need to be re-mapped.
+//----------------------------------------------------------------------
+class IRMemoryMap
+{
+public:
+ IRMemoryMap (lldb::TargetSP target_sp);
+ ~IRMemoryMap ();
+
+ enum AllocationPolicy {
+ eAllocationPolicyInvalid = 0, ///< It is an error for an allocation to have this policy.
+ eAllocationPolicyHostOnly, ///< This allocation was created in the host and will never make it into the process.
+ ///< It is an error to create other types of allocations while such allocations exist.
+ eAllocationPolicyMirror, ///< The intent is that this allocation exist both in the host and the process and have
+ ///< the same content in both.
+ eAllocationPolicyProcessOnly ///< The intent is that this allocation exist only in the process.
+ };
+
+ lldb::addr_t Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error);
+ void Leak (lldb::addr_t process_address, Error &error);
+ void Free (lldb::addr_t process_address, Error &error);
+
+ void WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error);
+ void WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error);
+ void WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error);
+ void ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error);
+ void ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error);
+ void ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error);
+
+ void GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error);
+
+ lldb::ByteOrder GetByteOrder();
+ uint32_t GetAddressByteSize();
+
+ // This function can return NULL.
+ ExecutionContextScope *GetBestExecutionContextScope();
+
+protected:
+ // This function should only be used if you know you are using the JIT.
+ // Any other cases should use GetBestExecutionContextScope().
+ lldb::ProcessWP GetProcessWP ()
+ {
+ return m_process_wp;
+ }
+
+private:
+ struct Allocation
+ {
+ lldb::addr_t m_process_alloc; ///< The (unaligned) base for the remote allocation
+ lldb::addr_t m_process_start; ///< The base address of the allocation in the process
+ size_t m_size; ///< The size of the requested allocation
+ uint32_t m_permissions; ///< The access permissions on the memory in the process. In the host, the memory is always read/write.
+ uint8_t m_alignment; ///< The alignment of the requested allocation
+ DataBufferHeap m_data;
+
+ ///< Flags
+ AllocationPolicy m_policy;
+ bool m_leak;
+ public:
+ Allocation (lldb::addr_t process_alloc,
+ lldb::addr_t process_start,
+ size_t size,
+ uint32_t permissions,
+ uint8_t alignment,
+ AllocationPolicy m_policy);
+
+ Allocation () :
+ m_process_alloc (LLDB_INVALID_ADDRESS),
+ m_process_start (LLDB_INVALID_ADDRESS),
+ m_size (0),
+ m_permissions (0),
+ m_alignment (0),
+ m_data (),
+ m_policy (eAllocationPolicyInvalid),
+ m_leak (false)
+ {
+ }
+ };
+
+ lldb::ProcessWP m_process_wp;
+ lldb::TargetWP m_target_wp;
+ typedef std::map<lldb::addr_t, Allocation> AllocationMap;
+ AllocationMap m_allocations;
+
+ lldb::addr_t FindSpace (size_t size);
+ bool ContainsHostOnlyAllocations ();
+ AllocationMap::iterator FindAllocation (lldb::addr_t addr, size_t size);
+ bool IntersectsAllocation (lldb::addr_t addr, size_t size);
+};
+
+}
+
+#endif
diff --git a/include/lldb/Expression/IRToDWARF.h b/include/lldb/Expression/IRToDWARF.h
new file mode 100644
index 000000000000..43dc99d6d476
--- /dev/null
+++ b/include/lldb/Expression/IRToDWARF.h
@@ -0,0 +1,111 @@
+//===-- IRToDWARF.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_IRToDWARF_h_
+#define liblldb_IRToDWARF_h_
+
+#include "llvm/Pass.h"
+#include "llvm/PassManager.h"
+
+#include "lldb/lldb-public.h"
+
+class Relocator;
+//----------------------------------------------------------------------
+/// @class IRToDWARF IRToDWARF.h "lldb/Expression/IRToDWARF.h"
+/// @brief Transforms the IR for a function into a DWARF location expression
+///
+/// Once an expression has been parsed and converted to IR, it can run
+/// in two contexts: interpreted by LLDB as a DWARF location expression,
+/// or compiled by the JIT and inserted into the target process for
+/// execution.
+///
+/// IRToDWARF makes the first possible, by traversing the control flow
+/// graph and writing the code for each basic block out as location
+/// expression bytecode. To ensure that the links between the basic blocks
+/// remain intact, it uses a relocator that records the location of every
+/// location expression instruction that has a relocatable operand, the
+/// target of that operand (as a basic block), and the mapping of each basic
+/// block to an actual location. After all code has been written out, the
+/// relocator post-processes it and performs all necessary relocations.
+//----------------------------------------------------------------------
+class IRToDWARF : public llvm::ModulePass
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] local_vars
+ /// A list of variables to populate with the local variables this
+ /// expression uses.
+ ///
+ /// @param[in] decl_map
+ /// The list of externally-referenced variables for the expression,
+ /// for use in looking up globals.
+ ///
+ /// @param[in] stream
+ /// The stream to dump DWARF bytecode onto.
+ ///
+ /// @param[in] func_name
+ /// The name of the function to translate to DWARF.
+ //------------------------------------------------------------------
+ IRToDWARF(lldb_private::ClangExpressionVariableList &local_vars,
+ lldb_private::ClangExpressionDeclMap *decl_map,
+ lldb_private::StreamString &strm,
+ const char* func_name = "$__lldb_expr");
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual ~IRToDWARF();
+
+ //------------------------------------------------------------------
+ /// Run this IR transformer on a single module
+ ///
+ /// @param[in] M
+ /// The module to run on. This module is searched for the function
+ /// $__lldb_expr, and that function is converted to a location
+ /// expression.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool runOnModule(llvm::Module &M);
+
+ //------------------------------------------------------------------
+ /// Interface stub
+ //------------------------------------------------------------------
+ void assignPassManager(llvm::PMStack &PMS,
+ llvm::PassManagerType T = llvm::PMT_ModulePassManager);
+
+ //------------------------------------------------------------------
+ /// Returns PMT_ModulePassManager
+ //------------------------------------------------------------------
+ llvm::PassManagerType getPotentialPassManagerType() const;
+private:
+ //------------------------------------------------------------------
+ /// Run this IR transformer on a single basic block
+ ///
+ /// @param[in] BB
+ /// The basic block to transform.
+ ///
+ /// @param[in] Relocator
+ /// The relocator to use when registering branches.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool runOnBasicBlock(llvm::BasicBlock &BB, Relocator &Relocator);
+
+ std::string m_func_name; ///< The name of the function to translate
+ lldb_private::ClangExpressionVariableList &m_local_vars; ///< The list of local variables to populate while transforming
+ lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The list of external variables
+ lldb_private::StreamString &m_strm; ///< The stream to write bytecode to
+};
+
+#endif
diff --git a/include/lldb/Expression/Materializer.h b/include/lldb/Expression/Materializer.h
new file mode 100644
index 000000000000..208a08133923
--- /dev/null
+++ b/include/lldb/Expression/Materializer.h
@@ -0,0 +1,173 @@
+//===-- Materializer.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Materializer_h
+#define lldb_Materializer_h
+
+#include "lldb/lldb-private-types.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/IRMemoryMap.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/StackFrame.h"
+
+#include <vector>
+
+namespace lldb_private
+{
+
+class Materializer
+{
+public:
+ Materializer ();
+ ~Materializer ();
+
+ class Dematerializer
+ {
+ public:
+ Dematerializer () :
+ m_materializer(NULL),
+ m_map(NULL),
+ m_process_address(LLDB_INVALID_ADDRESS)
+ {
+ }
+
+ ~Dematerializer ()
+ {
+ Wipe ();
+ }
+
+ void Dematerialize (Error &err,
+ lldb::ClangExpressionVariableSP &result_sp,
+ lldb::addr_t frame_top,
+ lldb::addr_t frame_bottom);
+
+ void Wipe ();
+
+ bool IsValid ()
+ {
+ return m_materializer && m_map && (m_process_address != LLDB_INVALID_ADDRESS);
+ }
+ private:
+ friend class Materializer;
+
+ Dematerializer (Materializer &materializer,
+ lldb::StackFrameSP &frame_sp,
+ IRMemoryMap &map,
+ lldb::addr_t process_address) :
+ m_materializer(&materializer),
+ m_map(&map),
+ m_process_address(process_address)
+ {
+ if (frame_sp)
+ {
+ m_thread_wp = frame_sp->GetThread();
+ m_stack_id = frame_sp->GetStackID();
+ }
+ }
+
+ Materializer *m_materializer;
+ lldb::ThreadWP m_thread_wp;
+ StackID m_stack_id;
+ IRMemoryMap *m_map;
+ lldb::addr_t m_process_address;
+ };
+
+ typedef std::shared_ptr<Dematerializer> DematerializerSP;
+ typedef std::weak_ptr<Dematerializer> DematerializerWP;
+
+ DematerializerSP Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err);
+
+ uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
+ uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
+ uint32_t AddResultVariable (const TypeFromUser &type, bool is_lvalue, bool keep_in_memory, Error &err);
+ uint32_t AddSymbol (const Symbol &symbol_sp, Error &err);
+ uint32_t AddRegister (const RegisterInfo &register_info, Error &err);
+
+ uint32_t GetStructAlignment ()
+ {
+ return m_struct_alignment;
+ }
+
+ uint32_t GetStructByteSize ()
+ {
+ return m_current_offset;
+ }
+
+ uint32_t GetResultOffset ()
+ {
+ if (m_result_entity)
+ return m_result_entity->GetOffset();
+ else
+ return UINT32_MAX;
+ }
+
+ class Entity
+ {
+ public:
+ Entity () :
+ m_alignment(1),
+ m_size(0),
+ m_offset(0)
+ {
+ }
+
+ virtual ~Entity ()
+ {
+ }
+
+ virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
+ virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
+ lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) = 0;
+ virtual void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) = 0;
+ virtual void Wipe (IRMemoryMap &map, lldb::addr_t process_address) = 0;
+
+ uint32_t GetAlignment ()
+ {
+ return m_alignment;
+ }
+
+ uint32_t GetSize ()
+ {
+ return m_size;
+ }
+
+ uint32_t GetOffset ()
+ {
+ return m_offset;
+ }
+
+ void SetOffset (uint32_t offset)
+ {
+ m_offset = offset;
+ }
+ protected:
+ void SetSizeAndAlignmentFromType (ClangASTType &type);
+
+ uint32_t m_alignment;
+ uint32_t m_size;
+ uint32_t m_offset;
+ };
+
+private:
+ uint32_t AddStructMember (Entity &entity);
+
+ typedef std::unique_ptr<Entity> EntityUP;
+ typedef std::vector<EntityUP> EntityVector;
+
+ DematerializerWP m_dematerializer_wp;
+ EntityVector m_entities;
+ Entity *m_result_entity;
+ uint32_t m_current_offset;
+ uint32_t m_struct_alignment;
+};
+
+}
+
+#endif
diff --git a/include/lldb/Host/Condition.h b/include/lldb/Host/Condition.h
new file mode 100644
index 000000000000..98439ee2ebdf
--- /dev/null
+++ b/include/lldb/Host/Condition.h
@@ -0,0 +1,124 @@
+//===-- Condition.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DBCondition_h_
+#define liblldb_DBCondition_h_
+#if defined(__cplusplus)
+
+
+#include <pthread.h>
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+class TimeValue;
+
+//----------------------------------------------------------------------
+/// @class Condition Condition.h "lldb/Host/Condition.h"
+/// @brief A C++ wrapper class for pthread condition variables.
+///
+/// A class that wraps up a pthread condition (pthread_cond_t). The
+/// class will create a pthread condition when an instance is
+/// constructed, and detroy it when it is destructed. It also provides
+/// access to the standard pthread condition calls.
+//----------------------------------------------------------------------
+class Condition
+{
+public:
+
+ //------------------------------------------------------------------
+ /// Default constructor
+ ///
+ /// The default constructor will initialize a new pthread condition
+ /// and maintain the condition in the object state.
+ //------------------------------------------------------------------
+ Condition ();
+
+ //------------------------------------------------------------------
+ /// Destructor
+ ///
+ /// Destroys the pthread condition that the object owns.
+ //------------------------------------------------------------------
+ ~Condition ();
+
+ //------------------------------------------------------------------
+ /// Unblock all threads waiting for a condition variable
+ ///
+ /// @return
+ /// The return value from \c pthread_cond_broadcast()
+ //------------------------------------------------------------------
+ int
+ Broadcast ();
+
+ //------------------------------------------------------------------
+ /// Unblocks one thread waiting for the condition variable
+ ///
+ /// @return
+ /// The return value from \c pthread_cond_signal()
+ //------------------------------------------------------------------
+ int
+ Signal ();
+
+ //------------------------------------------------------------------
+ /// Wait for the condition variable to be signaled.
+ ///
+ /// The Wait() function atomically blocks the current thread
+ /// waiting on this object's condition variable, and unblocks
+ /// \a mutex. The waiting thread unblocks only after another thread
+ /// signals or broadcasts this object's condition variable.
+ ///
+ /// If \a abstime is non-NULL, this function will return when the
+ /// system time reaches the time specified in \a abstime if the
+ /// condition variable doesn't get unblocked. If \a abstime is NULL
+ /// this function will wait for an infinite amount of time for the
+ /// condition variable to be unblocked.
+ ///
+ /// The current thread re-acquires the lock on \a mutex following
+ /// the wait.
+ ///
+ /// @param[in] mutex
+ /// The mutex to use in the \c pthread_cond_timedwait() or
+ /// \c pthread_cond_wait() calls.
+ ///
+ /// @param[in] abstime
+ /// An absolute time at which to stop waiting if non-NULL, else
+ /// wait an infinite amount of time for the condition variable
+ /// toget signaled.
+ ///
+ /// @param[out] timed_out
+ /// If not NULL, will be set to true if the wait timed out, and
+ // false otherwise.
+ ///
+ /// @see Condition::Broadcast()
+ /// @see Condition::Signal()
+ //------------------------------------------------------------------
+ int
+ Wait (Mutex &mutex, const TimeValue *abstime = NULL, bool *timed_out = NULL);
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ pthread_cond_t m_condition; ///< The condition variable.
+
+ //------------------------------------------------------------------
+ /// Get accessor to the pthread condition object.
+ ///
+ /// @return
+ /// A pointer to the condition variable owned by this object.
+ //------------------------------------------------------------------
+ pthread_cond_t *
+ GetCondition ();
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif
+
diff --git a/include/lldb/Host/Config.h b/include/lldb/Host/Config.h
new file mode 100644
index 000000000000..2d5d39baac3d
--- /dev/null
+++ b/include/lldb/Host/Config.h
@@ -0,0 +1,35 @@
+//===-- Config.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Config_h_
+#define liblldb_Config_h_
+
+#if defined(__APPLE__)
+
+#include "lldb/Host/macosx/Config.h"
+
+#elif defined(__linux__)
+
+#include "lldb/Host/linux/Config.h"
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
+
+#include "lldb/Host/freebsd/Config.h"
+
+#elif defined(__MINGW__) || defined (__MINGW32__)
+
+#include "lldb/Host/mingw/Config.h"
+
+#else
+
+#error undefined platform
+
+#endif
+
+#endif // #ifndef liblldb_Config_h_
diff --git a/include/lldb/Host/DynamicLibrary.h b/include/lldb/Host/DynamicLibrary.h
new file mode 100644
index 000000000000..1fcc7d1883cf
--- /dev/null
+++ b/include/lldb/Host/DynamicLibrary.h
@@ -0,0 +1,51 @@
+//===-- DynamicLibrary.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DynamicLibrary_h_
+#define liblldb_DynamicLibrary_h_
+
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
+
+namespace lldb_private {
+
+class DynamicLibrary
+{
+public:
+ DynamicLibrary (const FileSpec& spec, uint32_t options = Host::eDynamicLibraryOpenOptionLazy |
+ Host::eDynamicLibraryOpenOptionLocal |
+ Host::eDynamicLibraryOpenOptionLimitGetSymbol);
+
+ ~DynamicLibrary ();
+
+ template <typename T = void*>
+ T GetSymbol (const char* name)
+ {
+ Error err;
+ if (!m_handle)
+ return (T)NULL;
+ void* symbol = Host::DynamicLibraryGetSymbol (m_handle, name, err);
+ if (!symbol)
+ return (T)NULL;
+ return (T)symbol;
+ }
+
+ bool
+ IsValid ();
+
+private:
+ lldb_private::FileSpec m_filespec;
+ void* m_handle;
+
+ DISALLOW_COPY_AND_ASSIGN (DynamicLibrary);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_DynamicLibrary_h_
diff --git a/include/lldb/Host/Endian.h b/include/lldb/Host/Endian.h
new file mode 100644
index 000000000000..610f3ce95c41
--- /dev/null
+++ b/include/lldb/Host/Endian.h
@@ -0,0 +1,33 @@
+//===-- Endian.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_host_endian_h_
+#define liblldb_host_endian_h_
+
+#include "lldb/lldb-enumerations.h"
+
+namespace lldb {
+
+namespace endian {
+
+ static union EndianTest
+ {
+ uint32_t num;
+ uint8_t bytes[sizeof(uint32_t)];
+ } const endianTest = { (uint16_t)0x01020304 };
+
+ inline ByteOrder InlHostByteOrder() { return (ByteOrder)endianTest.bytes[0]; }
+
+// ByteOrder const InlHostByteOrder = (ByteOrder)endianTest.bytes[0];
+}
+
+}
+
+#endif // liblldb_host_endian_h_
+
diff --git a/include/lldb/Host/File.h b/include/lldb/Host/File.h
new file mode 100644
index 000000000000..df7fe92cccba
--- /dev/null
+++ b/include/lldb/Host/File.h
@@ -0,0 +1,500 @@
+//===-- File.h --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_File_h_
+#define liblldb_File_h_
+#if defined(__cplusplus)
+
+#include <stdio.h>
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class File File.h "lldb/Host/File.h"
+/// @brief A file class.
+///
+/// A file class that divides abstracts the LLDB core from host file
+/// functionality.
+//----------------------------------------------------------------------
+class File
+{
+public:
+ static int kInvalidDescriptor;
+ static FILE * kInvalidStream;
+
+ enum OpenOptions
+ {
+ eOpenOptionRead = (1u << 0), // Open file for reading
+ eOpenOptionWrite = (1u << 1), // Open file for writing
+ eOpenOptionAppend = (1u << 2), // Don't truncate file when opening, append to end of file
+ eOpenOptionTruncate = (1u << 3), // Truncate file when opening
+ eOpenOptionNonBlocking = (1u << 4), // File reads
+ eOpenOptionCanCreate = (1u << 5), // Create file if doesn't already exist
+ eOpenOptionCanCreateNewOnly = (1u << 6) // Can create file only if it doesn't already exist
+ };
+
+ enum Permissions
+ {
+ ePermissionsUserRead = (1u << 0),
+ ePermissionsUserWrite = (1u << 1),
+ ePermissionsUserExecute = (1u << 2),
+ ePermissionsGroupRead = (1u << 3),
+ ePermissionsGroupWrite = (1u << 4),
+ ePermissionsGroupExecute = (1u << 5),
+ ePermissionsWorldRead = (1u << 6),
+ ePermissionsWorldWrite = (1u << 7),
+ ePermissionsWorldExecute = (1u << 8),
+
+ ePermissionsUserRW = (ePermissionsUserRead | ePermissionsUserWrite | 0 ),
+ ePermissionsUserRX = (ePermissionsUserRead | 0 | ePermissionsUserExecute ),
+ ePermissionsUserRWX = (ePermissionsUserRead | ePermissionsUserWrite | ePermissionsUserExecute ),
+
+ ePermissionsGroupRW = (ePermissionsGroupRead | ePermissionsGroupWrite | 0 ),
+ ePermissionsGroupRX = (ePermissionsGroupRead | 0 | ePermissionsGroupExecute ),
+ ePermissionsGroupRWX = (ePermissionsGroupRead | ePermissionsGroupWrite | ePermissionsGroupExecute ),
+
+ ePermissionsWorldRW = (ePermissionsWorldRead | ePermissionsWorldWrite | 0 ),
+ ePermissionsWorldRX = (ePermissionsWorldRead | 0 | ePermissionsWorldExecute ),
+ ePermissionsWorldRWX = (ePermissionsWorldRead | ePermissionsWorldWrite | ePermissionsWorldExecute ),
+
+ ePermissionsEveryoneR = (ePermissionsUserRead | ePermissionsGroupRead | ePermissionsWorldRead ),
+ ePermissionsEveryoneW = (ePermissionsUserWrite | ePermissionsGroupWrite | ePermissionsWorldWrite ),
+ ePermissionsEveryoneX = (ePermissionsUserExecute | ePermissionsGroupExecute | ePermissionsWorldExecute ),
+
+ ePermissionsEveryoneRW = (ePermissionsEveryoneR | ePermissionsEveryoneW | 0 ),
+ ePermissionsEveryoneRX = (ePermissionsEveryoneR | 0 | ePermissionsEveryoneX ),
+ ePermissionsEveryoneRWX = (ePermissionsEveryoneR | ePermissionsEveryoneW | ePermissionsEveryoneX ),
+ ePermissionsDefault = (ePermissionsUserRW | ePermissionsGroupRead)
+ };
+
+ File() :
+ m_descriptor (kInvalidDescriptor),
+ m_stream (kInvalidStream),
+ m_options (0),
+ m_owned (false)
+ {
+ }
+
+ File (FILE *fh, bool transfer_ownership) :
+ m_descriptor (kInvalidDescriptor),
+ m_stream (fh),
+ m_options (0),
+ m_owned (transfer_ownership)
+ {
+ }
+
+ File (const File &rhs);
+
+ File &
+ operator= (const File &rhs);
+ //------------------------------------------------------------------
+ /// Constructor with path.
+ ///
+ /// Takes a path to a file which can be just a filename, or a full
+ /// path. If \a path is not NULL or empty, this function will call
+ /// File::Open (const char *path, uint32_t options, uint32_t permissions).
+ ///
+ /// @param[in] path
+ /// The full or partial path to a file.
+ ///
+ /// @param[in] options
+ /// Options to use when opening (see File::OpenOptions)
+ ///
+ /// @param[in] permissions
+ /// Options to use when opening (see File::Permissions)
+ ///
+ /// @see File::Open (const char *path, uint32_t options, uint32_t permissions)
+ //------------------------------------------------------------------
+ File (const char *path,
+ uint32_t options,
+ uint32_t permissions = ePermissionsDefault);
+
+
+ File (int fd, bool tranfer_ownership) :
+ m_descriptor (fd),
+ m_stream (kInvalidStream),
+ m_options (0),
+ m_owned (tranfer_ownership)
+ {
+ }
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual in case this class is subclassed.
+ //------------------------------------------------------------------
+ virtual
+ ~File ();
+
+ bool
+ IsValid () const
+ {
+ return DescriptorIsValid() || StreamIsValid();
+ }
+
+ //------------------------------------------------------------------
+ /// Convert to pointer operator.
+ ///
+ /// This allows code to check a File object to see if it
+ /// contains anything valid using code such as:
+ ///
+ /// @code
+ /// File file(...);
+ /// if (file)
+ /// { ...
+ /// @endcode
+ ///
+ /// @return
+ /// A pointer to this object if either the directory or filename
+ /// is valid, NULL otherwise.
+ //------------------------------------------------------------------
+ operator
+ bool () const
+ {
+ return DescriptorIsValid() || StreamIsValid();
+ }
+
+ //------------------------------------------------------------------
+ /// Logical NOT operator.
+ ///
+ /// This allows code to check a File object to see if it is
+ /// invalid using code such as:
+ ///
+ /// @code
+ /// File file(...);
+ /// if (!file)
+ /// { ...
+ /// @endcode
+ ///
+ /// @return
+ /// Returns \b true if the object has an empty directory and
+ /// filename, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ operator! () const
+ {
+ return !DescriptorIsValid() && !StreamIsValid();
+ }
+
+ //------------------------------------------------------------------
+ /// Get the file spec for this file.
+ ///
+ /// @return
+ /// A reference to the file specification object.
+ //------------------------------------------------------------------
+ Error
+ GetFileSpec (FileSpec &file_spec) const;
+
+ //------------------------------------------------------------------
+ /// Open a file for read/writing with the specified options.
+ ///
+ /// Takes a path to a file which can be just a filename, or a full
+ /// path.
+ ///
+ /// @param[in] path
+ /// The full or partial path to a file.
+ ///
+ /// @param[in] options
+ /// Options to use when opening (see File::OpenOptions)
+ ///
+ /// @param[in] permissions
+ /// Options to use when opening (see File::Permissions)
+ //------------------------------------------------------------------
+ Error
+ Open (const char *path,
+ uint32_t options,
+ uint32_t permissions = ePermissionsDefault);
+
+ Error
+ Close ();
+
+ Error
+ Duplicate (const File &rhs);
+
+ int
+ GetDescriptor() const;
+
+ void
+ SetDescriptor(int fd, bool transfer_ownership);
+
+ FILE *
+ GetStream ();
+
+ void
+ SetStream (FILE *fh, bool transfer_ownership);
+
+ //------------------------------------------------------------------
+ /// Read bytes from a file from the current file position.
+ ///
+ /// NOTE: This function is NOT thread safe. Use the read function
+ /// that takes an "off_t &offset" to ensure correct operation in
+ /// multi-threaded environments.
+ ///
+ /// @param[in] buf
+ /// A buffer where to put the bytes that are read.
+ ///
+ /// @param[in/out] num_bytes
+ /// The number of bytes to read form the current file position
+ /// which gets modified with the number of bytes that were read.
+ ///
+ /// @return
+ /// An error object that indicates success or the reason for
+ /// failure.
+ //------------------------------------------------------------------
+ Error
+ Read (void *buf, size_t &num_bytes);
+
+ //------------------------------------------------------------------
+ /// Write bytes to a file at the current file position.
+ ///
+ /// NOTE: This function is NOT thread safe. Use the write function
+ /// that takes an "off_t &offset" to ensure correct operation in
+ /// multi-threaded environments.
+ ///
+ /// @param[in] buf
+ /// A buffer where to put the bytes that are read.
+ ///
+ /// @param[in/out] num_bytes
+ /// The number of bytes to write to the current file position
+ /// which gets modified with the number of bytes that were
+ /// written.
+ ///
+ /// @return
+ /// An error object that indicates success or the reason for
+ /// failure.
+ //------------------------------------------------------------------
+ Error
+ Write (const void *buf, size_t &num_bytes);
+
+ //------------------------------------------------------------------
+ /// Seek to an offset relative to the beginning of the file.
+ ///
+ /// NOTE: This function is NOT thread safe, other threads that
+ /// access this object might also change the current file position.
+ /// For thread safe reads and writes see the following functions:
+ /// @see File::Read (void *, size_t, off_t &)
+ /// @see File::Write (const void *, size_t, off_t &)
+ ///
+ /// @param[in] offset
+ /// The offset to seek to within the file relative to the
+ /// beginning of the file.
+ ///
+ /// @param[in] error_ptr
+ /// A pointer to a lldb_private::Error object that will be
+ /// filled in if non-NULL.
+ ///
+ /// @return
+ /// The resulting seek offset, or -1 on error.
+ //------------------------------------------------------------------
+ off_t
+ SeekFromStart (off_t offset, Error *error_ptr = NULL);
+
+ //------------------------------------------------------------------
+ /// Seek to an offset relative to the current file position.
+ ///
+ /// NOTE: This function is NOT thread safe, other threads that
+ /// access this object might also change the current file position.
+ /// For thread safe reads and writes see the following functions:
+ /// @see File::Read (void *, size_t, off_t &)
+ /// @see File::Write (const void *, size_t, off_t &)
+ ///
+ /// @param[in] offset
+ /// The offset to seek to within the file relative to the
+ /// current file position.
+ ///
+ /// @param[in] error_ptr
+ /// A pointer to a lldb_private::Error object that will be
+ /// filled in if non-NULL.
+ ///
+ /// @return
+ /// The resulting seek offset, or -1 on error.
+ //------------------------------------------------------------------
+ off_t
+ SeekFromCurrent (off_t offset, Error *error_ptr = NULL);
+
+ //------------------------------------------------------------------
+ /// Seek to an offset relative to the end of the file.
+ ///
+ /// NOTE: This function is NOT thread safe, other threads that
+ /// access this object might also change the current file position.
+ /// For thread safe reads and writes see the following functions:
+ /// @see File::Read (void *, size_t, off_t &)
+ /// @see File::Write (const void *, size_t, off_t &)
+ ///
+ /// @param[in/out] offset
+ /// The offset to seek to within the file relative to the
+ /// end of the file which gets filled in the the resulting
+ /// absolute file offset.
+ ///
+ /// @param[in] error_ptr
+ /// A pointer to a lldb_private::Error object that will be
+ /// filled in if non-NULL.
+ ///
+ /// @return
+ /// The resulting seek offset, or -1 on error.
+ //------------------------------------------------------------------
+ off_t
+ SeekFromEnd (off_t offset, Error *error_ptr = NULL);
+
+ //------------------------------------------------------------------
+ /// Read bytes from a file from the specified file offset.
+ ///
+ /// NOTE: This function is thread safe in that clients manager their
+ /// own file position markers and reads on other threads won't mess
+ /// up the current read.
+ ///
+ /// @param[in] buf
+ /// A buffer where to put the bytes that are read.
+ ///
+ /// @param[in/out] num_bytes
+ /// The number of bytes to read form the current file position
+ /// which gets modified with the number of bytes that were read.
+ ///
+ /// @param[in/out] offset
+ /// The offset within the file from which to read \a num_bytes
+ /// bytes. This offset gets incremented by the number of bytes
+ /// that were read.
+ ///
+ /// @return
+ /// An error object that indicates success or the reason for
+ /// failure.
+ //------------------------------------------------------------------
+ Error
+ Read (void *dst, size_t &num_bytes, off_t &offset);
+
+ //------------------------------------------------------------------
+ /// Read bytes from a file from the specified file offset.
+ ///
+ /// NOTE: This function is thread safe in that clients manager their
+ /// own file position markers and reads on other threads won't mess
+ /// up the current read.
+ ///
+ /// @param[in/out] num_bytes
+ /// The number of bytes to read form the current file position
+ /// which gets modified with the number of bytes that were read.
+ ///
+ /// @param[in/out] offset
+ /// The offset within the file from which to read \a num_bytes
+ /// bytes. This offset gets incremented by the number of bytes
+ /// that were read.
+ ///
+ /// @param[in] null_terminate
+ /// Ensure that the data that is read is terminated with a NULL
+ /// character so that the data can be used as a C string.
+ ///
+ /// @param[out] data_buffer_sp
+ /// A data buffer to create and fill in that will contain any
+ /// data that is read from the file. This buffer will be reset
+ /// if an error occurs.
+ ///
+ /// @return
+ /// An error object that indicates success or the reason for
+ /// failure.
+ //------------------------------------------------------------------
+ Error
+ Read (size_t &num_bytes,
+ off_t &offset,
+ bool null_terminate,
+ lldb::DataBufferSP &data_buffer_sp);
+
+ //------------------------------------------------------------------
+ /// Write bytes to a file at the specified file offset.
+ ///
+ /// NOTE: This function is thread safe in that clients manager their
+ /// own file position markers, though clients will need to implement
+ /// their own locking externally to avoid multiple people writing
+ /// to the file at the same time.
+ ///
+ /// @param[in] buf
+ /// A buffer containing the bytes to write.
+ ///
+ /// @param[in/out] num_bytes
+ /// The number of bytes to write to the file at offset \a offset.
+ /// \a num_bytes gets modified with the number of bytes that
+ /// were read.
+ ///
+ /// @param[in/out] offset
+ /// The offset within the file at which to write \a num_bytes
+ /// bytes. This offset gets incremented by the number of bytes
+ /// that were written.
+ ///
+ /// @return
+ /// An error object that indicates success or the reason for
+ /// failure.
+ //------------------------------------------------------------------
+ Error
+ Write (const void *src, size_t &num_bytes, off_t &offset);
+
+ //------------------------------------------------------------------
+ /// Flush the current stream
+ ///
+ /// @return
+ /// An error object that indicates success or the reason for
+ /// failure.
+ //------------------------------------------------------------------
+ Error
+ Flush ();
+
+ //------------------------------------------------------------------
+ /// Sync to disk.
+ ///
+ /// @return
+ /// An error object that indicates success or the reason for
+ /// failure.
+ //------------------------------------------------------------------
+ Error
+ Sync ();
+
+ //------------------------------------------------------------------
+ /// Output printf formatted output to the stream.
+ ///
+ /// Print some formatted output to the stream.
+ ///
+ /// @param[in] format
+ /// A printf style format string.
+ ///
+ /// @param[in] ...
+ /// Variable arguments that are needed for the printf style
+ /// format string \a format.
+ //------------------------------------------------------------------
+ size_t
+ Printf (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ size_t
+ PrintfVarArg(const char *format, va_list args);
+
+protected:
+
+
+ bool
+ DescriptorIsValid () const
+ {
+ return m_descriptor >= 0;
+ }
+
+ bool
+ StreamIsValid () const
+ {
+ return m_stream != kInvalidStream;
+ }
+
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ int m_descriptor;
+ FILE *m_stream;
+ uint32_t m_options;
+ bool m_owned;
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_File_h_
diff --git a/include/lldb/Host/FileSpec.h b/include/lldb/Host/FileSpec.h
new file mode 100644
index 000000000000..c58be9ec09d5
--- /dev/null
+++ b/include/lldb/Host/FileSpec.h
@@ -0,0 +1,692 @@
+//===-- FileSpec.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_FileSpec_h_
+#define liblldb_FileSpec_h_
+#if defined(__cplusplus)
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/STLUtils.h"
+#include "lldb/Host/TimeValue.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class FileSpec FileSpec.h "lldb/Host/FileSpec.h"
+/// @brief A file utility class.
+///
+/// A file specification class that divides paths up into a directory
+/// and basename. These string values of the paths are put into uniqued
+/// string pools for fast comparisons and efficient memory usage.
+///
+/// Another reason the paths are split into the directory and basename
+/// is to allow efficient debugger searching. Often in a debugger the
+/// user types in the basename of the file, for example setting a
+/// breakpoint by file and line, or specifying a module (shared library)
+/// to limit the scope in which to execute a command. The user rarely
+/// types in a full path. When the paths are already split up, it makes
+/// it easy for us to compare only the basenames of a lot of file
+/// specifications without having to split up the file path each time
+/// to get to the basename.
+//----------------------------------------------------------------------
+class FileSpec
+{
+public:
+ typedef enum FileType
+ {
+ eFileTypeInvalid = -1,
+ eFileTypeUnknown = 0,
+ eFileTypeDirectory,
+ eFileTypePipe,
+ eFileTypeRegular,
+ eFileTypeSocket,
+ eFileTypeSymbolicLink,
+ eFileTypeOther
+ } FileType;
+
+ FileSpec();
+
+ //------------------------------------------------------------------
+ /// Constructor with path.
+ ///
+ /// Takes a path to a file which can be just a filename, or a full
+ /// path. If \a path is not NULL or empty, this function will call
+ /// FileSpec::SetFile (const char *path, bool resolve).
+ ///
+ /// @param[in] path
+ /// The full or partial path to a file.
+ ///
+ /// @param[in] resolve_path
+ /// If \b true, then we resolve the path with realpath,
+ /// if \b false we trust the path is in canonical form already.
+ ///
+ /// @see FileSpec::SetFile (const char *path, bool resolve)
+ //------------------------------------------------------------------
+ explicit FileSpec (const char *path, bool resolve_path);
+
+ //------------------------------------------------------------------
+ /// Copy constructor
+ ///
+ /// Makes a copy of the uniqued directory and filename strings from
+ /// \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A const FileSpec object reference to copy.
+ //------------------------------------------------------------------
+ FileSpec (const FileSpec& rhs);
+
+ //------------------------------------------------------------------
+ /// Copy constructor
+ ///
+ /// Makes a copy of the uniqued directory and filename strings from
+ /// \a rhs if it is not NULL.
+ ///
+ /// @param[in] rhs
+ /// A const FileSpec object pointer to copy if non-NULL.
+ //------------------------------------------------------------------
+ FileSpec (const FileSpec* rhs);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~FileSpec ();
+
+ //------------------------------------------------------------------
+ /// Assignment operator.
+ ///
+ /// Makes a copy of the uniqued directory and filename strings from
+ /// \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A const FileSpec object reference to assign to this object.
+ ///
+ /// @return
+ /// A const reference to this object.
+ //------------------------------------------------------------------
+ const FileSpec&
+ operator= (const FileSpec& rhs);
+
+ //------------------------------------------------------------------
+ /// Equal to operator
+ ///
+ /// Tests if this object is equal to \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A const FileSpec object reference to compare this object
+ /// to.
+ ///
+ /// @return
+ /// \b true if this object is equal to \a rhs, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ operator== (const FileSpec& rhs) const;
+
+ //------------------------------------------------------------------
+ /// Not equal to operator
+ ///
+ /// Tests if this object is not equal to \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A const FileSpec object reference to compare this object
+ /// to.
+ ///
+ /// @return
+ /// \b true if this object is equal to \a rhs, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ operator!= (const FileSpec& rhs) const;
+
+ //------------------------------------------------------------------
+ /// Less than to operator
+ ///
+ /// Tests if this object is less than \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A const FileSpec object reference to compare this object
+ /// to.
+ ///
+ /// @return
+ /// \b true if this object is less than \a rhs, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ operator< (const FileSpec& rhs) const;
+
+ //------------------------------------------------------------------
+ /// Convert to pointer operator.
+ ///
+ /// This allows code to check a FileSpec object to see if it
+ /// contains anything valid using code such as:
+ ///
+ /// @code
+ /// FileSpec file_spec(...);
+ /// if (file_spec)
+ /// { ...
+ /// @endcode
+ ///
+ /// @return
+ /// A pointer to this object if either the directory or filename
+ /// is valid, NULL otherwise.
+ //------------------------------------------------------------------
+ operator bool() const;
+
+ //------------------------------------------------------------------
+ /// Logical NOT operator.
+ ///
+ /// This allows code to check a FileSpec object to see if it is
+ /// invalid using code such as:
+ ///
+ /// @code
+ /// FileSpec file_spec(...);
+ /// if (!file_spec)
+ /// { ...
+ /// @endcode
+ ///
+ /// @return
+ /// Returns \b true if the object has an empty directory and
+ /// filename, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ operator! () const;
+
+ //------------------------------------------------------------------
+ /// Clears the object state.
+ ///
+ /// Clear this object by releasing both the directory and filename
+ /// string values and reverting them to empty strings.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Compare two FileSpec objects.
+ ///
+ /// If \a full is true, then both the directory and the filename
+ /// must match. If \a full is false, then the directory names for
+ /// \a lhs and \a rhs are only compared if they are both not empty.
+ /// This allows a FileSpec object to only contain a filename
+ /// and it can match FileSpec objects that have matching
+ /// filenames with different paths.
+ ///
+ /// @param[in] lhs
+ /// A const reference to the Left Hand Side object to compare.
+ ///
+ /// @param[in] rhs
+ /// A const reference to the Right Hand Side object to compare.
+ ///
+ /// @param[in] full
+ /// If true, then both the directory and filenames will have to
+ /// match for a compare to return zero (equal to). If false
+ /// and either directory from \a lhs or \a rhs is empty, then
+ /// only the filename will be compared, else a full comparison
+ /// is done.
+ ///
+ /// @return
+ /// @li -1 if \a lhs is less than \a rhs
+ /// @li 0 if \a lhs is equal to \a rhs
+ /// @li 1 if \a lhs is greater than \a rhs
+ //------------------------------------------------------------------
+ static int
+ Compare (const FileSpec& lhs, const FileSpec& rhs, bool full);
+
+ static bool
+ Equal (const FileSpec& a, const FileSpec& b, bool full);
+
+ //------------------------------------------------------------------
+ /// Dump this object to a Stream.
+ ///
+ /// Dump the object to the supplied stream \a s. If the object
+ /// contains a valid directory name, it will be displayed followed
+ /// by a directory delimiter, and the filename.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s) const;
+
+ //------------------------------------------------------------------
+ /// Existence test.
+ ///
+ /// @return
+ /// \b true if the file exists on disk, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Exists () const;
+
+
+ //------------------------------------------------------------------
+ /// Expanded existence test.
+ ///
+ /// Call into the Host to see if it can help find the file (e.g. by
+ /// searching paths set in the environment, etc.).
+ ///
+ /// If found, sets the value of m_directory to the directory where
+ /// the file was found.
+ ///
+ /// @return
+ /// \b true if was able to find the file using expanded search
+ /// methods, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ResolveExecutableLocation ();
+
+ //------------------------------------------------------------------
+ /// Canonicalize this file path (basically running the static
+ /// FileSpec::Resolve method on it). Useful if you asked us not to
+ /// resolve the file path when you set the file.
+ //------------------------------------------------------------------
+ bool
+ ResolvePath ();
+
+ uint64_t
+ GetByteSize() const;
+
+ //------------------------------------------------------------------
+ /// Directory string get accessor.
+ ///
+ /// @return
+ /// A reference to the directory string object.
+ //------------------------------------------------------------------
+ ConstString &
+ GetDirectory ();
+
+ //------------------------------------------------------------------
+ /// Directory string const get accessor.
+ ///
+ /// @return
+ /// A const reference to the directory string object.
+ //------------------------------------------------------------------
+ const ConstString &
+ GetDirectory () const;
+
+ //------------------------------------------------------------------
+ /// Filename string get accessor.
+ ///
+ /// @return
+ /// A reference to the filename string object.
+ //------------------------------------------------------------------
+ ConstString &
+ GetFilename ();
+
+ //------------------------------------------------------------------
+ /// Filename string const get accessor.
+ ///
+ /// @return
+ /// A const reference to the filename string object.
+ //------------------------------------------------------------------
+ const ConstString &
+ GetFilename () const;
+
+ //------------------------------------------------------------------
+ /// Returns true if the filespec represents an implementation source
+ /// file (files with a ".c", ".cpp", ".m", ".mm" (many more)
+ /// extension).
+ ///
+ /// @return
+ /// \b true if the filespec represents an implementation source
+ /// file, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsSourceImplementationFile () const;
+
+ //------------------------------------------------------------------
+ /// Returns true if the filespec represents path that is relative
+ /// path to the current working directory.
+ ///
+ /// @return
+ /// \b true if the filespec represents a current working
+ /// directory relative path, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsRelativeToCurrentWorkingDirectory () const;
+
+ TimeValue
+ GetModificationTime () const;
+
+ //------------------------------------------------------------------
+ /// Extract the full path to the file.
+ ///
+ /// Extract the directory and path into a fixed buffer. This is
+ /// needed as the directory and path are stored in separate string
+ /// values.
+ ///
+ /// @param[out] path
+ /// The buffer in which to place the extracted full path.
+ ///
+ /// @param[in] max_path_length
+ /// The maximum length of \a path.
+ ///
+ /// @return
+ /// Returns the number of characters that would be needed to
+ /// properly copy the full path into \a path. If the returned
+ /// number is less than \a max_path_length, then the path is
+ /// properly copied and terminated. If the return value is
+ /// >= \a max_path_length, then the path was truncated (but is
+ /// still NULL terminated).
+ //------------------------------------------------------------------
+ size_t
+ GetPath (char *path, size_t max_path_length) const;
+
+ //------------------------------------------------------------------
+ /// Extract the full path to the file.
+ ///
+ /// Extract the directory and path into a std::string, which is returned.
+ ///
+ /// @return
+ /// Returns a std::string with the directory and filename
+ /// concatenated.
+ //------------------------------------------------------------------
+ std::string
+ GetPath () const;
+
+ //------------------------------------------------------------------
+ /// Extract the extension of the file.
+ ///
+ /// Returns a ConstString that represents the extension of the filename
+ /// for this FileSpec object. If this object does not represent a file,
+ /// or the filename has no extension, ConstString(NULL) is returned.
+ /// The dot ('.') character is not returned as part of the extension
+ ///
+ /// @return
+ /// Returns the extension of the file as a ConstString object.
+ //------------------------------------------------------------------
+ ConstString
+ GetFileNameExtension () const;
+
+ //------------------------------------------------------------------
+ /// Return the filename without the extension part
+ ///
+ /// Returns a ConstString that represents the filename of this object
+ /// without the extension part (e.g. for a file named "foo.bar", "foo"
+ /// is returned)
+ ///
+ /// @return
+ /// Returns the filename without extension
+ /// as a ConstString object.
+ //------------------------------------------------------------------
+ ConstString
+ GetFileNameStrippingExtension () const;
+
+ FileType
+ GetFileType () const;
+
+ bool
+ IsDirectory () const
+ {
+ return GetFileType() == FileSpec::eFileTypeDirectory;
+ }
+
+ bool
+ IsPipe () const
+ {
+ return GetFileType() == FileSpec::eFileTypePipe;
+ }
+
+ bool
+ IsRegularFile () const
+ {
+ return GetFileType() == FileSpec::eFileTypeRegular;
+ }
+
+ bool
+ IsSocket () const
+ {
+ return GetFileType() == FileSpec::eFileTypeSocket;
+ }
+
+ bool
+ IsSymbolicLink () const
+ {
+ return GetFileType() == FileSpec::eFileTypeSymbolicLink;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// Return the size in bytes that this object takes in memory. This
+ /// returns the size in bytes of this object, not any shared string
+ /// values it may refer to.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ size_t
+ MemorySize () const;
+
+ //------------------------------------------------------------------
+ /// Memory map part of, or the entire contents of, a file.
+ ///
+ /// Returns a shared pointer to a data buffer that contains all or
+ /// part of the contents of a file. The data is memory mapped and
+ /// will lazily page in data from the file as memory is accessed.
+ /// The data that is mappped will start \a offset bytes into the
+ /// file, and \a length bytes will be mapped. If \a length is
+ /// greater than the number of bytes available in the file starting
+ /// at \a offset, the number of bytes will be appropriately
+ /// truncated. The final number of bytes that get mapped can be
+ /// verified using the DataBuffer::GetByteSize() function on the return
+ /// shared data pointer object contents.
+ ///
+ /// @param[in] offset
+ /// The offset in bytes from the beginning of the file where
+ /// memory mapping should begin.
+ ///
+ /// @param[in] length
+ /// The size in bytes that should be mapped starting \a offset
+ /// bytes into the file. If \a length is \c SIZE_MAX, map
+ /// as many bytes as possible.
+ ///
+ /// @return
+ /// A shared pointer to the memeory mapped data. This shared
+ /// pointer can contain a NULL DataBuffer pointer, so the contained
+ /// pointer must be checked prior to using it.
+ //------------------------------------------------------------------
+ lldb::DataBufferSP
+ MemoryMapFileContents (off_t offset = 0, size_t length = SIZE_MAX) const;
+
+ //------------------------------------------------------------------
+ /// Read part of, or the entire contents of, a file into a heap based data buffer.
+ ///
+ /// Returns a shared pointer to a data buffer that contains all or
+ /// part of the contents of a file. The data copies into a heap based
+ /// buffer that lives in the DataBuffer shared pointer object returned.
+ /// The data that is cached will start \a offset bytes into the
+ /// file, and \a length bytes will be mapped. If \a length is
+ /// greater than the number of bytes available in the file starting
+ /// at \a offset, the number of bytes will be appropriately
+ /// truncated. The final number of bytes that get mapped can be
+ /// verified using the DataBuffer::GetByteSize() function.
+ ///
+ /// @param[in] offset
+ /// The offset in bytes from the beginning of the file where
+ /// memory mapping should begin.
+ ///
+ /// @param[in] length
+ /// The size in bytes that should be mapped starting \a offset
+ /// bytes into the file. If \a length is \c SIZE_MAX, map
+ /// as many bytes as possible.
+ ///
+ /// @return
+ /// A shared pointer to the memeory mapped data. This shared
+ /// pointer can contain a NULL DataBuffer pointer, so the contained
+ /// pointer must be checked prior to using it.
+ //------------------------------------------------------------------
+ lldb::DataBufferSP
+ ReadFileContents (off_t offset = 0, size_t length = SIZE_MAX, Error *error_ptr = NULL) const;
+
+ size_t
+ ReadFileContents (off_t file_offset, void *dst, size_t dst_len, Error *error_ptr) const;
+
+
+ //------------------------------------------------------------------
+ /// Read the entire contents of a file as data that can be used
+ /// as a C string.
+ ///
+ /// Read the entire contents of a file and ensure that the data
+ /// is NULL terminated so it can be used as a C string.
+ ///
+ /// @return
+ /// A shared pointer to the data. This shared pointer can
+ /// contain a NULL DataBuffer pointer, so the contained pointer
+ /// must be checked prior to using it.
+ //------------------------------------------------------------------
+ lldb::DataBufferSP
+ ReadFileContentsAsCString(Error *error_ptr = NULL);
+ //------------------------------------------------------------------
+ /// Change the file specificed with a new path.
+ ///
+ /// Update the contents of this object with a new path. The path will
+ /// be split up into a directory and filename and stored as uniqued
+ /// string values for quick comparison and efficient memory usage.
+ ///
+ /// @param[in] path
+ /// A full, partial, or relative path to a file.
+ ///
+ /// @param[in] resolve_path
+ /// If \b true, then we will try to resolve links the path using
+ /// the static FileSpec::Resolve.
+ //------------------------------------------------------------------
+ void
+ SetFile (const char *path, bool resolve_path);
+
+ bool
+ IsResolved () const
+ {
+ return m_is_resolved;
+ }
+
+ //------------------------------------------------------------------
+ /// Set if the file path has been resolved or not.
+ ///
+ /// If you know a file path is already resolved and avoided passing
+ /// a \b true parameter for any functions that take a "bool
+ /// resolve_path" parameter, you can set the value manually using
+ /// this call to make sure we don't try and resolve it later, or try
+ /// and resolve a path that has already been resolved.
+ ///
+ /// @param[in] is_resolved
+ /// A boolean value that will replace the current value that
+ /// indicates if the paths in this object have been resolved.
+ //------------------------------------------------------------------
+ void
+ SetIsResolved (bool is_resolved)
+ {
+ m_is_resolved = is_resolved;
+ }
+ //------------------------------------------------------------------
+ /// Read the file into an array of strings, one per line.
+ ///
+ /// Opens and reads the file in this object into an array of strings,
+ /// one string per line of the file. Returns a boolean indicating
+ /// success or failure.
+ ///
+ /// @param[out] lines
+ /// The string array into which to read the file.
+ ///
+ /// @result
+ /// Returns the number of lines that were read from the file.
+ //------------------------------------------------------------------
+ size_t
+ ReadFileLines (STLStringArray &lines);
+
+ //------------------------------------------------------------------
+ /// Resolves user name and links in \a src_path, and writes the output
+ /// to \a dst_path. Note if the path pointed to by \a src_path does not
+ /// exist, the contents of \a src_path will be copied to \a dst_path
+ /// unchanged.
+ ///
+ /// @param[in] src_path
+ /// Input path to be resolved.
+ ///
+ /// @param[in] dst_path
+ /// Buffer to store the resolved path.
+ ///
+ /// @param[in] dst_len
+ /// Size of the buffer pointed to by dst_path.
+ ///
+ /// @result
+ /// The number of characters required to write the resolved path. If the
+ /// resolved path doesn't fit in dst_len, dst_len-1 characters will
+ /// be written to \a dst_path, but the actual required length will still be returned.
+ //------------------------------------------------------------------
+ static size_t
+ Resolve (const char *src_path, char *dst_path, size_t dst_len);
+
+ //------------------------------------------------------------------
+ /// Resolves the user name at the beginning of \a src_path, and writes the output
+ /// to \a dst_path. Note, \a src_path can contain other path components after the
+ /// user name, they will be copied over, and if the path doesn't start with "~" it
+ /// will also be copied over to \a dst_path.
+ ///
+ /// @param[in] src_path
+ /// Input path to be resolved.
+ ///
+ /// @param[in] dst_path
+ /// Buffer to store the resolved path.
+ ///
+ /// @param[in] dst_len
+ /// Size of the buffer pointed to by dst_path.
+ ///
+ /// @result
+ /// The number of characters required to write the resolved path, or 0 if
+ /// the user name could not be found. If the
+ /// resolved path doesn't fit in dst_len, dst_len-1 characters will
+ /// be written to \a dst_path, but the actual required length will still be returned.
+ //------------------------------------------------------------------
+ static size_t
+ ResolveUsername (const char *src_path, char *dst_path, size_t dst_len);
+
+ static size_t
+ ResolvePartialUsername (const char *partial_name, StringList &matches);
+
+ enum EnumerateDirectoryResult
+ {
+ eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory
+ eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not
+ eEnumerateDirectoryResultExit, // Exit from the current directory at the current level.
+ eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
+ };
+
+ typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
+ FileType file_type,
+ const FileSpec &spec
+);
+
+ static EnumerateDirectoryResult
+ EnumerateDirectory (const char *dir_path,
+ bool find_directories,
+ bool find_files,
+ bool find_other,
+ EnumerateDirectoryCallbackType callback,
+ void *callback_baton);
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ ConstString m_directory; ///< The uniqued directory path
+ ConstString m_filename; ///< The uniqued filename path
+ mutable bool m_is_resolved; ///< True if this path has been resolved.
+};
+
+//----------------------------------------------------------------------
+/// Dump a FileSpec object to a stream
+//----------------------------------------------------------------------
+Stream& operator << (Stream& s, const FileSpec& f);
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_FileSpec_h_
diff --git a/include/lldb/Host/Host.h b/include/lldb/Host/Host.h
new file mode 100644
index 000000000000..547bdd5d637b
--- /dev/null
+++ b/include/lldb/Host/Host.h
@@ -0,0 +1,502 @@
+//===-- Host.h --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_h_
+#define liblldb_Host_h_
+#if defined(__cplusplus)
+
+#include <stdarg.h>
+
+#include <map>
+#include <string>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/StringList.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Host Host.h "lldb/Host/Host.h"
+/// @brief A class that provides host computer information.
+///
+/// Host is a class that answers information about the host operating
+/// system.
+//----------------------------------------------------------------------
+class Host
+{
+public:
+ typedef bool (*MonitorChildProcessCallback) (void *callback_baton,
+ lldb::pid_t pid,
+ bool exited,
+ int signal, // Zero for no signal
+ int status); // Exit value of process if signal is zero
+
+ //------------------------------------------------------------------
+ /// Start monitoring a child process.
+ ///
+ /// Allows easy monitoring of child processes. \a callback will be
+ /// called when the child process exits or if it gets a signal. The
+ /// callback will only be called with signals if \a monitor_signals
+ /// is \b true. \a callback will usually be called from another
+ /// thread so the callback function must be thread safe.
+ ///
+ /// When the callback gets called, the return value indicates if
+ /// minotoring should stop. If \b true is returned from \a callback
+ /// the information will be removed. If \b false is returned then
+ /// monitoring will continue. If the child process exits, the
+ /// monitoring will automatically stop after the callback returned
+ /// ragardless of the callback return value.
+ ///
+ /// @param[in] callback
+ /// A function callback to call when a child receives a signal
+ /// (if \a monitor_signals is true) or a child exits.
+ ///
+ /// @param[in] callback_baton
+ /// A void * of user data that will be pass back when
+ /// \a callback is called.
+ ///
+ /// @param[in] pid
+ /// The process ID of a child process to monitor, -1 for all
+ /// processes.
+ ///
+ /// @param[in] monitor_signals
+ /// If \b true the callback will get called when the child
+ /// process gets a signal. If \b false, the callback will only
+ /// get called if the child process exits.
+ ///
+ /// @return
+ /// A thread handle that can be used to cancel the thread that
+ /// was spawned to monitor \a pid.
+ ///
+ /// @see static void Host::StopMonitoringChildProcess (uint32_t)
+ //------------------------------------------------------------------
+ static lldb::thread_t
+ StartMonitoringChildProcess (MonitorChildProcessCallback callback,
+ void *callback_baton,
+ lldb::pid_t pid,
+ bool monitor_signals);
+
+ //------------------------------------------------------------------
+ /// Get the host page size.
+ ///
+ /// @return
+ /// The size in bytes of a VM page on the host system.
+ //------------------------------------------------------------------
+ static size_t
+ GetPageSize();
+
+ //------------------------------------------------------------------
+ /// Returns the endianness of the host system.
+ ///
+ /// @return
+ /// Returns the endianness of the host system as a lldb::ByteOrder
+ /// enumeration.
+ //------------------------------------------------------------------
+ static lldb::ByteOrder
+ GetByteOrder ();
+
+ //------------------------------------------------------------------
+ /// Returns the number of CPUs on this current host.
+ ///
+ /// @return
+ /// Number of CPUs on this current host, or zero if the number
+ /// of CPUs can't be determined on this host.
+ //------------------------------------------------------------------
+ static uint32_t
+ GetNumberCPUS ();
+
+ static bool
+ GetOSVersion (uint32_t &major,
+ uint32_t &minor,
+ uint32_t &update);
+
+ static bool
+ GetOSBuildString (std::string &s);
+
+ static bool
+ GetOSKernelDescription (std::string &s);
+
+ static bool
+ GetHostname (std::string &s);
+
+ static const char *
+ GetUserName (uint32_t uid, std::string &user_name);
+
+ static const char *
+ GetGroupName (uint32_t gid, std::string &group_name);
+
+ static uint32_t
+ GetUserID ();
+
+ static uint32_t
+ GetGroupID ();
+
+ static uint32_t
+ GetEffectiveUserID ();
+
+ static uint32_t
+ GetEffectiveGroupID ();
+
+
+ enum SystemLogType
+ {
+ eSystemLogWarning,
+ eSystemLogError
+ };
+
+ static void
+ SystemLog (SystemLogType type, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ static void
+ SystemLog (SystemLogType type, const char *format, va_list args);
+
+ //------------------------------------------------------------------
+ /// Gets the host architecture.
+ ///
+ /// @return
+ /// A const architecture object that represents the host
+ /// architecture.
+ //------------------------------------------------------------------
+ enum SystemDefaultArchitecture
+ {
+ eSystemDefaultArchitecture, // The overall default architecture that applications will run on this host
+ eSystemDefaultArchitecture32, // If this host supports 32 bit programs, return the default 32 bit arch
+ eSystemDefaultArchitecture64 // If this host supports 64 bit programs, return the default 64 bit arch
+ };
+
+ static const ArchSpec &
+ GetArchitecture (SystemDefaultArchitecture arch_kind = eSystemDefaultArchitecture);
+
+ //------------------------------------------------------------------
+ /// Gets the host vendor string.
+ ///
+ /// @return
+ /// A const string object containing the host vendor name.
+ //------------------------------------------------------------------
+ static const ConstString &
+ GetVendorString ();
+
+ //------------------------------------------------------------------
+ /// Gets the host Operating System (OS) string.
+ ///
+ /// @return
+ /// A const string object containing the host OS name.
+ //------------------------------------------------------------------
+ static const ConstString &
+ GetOSString ();
+
+ //------------------------------------------------------------------
+ /// Gets the host target triple as a const string.
+ ///
+ /// @return
+ /// A const string object containing the host target triple.
+ //------------------------------------------------------------------
+ static const ConstString &
+ GetTargetTriple ();
+
+ //------------------------------------------------------------------
+ /// Get the process ID for the calling process.
+ ///
+ /// @return
+ /// The process ID for the current process.
+ //------------------------------------------------------------------
+ static lldb::pid_t
+ GetCurrentProcessID ();
+
+ //------------------------------------------------------------------
+ /// Get the thread ID for the calling thread in the current process.
+ ///
+ /// @return
+ /// The thread ID for the calling thread in the current process.
+ //------------------------------------------------------------------
+ static lldb::tid_t
+ GetCurrentThreadID ();
+
+ //------------------------------------------------------------------
+ /// Get the thread token (the one returned by ThreadCreate when the thread was created) for the
+ /// calling thread in the current process.
+ ///
+ /// @return
+ /// The thread token for the calling thread in the current process.
+ //------------------------------------------------------------------
+ static lldb::thread_t
+ GetCurrentThread ();
+
+ static const char *
+ GetSignalAsCString (int signo);
+
+ static void
+ WillTerminate ();
+ //------------------------------------------------------------------
+ /// Host specific thread created function call.
+ ///
+ /// This function call lets the current host OS do any thread
+ /// specific initialization that it needs, including naming the
+ /// thread. No cleanup routine is exptected to be called
+ ///
+ /// @param[in] name
+ /// The current thread's name in the current process.
+ //------------------------------------------------------------------
+ static void
+ ThreadCreated (const char *name);
+
+ static lldb::thread_t
+ ThreadCreate (const char *name,
+ lldb::thread_func_t function,
+ lldb::thread_arg_t thread_arg,
+ Error *err);
+
+ static bool
+ ThreadCancel (lldb::thread_t thread,
+ Error *error);
+
+ static bool
+ ThreadDetach (lldb::thread_t thread,
+ Error *error);
+ static bool
+ ThreadJoin (lldb::thread_t thread,
+ lldb::thread_result_t *thread_result_ptr,
+ Error *error);
+
+ //------------------------------------------------------------------
+ /// Gets the name of a thread in a process.
+ ///
+ /// This function will name a thread in a process using it's own
+ /// thread name pool, and also will attempt to set a thread name
+ /// using any supported host OS APIs.
+ ///
+ /// @param[in] pid
+ /// The process ID in which we are trying to get the name of
+ /// a thread.
+ ///
+ /// @param[in] tid
+ /// The thread ID for which we are trying retrieve the name of.
+ ///
+ /// @return
+ /// A std::string containing the thread name.
+ //------------------------------------------------------------------
+ static std::string
+ GetThreadName (lldb::pid_t pid, lldb::tid_t tid);
+
+ //------------------------------------------------------------------
+ /// Sets the name of a thread in the current process.
+ ///
+ /// @param[in] pid
+ /// The process ID in which we are trying to name a thread.
+ ///
+ /// @param[in] tid
+ /// The thread ID which we are trying to name.
+ ///
+ /// @param[in] name
+ /// The current thread's name in the current process to \a name.
+ ///
+ /// @return
+ /// \b true if the thread name was able to be set, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ static bool
+ SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name);
+
+ //------------------------------------------------------------------
+ /// Sets a shortened name of a thread in the current process.
+ ///
+ /// @param[in] pid
+ /// The process ID in which we are trying to name a thread.
+ ///
+ /// @param[in] tid
+ /// The thread ID which we are trying to name.
+ ///
+ /// @param[in] name
+ /// The current thread's name in the current process to \a name.
+ ///
+ /// @param[in] len
+ /// The maximum length for the thread's shortened name.
+ ///
+ /// @return
+ /// \b true if the thread name was able to be set, \b false
+ /// otherwise.
+ static bool
+ SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name, size_t len);
+
+ //------------------------------------------------------------------
+ /// Gets the FileSpec of the current process (the process that
+ /// that is running the LLDB code).
+ ///
+ /// @return
+ /// \b A file spec with the program name.
+ //------------------------------------------------------------------
+ static FileSpec
+ GetProgramFileSpec ();
+
+ //------------------------------------------------------------------
+ /// Given an address in the current process (the process that
+ /// is running the LLDB code), return the name of the module that
+ /// it comes from. This can be useful when you need to know the
+ /// path to the shared library that your code is running in for
+ /// loading resources that are relative to your binary.
+ ///
+ /// @param[in] host_addr
+ /// The pointer to some code in the current process.
+ ///
+ /// @return
+ /// \b A file spec with the module that contains \a host_addr,
+ /// which may be invalid if \a host_addr doesn't fall into
+ /// any valid module address range.
+ //------------------------------------------------------------------
+ static FileSpec
+ GetModuleFileSpecForHostAddress (const void *host_addr);
+
+
+
+ //------------------------------------------------------------------
+ /// If you have an executable that is in a bundle and want to get
+ /// back to the bundle directory from the path itself, this
+ /// function will change a path to a file within a bundle to the
+ /// bundle directory itself.
+ ///
+ /// @param[in] file
+ /// A file spec that might point to a file in a bundle.
+ ///
+ /// @param[out] bundle_directory
+ /// An object will be filled in with the bundle directory for
+ /// the bundle when \b true is returned. Otherwise \a file is
+ /// left untouched and \b false is returned.
+ ///
+ /// @return
+ /// \b true if \a file was resolved in \a bundle_directory,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ static bool
+ GetBundleDirectory (const FileSpec &file, FileSpec &bundle_directory);
+
+ //------------------------------------------------------------------
+ /// When executable files may live within a directory, where the
+ /// directory represents an executable bundle (like the MacOSX
+ /// app bundles), the locate the executable within the containing
+ /// bundle.
+ ///
+ /// @param[in,out] file
+ /// A file spec that currently points to the bundle that will
+ /// be filled in with the executable path within the bundle
+ /// if \b true is returned. Otherwise \a file is left untouched.
+ ///
+ /// @return
+ /// \b true if \a file was resolved, \b false if this function
+ /// was not able to resolve the path.
+ //------------------------------------------------------------------
+ static bool
+ ResolveExecutableInBundle (FileSpec &file);
+
+ //------------------------------------------------------------------
+ /// Find a resource files that are related to LLDB.
+ ///
+ /// Operating systems have different ways of storing shared
+ /// libraries and related resources. This function abstracts the
+ /// access to these paths.
+ ///
+ /// @param[in] path_type
+ /// The type of LLDB resource path you are looking for. If the
+ /// enumeration ends with "Dir", then only the \a file_spec's
+ /// directory member gets filled in.
+ ///
+ /// @param[in] file_spec
+ /// A file spec that gets filled in with the appriopriate path.
+ ///
+ /// @return
+ /// \b true if \a resource_path was resolved, \a false otherwise.
+ //------------------------------------------------------------------
+ static bool
+ GetLLDBPath (PathType path_type,
+ FileSpec &file_spec);
+
+ //------------------------------------------------------------------
+ /// Set a string that can be displayed if host application crashes.
+ ///
+ /// Some operating systems have the ability to print a description
+ /// for shared libraries when a program crashes. If the host OS
+ /// supports such a mechanism, it should be implemented to help
+ /// with crash triage.
+ ///
+ /// @param[in] format
+ /// A printf format that will be used to form a new crash
+ /// description string.
+ //------------------------------------------------------------------
+ static void
+ SetCrashDescriptionWithFormat (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
+
+ static void
+ SetCrashDescription (const char *description);
+
+ static uint32_t
+ FindProcesses (const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &proc_infos);
+
+ typedef std::map<lldb::pid_t, bool> TidMap;
+ typedef std::pair<lldb::pid_t, bool> TidPair;
+ static bool
+ FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach);
+
+ static bool
+ GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
+
+ static lldb::pid_t
+ LaunchApplication (const FileSpec &app_file_spec);
+
+ static Error
+ LaunchProcess (ProcessLaunchInfo &launch_info);
+
+ static Error
+ RunShellCommand (const char *command, // Shouldn't be NULL
+ const char *working_dir, // Pass NULL to use the current working directory
+ int *status_ptr, // Pass NULL if you don't want the process exit status
+ int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
+ std::string *command_output, // Pass NULL if you don't want the command output
+ uint32_t timeout_sec,
+ const char *shell = "/bin/bash");
+
+ static lldb::DataBufferSP
+ GetAuxvData (lldb_private::Process *process);
+
+ static lldb::TargetSP
+ GetDummyTarget (Debugger &debugger);
+
+ static bool
+ OpenFileInExternalEditor (const FileSpec &file_spec,
+ uint32_t line_no);
+
+ static void
+ Backtrace (Stream &strm, uint32_t max_frames);
+
+ static size_t
+ GetEnvironment (StringList &env);
+
+ enum DynamicLibraryOpenOptions
+ {
+ eDynamicLibraryOpenOptionLazy = (1u << 0), // Lazily resolve symbols in this dynamic library
+ eDynamicLibraryOpenOptionLocal = (1u << 1), // Only open a shared library with local access (hide it from the global symbol namespace)
+ eDynamicLibraryOpenOptionLimitGetSymbol = (1u << 2) // DynamicLibraryGetSymbol calls on this handle will only return matches from this shared library
+ };
+ static void *
+ DynamicLibraryOpen (const FileSpec &file_spec,
+ uint32_t options,
+ Error &error);
+
+ static Error
+ DynamicLibraryClose (void *dynamic_library_handle);
+
+ static void *
+ DynamicLibraryGetSymbol (void *dynamic_library_handle,
+ const char *symbol_name,
+ Error &error);
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_Host_h_
diff --git a/include/lldb/Host/Mutex.h b/include/lldb/Host/Mutex.h
new file mode 100644
index 000000000000..63f759efe366
--- /dev/null
+++ b/include/lldb/Host/Mutex.h
@@ -0,0 +1,312 @@
+//===-- Mutex.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Mutex_h_
+#define liblldb_Mutex_h_
+#if defined(__cplusplus)
+
+#include <pthread.h>
+#include <assert.h>
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+#include <string>
+#endif
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Mutex Mutex.h "lldb/Host/Mutex.h"
+/// @brief A C++ wrapper class for pthread mutexes.
+//----------------------------------------------------------------------
+class Mutex
+{
+public:
+ friend class Locker;
+ friend class Condition;
+
+ enum Type
+ {
+ eMutexTypeNormal, ///< Mutex that can't recursively entered by the same thread
+ eMutexTypeRecursive ///< Mutex can be recursively entered by the same thread
+ };
+
+ //------------------------------------------------------------------
+ /// @class Mutex::Locker
+ ///
+ /// A scoped locking class that allows a variety of pthread mutex
+ /// objects to have a mutex locked when an Mutex::Locker
+ /// object is created, and unlocked when it goes out of scope or
+ /// when the Mutex::Locker::Reset(pthread_mutex_t *)
+ /// is called. This provides an exception safe way to lock a mutex
+ /// in a scope.
+ //------------------------------------------------------------------
+ class Locker
+ {
+ public:
+ //--------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// This will create a scoped mutex locking object that doesn't
+ /// have a mutex to lock. One will need to be provided using the
+ /// Mutex::Locker::Reset(pthread_mutex_t *) method.
+ ///
+ /// @see Mutex::Locker::Reset(pthread_mutex_t *)
+ //--------------------------------------------------------------
+ Locker();
+
+ //--------------------------------------------------------------
+ /// Constructor with a Mutex object.
+ ///
+ /// This will create a scoped mutex locking object that extracts
+ /// the mutex owned by \a m and locks it.
+ ///
+ /// @param[in] m
+ /// An instance of a Mutex object that contains a
+ /// valid mutex object.
+ //--------------------------------------------------------------
+ Locker(Mutex& m);
+
+ //--------------------------------------------------------------
+ /// Constructor with a Mutex object pointer.
+ ///
+ /// This will create a scoped mutex locking object that extracts
+ /// the mutex owned by a m and locks it.
+ ///
+ /// @param[in] m
+ /// A pointer to instance of a Mutex object that
+ /// contains a valid mutex object.
+ //--------------------------------------------------------------
+ Locker(Mutex* m);
+
+ //--------------------------------------------------------------
+ /// Desstructor
+ ///
+ /// Unlocks any valid pthread_mutex_t that this object may
+ /// contain.
+ //--------------------------------------------------------------
+ ~Locker();
+
+ //--------------------------------------------------------------
+ /// Change the contained mutex.
+ ///
+ /// Unlock the current mutex in this object (if it contains a
+ /// valid mutex) and lock the new \a mutex object if it is
+ /// non-NULL.
+ //--------------------------------------------------------------
+ void
+ Lock (Mutex &mutex);
+
+ void
+ Lock (Mutex *mutex)
+ {
+ if (mutex)
+ Lock(*mutex);
+ }
+
+ //--------------------------------------------------------------
+ /// Change the contained mutex only if the mutex can be locked.
+ ///
+ /// Unlock the current mutex in this object (if it contains a
+ /// valid mutex) and try to lock \a mutex. If \a mutex can be
+ /// locked this object will take ownership of the lock and will
+ /// unlock it when it goes out of scope or Reset or TryLock are
+ /// called again. If the mutex is already locked, this object
+ /// will not take ownership of the mutex.
+ ///
+ /// @return
+ /// Returns \b true if the lock was aquired and the this
+ /// object will unlock the mutex when it goes out of scope,
+ /// returns \b false otherwise.
+ //--------------------------------------------------------------
+ bool
+ TryLock (Mutex &mutex, const char *failure_message = NULL);
+
+ bool
+ TryLock (Mutex *mutex, const char *failure_message = NULL)
+ {
+ if (mutex)
+ return TryLock(*mutex, failure_message);
+ else
+ return false;
+ }
+
+ void
+ Unlock ();
+
+ protected:
+ //--------------------------------------------------------------
+ /// Member variables
+ //--------------------------------------------------------------
+ Mutex *m_mutex_ptr;
+
+ private:
+ Locker(const Locker&);
+ const Locker& operator=(const Locker&);
+ };
+
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Creates a pthread mutex with no attributes.
+ //------------------------------------------------------------------
+ Mutex();
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Creates a pthread mutex with \a type as the mutex type.
+ /// Valid values for \a type include:
+ /// @li Mutex::Type::eMutexTypeNormal
+ /// @li Mutex::Type::eMutexTypeRecursive
+ ///
+ /// @param[in] type
+ /// The type of the mutex.
+ ///
+ /// @see ::pthread_mutexattr_settype()
+ //------------------------------------------------------------------
+ Mutex(Mutex::Type type);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// Destroys the mutex owned by this object.
+ //------------------------------------------------------------------
+#ifdef LLDB_CONFIGURATION_DEBUG
+ virtual
+#endif
+ ~Mutex();
+
+ //------------------------------------------------------------------
+ /// Lock the mutex.
+ ///
+ /// Locks the mutex owned by this object. If the mutex is already
+ /// locked, the calling thread will block until the mutex becomes
+ /// available.
+ ///
+ /// @return
+ /// The error code from \c pthread_mutex_lock().
+ //------------------------------------------------------------------
+#ifdef LLDB_CONFIGURATION_DEBUG
+ virtual
+#endif
+ int
+ Lock();
+
+ //------------------------------------------------------------------
+ /// Try to lock the mutex.
+ ///
+ /// Attempts to lock the mutex owned by this object without blocking.
+ /// If the mutex is already locked, TryLock() will not block waiting
+ /// for the mutex, but will return an error condition.
+ ///
+ /// @return
+ /// The error code from \c pthread_mutex_trylock().
+ //------------------------------------------------------------------
+#ifdef LLDB_CONFIGURATION_DEBUG
+ virtual
+#endif
+ int
+ TryLock(const char *failure_message = NULL);
+
+ //------------------------------------------------------------------
+ /// Unlock the mutex.
+ ///
+ /// If the current thread holds the lock on the owned mutex, then
+ /// Unlock() will unlock the mutex. Calling Unlock() on this object
+ /// when the calling thread does not hold the lock will result in
+ /// undefined behavior.
+ ///
+ /// @return
+ /// The error code from \c pthread_mutex_unlock().
+ //------------------------------------------------------------------
+#ifdef LLDB_CONFIGURATION_DEBUG
+ virtual
+#endif
+ int
+ Unlock();
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ // TODO: Hide the mutex in the implementation file in case we ever need to port to an
+ // architecture that doesn't have pthread mutexes.
+ pthread_mutex_t m_mutex; ///< The pthread mutex object.
+
+private:
+ //------------------------------------------------------------------
+ /// Mutex get accessor.
+ ///
+ /// @return
+ /// A pointer to the pthread mutex object owned by this object.
+ //------------------------------------------------------------------
+ pthread_mutex_t *
+ GetMutex();
+
+ Mutex(const Mutex&);
+ const Mutex& operator=(const Mutex&);
+};
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+class TrackingMutex : public Mutex
+{
+public:
+ TrackingMutex() : Mutex() {}
+ TrackingMutex(Mutex::Type type) : Mutex (type) {}
+
+ virtual
+ ~TrackingMutex() {}
+
+ virtual int
+ Unlock ();
+
+ virtual int
+ TryLock (const char *failure_message = NULL)
+ {
+ int return_value = Mutex::TryLock();
+ if (return_value != 0 && failure_message != NULL)
+ {
+ m_failure_message.assign(failure_message);
+ m_thread_that_tried = pthread_self();
+ }
+ return return_value;
+ }
+
+protected:
+ pthread_t m_thread_that_tried;
+ std::string m_failure_message;
+};
+
+class LoggingMutex : public Mutex
+{
+public:
+ LoggingMutex() : Mutex(),m_locked(false) {}
+ LoggingMutex(Mutex::Type type) : Mutex (type),m_locked(false) {}
+
+ virtual
+ ~LoggingMutex() {}
+
+ virtual int
+ Lock ();
+
+ virtual int
+ Unlock ();
+
+ virtual int
+ TryLock (const char *failure_message = NULL);
+protected:
+ bool m_locked;
+};
+#endif
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif
diff --git a/include/lldb/Host/Predicate.h b/include/lldb/Host/Predicate.h
new file mode 100644
index 000000000000..6ddf20b67c69
--- /dev/null
+++ b/include/lldb/Host/Predicate.h
@@ -0,0 +1,509 @@
+//===-- Predicate.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Predicate_h_
+#define liblldb_Predicate_h_
+#if defined(__cplusplus)
+
+#include "lldb/Host/Mutex.h"
+#include "lldb/Host/Condition.h"
+#include <stdint.h>
+#include <time.h>
+
+//#define DB_PTHREAD_LOG_EVENTS
+
+//----------------------------------------------------------------------
+/// Enumerations for broadcasting.
+//----------------------------------------------------------------------
+namespace lldb_private {
+
+typedef enum
+{
+ eBroadcastNever, ///< No broadcast will be sent when the value is modified.
+ eBroadcastAlways, ///< Always send a broadcast when the value is modified.
+ eBroadcastOnChange ///< Only broadcast if the value changes when the value is modified.
+
+} PredicateBroadcastType;
+
+//----------------------------------------------------------------------
+/// @class Predicate Predicate.h "lldb/Host/Predicate.h"
+/// @brief A C++ wrapper class for providing threaded access to a value
+/// of type T.
+///
+/// A templatized class that provides multi-threaded access to a value
+/// of type T. Threads can efficiently wait for bits within T to be set
+/// or reset, or wait for T to be set to be equal/not equal to a
+/// specified values.
+//----------------------------------------------------------------------
+template <class T>
+class Predicate
+{
+public:
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initializes the mutex, condition and value with their default
+ /// constructors.
+ //------------------------------------------------------------------
+ Predicate () :
+ m_value(),
+ m_mutex(),
+ m_condition()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Construct with initial T value \a initial_value.
+ ///
+ /// Initializes the mutex and condition with their default
+ /// constructors, and initializes the value with \a initial_value.
+ ///
+ /// @param[in] initial_value
+ /// The initial value for our T object.
+ //------------------------------------------------------------------
+ Predicate (T initial_value) :
+ m_value(initial_value),
+ m_mutex(),
+ m_condition()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// Destrory the condition, mutex, and T objects.
+ //------------------------------------------------------------------
+ ~Predicate ()
+ {
+ }
+
+
+ //------------------------------------------------------------------
+ /// Value get accessor.
+ ///
+ /// Copies the current \a m_value in a thread safe manor and returns
+ /// the copied value.
+ ///
+ /// @return
+ /// A copy of the current value.
+ //------------------------------------------------------------------
+ T
+ GetValue () const
+ {
+ Mutex::Locker locker(m_mutex);
+ T value = m_value;
+ return value;
+ }
+
+ //------------------------------------------------------------------
+ /// Value set accessor.
+ ///
+ /// Set the contained \a m_value to \a new_value in a thread safe
+ /// way and broadcast if needed.
+ ///
+ /// @param[in] value
+ /// The new value to set.
+ ///
+ /// @param[in] broadcast_type
+ /// A value indicating when and if to broadast. See the
+ /// PredicateBroadcastType enumeration for details.
+ ///
+ /// @see Predicate::Broadcast()
+ //------------------------------------------------------------------
+ void
+ SetValue (T value, PredicateBroadcastType broadcast_type)
+ {
+ Mutex::Locker locker(m_mutex);
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (value = 0x%8.8x, broadcast_type = %i)\n", __FUNCTION__, value, broadcast_type);
+#endif
+ const T old_value = m_value;
+ m_value = value;
+
+ Broadcast(old_value, broadcast_type);
+ }
+
+ //------------------------------------------------------------------
+ /// Set some bits in \a m_value.
+ ///
+ /// Logically set the bits \a bits in the contained \a m_value in a
+ /// thread safe way and broadcast if needed.
+ ///
+ /// @param[in] bits
+ /// The bits to set in \a m_value.
+ ///
+ /// @param[in] broadcast_type
+ /// A value indicating when and if to broadast. See the
+ /// PredicateBroadcastType enumeration for details.
+ ///
+ /// @see Predicate::Broadcast()
+ //------------------------------------------------------------------
+ void
+ SetValueBits (T bits, PredicateBroadcastType broadcast_type)
+ {
+ Mutex::Locker locker(m_mutex);
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (bits = 0x%8.8x, broadcast_type = %i)\n", __FUNCTION__, bits, broadcast_type);
+#endif
+ const T old_value = m_value;
+ m_value |= bits;
+
+ Broadcast(old_value, broadcast_type);
+ }
+
+ //------------------------------------------------------------------
+ /// Reset some bits in \a m_value.
+ ///
+ /// Logically reset (clear) the bits \a bits in the contained
+ /// \a m_value in a thread safe way and broadcast if needed.
+ ///
+ /// @param[in] bits
+ /// The bits to clear in \a m_value.
+ ///
+ /// @param[in] broadcast_type
+ /// A value indicating when and if to broadast. See the
+ /// PredicateBroadcastType enumeration for details.
+ ///
+ /// @see Predicate::Broadcast()
+ //------------------------------------------------------------------
+ void
+ ResetValueBits (T bits, PredicateBroadcastType broadcast_type)
+ {
+ Mutex::Locker locker(m_mutex);
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (bits = 0x%8.8x, broadcast_type = %i)\n", __FUNCTION__, bits, broadcast_type);
+#endif
+ const T old_value = m_value;
+ m_value &= ~bits;
+
+ Broadcast(old_value, broadcast_type);
+ }
+
+ //------------------------------------------------------------------
+ /// Wait for bits to be set in \a m_value.
+ ///
+ /// Waits in a thread safe way for any bits in \a bits to get
+ /// logically set in \a m_value. If any bits are already set in
+ /// \a m_value, this function will return without waiting.
+ ///
+ /// It is possible for the value to be changed between the time
+ /// the bits are set and the time the waiting thread wakes up.
+ /// If the bits are no longer set when the waiting thread wakes
+ /// up, it will go back into a wait state. It may be necessary
+ /// for the calling code to use additional thread synchronization
+ /// methods to detect transitory states.
+ ///
+ /// @param[in] bits
+ /// The bits we are waiting to be set in \a m_value.
+ ///
+ /// @param[in] abstime
+ /// If non-NULL, the absolute time at which we should stop
+ /// waiting, else wait an infinite amount of time.
+ ///
+ /// @return
+ /// Any bits of the requested bits that actually were set within
+ /// the time specified. Zero if a timeout or unrecoverable error
+ /// occurred.
+ //------------------------------------------------------------------
+ T
+ WaitForSetValueBits (T bits, const TimeValue *abstime = NULL)
+ {
+ int err = 0;
+ // pthread_cond_timedwait() or pthread_cond_wait() will atomically
+ // unlock the mutex and wait for the condition to be set. When either
+ // function returns, they will re-lock the mutex. We use an auto lock/unlock
+ // class (Mutex::Locker) to allow us to return at any point in this
+ // function and not have to worry about unlocking the mutex.
+ Mutex::Locker locker(m_mutex);
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (bits = 0x%8.8x, abstime = %p), m_value = 0x%8.8x\n", __FUNCTION__, bits, abstime, m_value);
+#endif
+ while (err == 0 && ((m_value & bits) == 0))
+ {
+ err = m_condition.Wait (m_mutex, abstime);
+ }
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (bits = 0x%8.8x), m_value = 0x%8.8x, returning 0x%8.8x\n", __FUNCTION__, bits, m_value, m_value & bits);
+#endif
+
+ return m_value & bits;
+ }
+
+ //------------------------------------------------------------------
+ /// Wait for bits to be reset in \a m_value.
+ ///
+ /// Waits in a thread safe way for any bits in \a bits to get
+ /// logically reset in \a m_value. If all bits are already reset in
+ /// \a m_value, this function will return without waiting.
+ ///
+ /// It is possible for the value to be changed between the time
+ /// the bits are reset and the time the waiting thread wakes up.
+ /// If the bits are no set when the waiting thread wakes up, it will
+ /// go back into a wait state. It may be necessary for the calling
+ /// code to use additional thread synchronization methods to detect
+ /// transitory states.
+ ///
+ /// @param[in] bits
+ /// The bits we are waiting to be reset in \a m_value.
+ ///
+ /// @param[in] abstime
+ /// If non-NULL, the absolute time at which we should stop
+ /// waiting, else wait an infinite amount of time.
+ ///
+ /// @return
+ /// Zero on successful waits, or non-zero if a timeout or
+ /// unrecoverable error occurs.
+ //------------------------------------------------------------------
+ T
+ WaitForResetValueBits (T bits, const TimeValue *abstime = NULL)
+ {
+ int err = 0;
+
+ // pthread_cond_timedwait() or pthread_cond_wait() will atomically
+ // unlock the mutex and wait for the condition to be set. When either
+ // function returns, they will re-lock the mutex. We use an auto lock/unlock
+ // class (Mutex::Locker) to allow us to return at any point in this
+ // function and not have to worry about unlocking the mutex.
+ Mutex::Locker locker(m_mutex);
+
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (bits = 0x%8.8x, abstime = %p), m_value = 0x%8.8x\n", __FUNCTION__, bits, abstime, m_value);
+#endif
+ while (err == 0 && ((m_value & bits) != 0))
+ {
+ err = m_condition.Wait (m_mutex, abstime);
+ }
+
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (bits = 0x%8.8x), m_value = 0x%8.8x, returning 0x%8.8x\n", __FUNCTION__, bits, m_value, m_value & bits);
+#endif
+ return m_value & bits;
+ }
+
+ //------------------------------------------------------------------
+ /// Wait for \a m_value to be equal to \a value.
+ ///
+ /// Waits in a thread safe way for \a m_value to be equal to \a
+ /// value. If \a m_value is already equal to \a value, this
+ /// function will return without waiting.
+ ///
+ /// It is possible for the value to be changed between the time
+ /// the value is set and the time the waiting thread wakes up.
+ /// If the value no longer matches the requested value when the
+ /// waiting thread wakes up, it will go back into a wait state. It
+ /// may be necessary for the calling code to use additional thread
+ /// synchronization methods to detect transitory states.
+ ///
+ /// @param[in] value
+ /// The value we want \a m_value to be equal to.
+ ///
+ /// @param[in] abstime
+ /// If non-NULL, the absolute time at which we should stop
+ /// waiting, else wait an infinite amount of time.
+ ///
+ /// @param[out] timed_out
+ /// If not null, set to true if we return because of a time out,
+ /// and false if the value was set.
+ ///
+ /// @return
+ /// @li \b true if the \a m_value is equal to \a value
+ /// @li \b false otherwise
+ //------------------------------------------------------------------
+ bool
+ WaitForValueEqualTo (T value, const TimeValue *abstime = NULL, bool *timed_out = NULL)
+ {
+ int err = 0;
+ // pthread_cond_timedwait() or pthread_cond_wait() will atomically
+ // unlock the mutex and wait for the condition to be set. When either
+ // function returns, they will re-lock the mutex. We use an auto lock/unlock
+ // class (Mutex::Locker) to allow us to return at any point in this
+ // function and not have to worry about unlocking the mutex.
+ Mutex::Locker locker(m_mutex);
+
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (value = 0x%8.8x, abstime = %p), m_value = 0x%8.8x\n", __FUNCTION__, value, abstime, m_value);
+#endif
+ if (timed_out)
+ *timed_out = false;
+
+ while (err == 0 && m_value != value)
+ {
+ err = m_condition.Wait (m_mutex, abstime, timed_out);
+ }
+
+ return m_value == value;
+ }
+
+ //------------------------------------------------------------------
+ /// Wait for \a m_value to be equal to \a value and then set it to
+ /// a new value.
+ ///
+ /// Waits in a thread safe way for \a m_value to be equal to \a
+ /// value and then sets \a m_value to \a new_value. If \a m_value
+ /// is already equal to \a value, this function will immediately
+ /// set \a m_value to \a new_value and return without waiting.
+ ///
+ /// It is possible for the value to be changed between the time
+ /// the value is set and the time the waiting thread wakes up.
+ /// If the value no longer matches the requested value when the
+ /// waiting thread wakes up, it will go back into a wait state. It
+ /// may be necessary for the calling code to use additional thread
+ /// synchronization methods to detect transitory states.
+ ///
+ /// @param[in] value
+ /// The value we want \a m_value to be equal to.
+ ///
+ /// @param[in] new_value
+ /// The value to which \a m_value will be set if \b true is
+ /// returned.
+ ///
+ /// @param[in] abstime
+ /// If non-NULL, the absolute time at which we should stop
+ /// waiting, else wait an infinite amount of time.
+ ///
+ /// @param[out] timed_out
+ /// If not null, set to true if we return because of a time out,
+ /// and false if the value was set.
+ ///
+ /// @return
+ /// @li \b true if the \a m_value became equal to \a value
+ /// @li \b false otherwise
+ //------------------------------------------------------------------
+ bool
+ WaitForValueEqualToAndSetValueTo (T wait_value, T new_value, const TimeValue *abstime = NULL, bool *timed_out = NULL)
+ {
+ int err = 0;
+ // pthread_cond_timedwait() or pthread_cond_wait() will atomically
+ // unlock the mutex and wait for the condition to be set. When either
+ // function returns, they will re-lock the mutex. We use an auto lock/unlock
+ // class (Mutex::Locker) to allow us to return at any point in this
+ // function and not have to worry about unlocking the mutex.
+ Mutex::Locker locker(m_mutex);
+
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (wait_value = 0x%8.8x, new_value = 0x%8.8x, abstime = %p), m_value = 0x%8.8x\n", __FUNCTION__, wait_value, new_value, abstime, m_value);
+#endif
+ if (timed_out)
+ *timed_out = false;
+
+ while (err == 0 && m_value != wait_value)
+ {
+ err = m_condition.Wait (m_mutex, abstime, timed_out);
+ }
+
+ if (m_value == wait_value)
+ {
+ m_value = new_value;
+ return true;
+ }
+
+ return false;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Wait for \a m_value to not be equal to \a value.
+ ///
+ /// Waits in a thread safe way for \a m_value to not be equal to \a
+ /// value. If \a m_value is already not equal to \a value, this
+ /// function will return without waiting.
+ ///
+ /// It is possible for the value to be changed between the time
+ /// the value is set and the time the waiting thread wakes up.
+ /// If the value is equal to the test value when the waiting thread
+ /// wakes up, it will go back into a wait state. It may be
+ /// necessary for the calling code to use additional thread
+ /// synchronization methods to detect transitory states.
+ ///
+ /// @param[in] value
+ /// The value we want \a m_value to not be equal to.
+ ///
+ /// @param[out] new_value
+ /// The new value if \b true is returned.
+ ///
+ /// @param[in] abstime
+ /// If non-NULL, the absolute time at which we should stop
+ /// waiting, else wait an infinite amount of time.
+ ///
+ /// @return
+ /// @li \b true if the \a m_value is equal to \a value
+ /// @li \b false otherwise
+ //------------------------------------------------------------------
+ bool
+ WaitForValueNotEqualTo (T value, T &new_value, const TimeValue *abstime = NULL)
+ {
+ int err = 0;
+ // pthread_cond_timedwait() or pthread_cond_wait() will atomically
+ // unlock the mutex and wait for the condition to be set. When either
+ // function returns, they will re-lock the mutex. We use an auto lock/unlock
+ // class (Mutex::Locker) to allow us to return at any point in this
+ // function and not have to worry about unlocking the mutex.
+ Mutex::Locker locker(m_mutex);
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (value = 0x%8.8x, abstime = %p), m_value = 0x%8.8x\n", __FUNCTION__, value, abstime, m_value);
+#endif
+ while (err == 0 && m_value == value)
+ {
+ err = m_condition.Wait (m_mutex, abstime);
+ }
+
+ if (m_value != value)
+ {
+ new_value = m_value;
+ return true;
+ }
+ return false;
+ }
+
+protected:
+ //----------------------------------------------------------------------
+ // pthread condition and mutex variable to controll access and allow
+ // blocking between the main thread and the spotlight index thread.
+ //----------------------------------------------------------------------
+ T m_value; ///< The templatized value T that we are protecting access to
+ mutable Mutex m_mutex; ///< The mutex to use when accessing the data
+ Condition m_condition; ///< The pthread condition variable to use for signaling that data available or changed.
+
+private:
+
+ //------------------------------------------------------------------
+ /// Broadcast if needed.
+ ///
+ /// Check to see if we need to broadcast to our condition variable
+ /// depedning on the \a old_value and on the \a broadcast_type.
+ ///
+ /// If \a broadcast_type is eBroadcastNever, no broadcast will be
+ /// sent.
+ ///
+ /// If \a broadcast_type is eBroadcastAlways, the condition variable
+ /// will always be broadcast.
+ ///
+ /// If \a broadcast_type is eBroadcastOnChange, the condition
+ /// variable be broadcast if the owned value changes.
+ //------------------------------------------------------------------
+ void
+ Broadcast (T old_value, PredicateBroadcastType broadcast_type)
+ {
+ bool broadcast = (broadcast_type == eBroadcastAlways) || ((broadcast_type == eBroadcastOnChange) && old_value != m_value);
+#ifdef DB_PTHREAD_LOG_EVENTS
+ printf("%s (old_value = 0x%8.8x, broadcast_type = %i) m_value = 0x%8.8x, broadcast = %u\n", __FUNCTION__, old_value, broadcast_type, m_value, broadcast);
+#endif
+ if (broadcast)
+ m_condition.Broadcast();
+ }
+
+
+ DISALLOW_COPY_AND_ASSIGN(Predicate);
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // #ifndef liblldb_Predicate_h_
diff --git a/include/lldb/Host/ProcessRunLock.h b/include/lldb/Host/ProcessRunLock.h
new file mode 100644
index 000000000000..f563be73fce0
--- /dev/null
+++ b/include/lldb/Host/ProcessRunLock.h
@@ -0,0 +1,165 @@
+//===-- ProcessRunLock.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ProcessRunLock_h_
+#define liblldb_ProcessRunLock_h_
+#if defined(__cplusplus)
+
+#include "lldb/Host/Mutex.h"
+#include "lldb/Host/Condition.h"
+#include <pthread.h>
+#include <stdint.h>
+#include <time.h>
+
+//----------------------------------------------------------------------
+/// Enumerations for broadcasting.
+//----------------------------------------------------------------------
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ProcessRunLock ProcessRunLock.h "lldb/Host/ProcessRunLock.h"
+/// @brief A class used to prevent the process from starting while other
+/// threads are accessing its data, and prevent access to its data while
+/// it is running.
+//----------------------------------------------------------------------
+
+class ProcessRunLock
+{
+public:
+ ProcessRunLock () :
+ m_rwlock(),
+ m_running(false)
+ {
+ int err = ::pthread_rwlock_init(&m_rwlock, NULL); (void)err;
+//#if LLDB_CONFIGURATION_DEBUG
+// assert(err == 0);
+//#endif
+ }
+
+ ~ProcessRunLock ()
+ {
+ int err = ::pthread_rwlock_destroy (&m_rwlock); (void)err;
+//#if LLDB_CONFIGURATION_DEBUG
+// assert(err == 0);
+//#endif
+ }
+
+ bool
+ ReadTryLock ()
+ {
+ ::pthread_rwlock_rdlock (&m_rwlock);
+ if (m_running == false)
+ {
+ return true;
+ }
+ ::pthread_rwlock_unlock (&m_rwlock);
+ return false;
+ }
+
+ bool
+ ReadUnlock ()
+ {
+ return ::pthread_rwlock_unlock (&m_rwlock) == 0;
+ }
+
+ bool
+ SetRunning()
+ {
+ ::pthread_rwlock_wrlock (&m_rwlock);
+ m_running = true;
+ ::pthread_rwlock_unlock (&m_rwlock);
+ return true;
+ }
+
+ bool
+ TrySetRunning()
+ {
+ bool r;
+
+ if (::pthread_rwlock_trywrlock (&m_rwlock) == 0)
+ {
+ r = !m_running;
+ m_running = true;
+ ::pthread_rwlock_unlock (&m_rwlock);
+ return r;
+ }
+ return false;
+ }
+
+ bool
+ SetStopped ()
+ {
+ ::pthread_rwlock_wrlock (&m_rwlock);
+ m_running = false;
+ ::pthread_rwlock_unlock (&m_rwlock);
+ return true;
+ }
+
+ class ProcessRunLocker
+ {
+ public:
+ ProcessRunLocker () :
+ m_lock (NULL)
+ {
+ }
+
+ ~ProcessRunLocker()
+ {
+ Unlock();
+ }
+
+ // Try to lock the read lock, but only do so if there are no writers.
+ bool
+ TryLock (ProcessRunLock *lock)
+ {
+ if (m_lock)
+ {
+ if (m_lock == lock)
+ return true; // We already have this lock locked
+ else
+ Unlock();
+ }
+ if (lock)
+ {
+ if (lock->ReadTryLock())
+ {
+ m_lock = lock;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected:
+ void
+ Unlock ()
+ {
+ if (m_lock)
+ {
+ m_lock->ReadUnlock();
+ m_lock = NULL;
+ }
+ }
+
+ ProcessRunLock *m_lock;
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ProcessRunLocker);
+ };
+
+protected:
+ pthread_rwlock_t m_rwlock;
+ bool m_running;
+private:
+ DISALLOW_COPY_AND_ASSIGN(ProcessRunLock);
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // #ifndef liblldb_ProcessRunLock_h_
diff --git a/include/lldb/Host/SocketAddress.h b/include/lldb/Host/SocketAddress.h
new file mode 100644
index 000000000000..e63b238c7994
--- /dev/null
+++ b/include/lldb/Host/SocketAddress.h
@@ -0,0 +1,256 @@
+//===-- SocketAddress.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SocketAddress_h_
+#define liblldb_SocketAddress_h_
+
+// C Includes
+#include <stdint.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+#if defined(__FreeBSD__)
+#include <sys/types.h>
+#endif
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+namespace lldb_private {
+
+class SocketAddress
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SocketAddress ();
+ SocketAddress (const struct sockaddr &s);
+ SocketAddress (const struct sockaddr_in &s);
+ SocketAddress (const struct sockaddr_in6 &s);
+ SocketAddress (const struct sockaddr_storage &s);
+ SocketAddress (const SocketAddress& rhs);
+ ~SocketAddress ();
+
+ //------------------------------------------------------------------
+ // Operators
+ //------------------------------------------------------------------
+ const SocketAddress&
+ operator=(const SocketAddress& rhs);
+
+ const SocketAddress&
+ operator=(const struct addrinfo *addr_info);
+
+ const SocketAddress&
+ operator=(const struct sockaddr &s);
+
+ const SocketAddress&
+ operator=(const struct sockaddr_in &s);
+
+ const SocketAddress&
+ operator=(const struct sockaddr_in6 &s);
+
+ const SocketAddress&
+ operator=(const struct sockaddr_storage &s);
+
+ //------------------------------------------------------------------
+ // Clear the contents of this socket address
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ // Get the length for the current socket address family
+ //------------------------------------------------------------------
+ socklen_t
+ GetLength () const;
+
+ //------------------------------------------------------------------
+ // Get the mex length for the the largest socket address supported.
+ //------------------------------------------------------------------
+ static socklen_t
+ GetMaxLength ();
+
+ //------------------------------------------------------------------
+ // Get the socket address family
+ //------------------------------------------------------------------
+ sa_family_t
+ GetFamily () const;
+
+ //------------------------------------------------------------------
+ // Set the socket address family
+ //------------------------------------------------------------------
+ void
+ SetFamily (sa_family_t family);
+
+ //------------------------------------------------------------------
+ // Get the port if the socket address for the family has a port
+ //------------------------------------------------------------------
+ in_port_t
+ GetPort () const;
+
+ //------------------------------------------------------------------
+ // Set the port if the socket address for the family has a port.
+ // The family must be set correctly prior to calling this function.
+ //------------------------------------------------------------------
+ bool
+ SetPort (in_port_t port);
+
+ //------------------------------------------------------------------
+ // Set the socket address according to the first match from a call
+ // to getaddrinfo() (or equivalent functions for systems that don't
+ // have getaddrinfo(). If "addr_info_ptr" is not NULL, it will get
+ // filled in with the match that was used to populate this socket
+ // address.
+ //------------------------------------------------------------------
+ bool
+ SetAddress (const struct addrinfo *hints_ptr, // Optional hints where the family, protocol and other things can be specified.
+ const char *host, // Hostname ("foo.bar.com" or "foo" or IP address string ("123.234.12.1" or "2001:0db8:85a3:0000:0000:8a2e:0370:7334")
+ const char *service, // Protocol name ("tcp", "http", etc) or a raw port number string ("81")
+ struct addrinfo *addr_info_ptr); // If non-NULL, this will get filled in with the match
+
+ //------------------------------------------------------------------
+ // Quick way to set the SocketAddress to localhost given the family.
+ // Returns true if successful, false if "family" doesn't support
+ // localhost or if "family" is not supported by this class.
+ //------------------------------------------------------------------
+ bool
+ SetToLocalhost (sa_family_t family,
+ in_port_t port);
+
+ //------------------------------------------------------------------
+ // Returns true if there is a valid socket address in this object.
+ //------------------------------------------------------------------
+ bool
+ IsValid () const;
+
+ //------------------------------------------------------------------
+ // Direct access to all of the sockaddr structures
+ //------------------------------------------------------------------
+ struct sockaddr &
+ sockaddr ()
+ {
+ return m_socket_addr.sa;
+ }
+
+ const struct sockaddr &
+ sockaddr () const
+ {
+ return m_socket_addr.sa;
+ }
+
+ struct sockaddr_in &
+ sockaddr_in ()
+ {
+ return m_socket_addr.sa_ipv4;
+ }
+
+ const struct sockaddr_in &
+ sockaddr_in () const
+ {
+ return m_socket_addr.sa_ipv4;
+ }
+
+ struct sockaddr_in6 &
+ sockaddr_in6 ()
+ {
+ return m_socket_addr.sa_ipv6;
+ }
+
+ const struct sockaddr_in6 &
+ sockaddr_in6 () const
+ {
+ return m_socket_addr.sa_ipv6;
+ }
+
+ struct sockaddr_storage &
+ sockaddr_storage ()
+ {
+ return m_socket_addr.sa_storage;
+ }
+
+
+ const struct sockaddr_storage &
+ sockaddr_storage () const
+ {
+ return m_socket_addr.sa_storage;
+ }
+
+
+ //------------------------------------------------------------------
+ // Conversion operators to allow getting the contents of this class
+ // as a pointer to the appropriate structure. This allows an instance
+ // of this class to be used in calls that take one of the sockaddr
+ // structure variants without having to manally use the correct
+ // accessor function.
+ //------------------------------------------------------------------
+
+ operator struct sockaddr * ()
+ {
+ return &m_socket_addr.sa;
+ }
+
+ operator const struct sockaddr * () const
+ {
+ return &m_socket_addr.sa;
+ }
+
+ operator struct sockaddr_in * ()
+ {
+ return &m_socket_addr.sa_ipv4;
+ }
+
+ operator const struct sockaddr_in * () const
+ {
+ return &m_socket_addr.sa_ipv4;
+ }
+
+ operator struct sockaddr_in6 * ()
+ {
+ return &m_socket_addr.sa_ipv6;
+ }
+
+ operator const struct sockaddr_in6 * () const
+ {
+ return &m_socket_addr.sa_ipv6;
+ }
+
+ operator const struct sockaddr_storage * () const
+ {
+ return &m_socket_addr.sa_storage;
+ }
+
+ operator struct sockaddr_storage * ()
+ {
+ return &m_socket_addr.sa_storage;
+ }
+
+
+protected:
+ typedef union sockaddr_tag
+ {
+ struct sockaddr sa;
+ struct sockaddr_in sa_ipv4;
+ struct sockaddr_in6 sa_ipv6;
+ struct sockaddr_storage sa_storage;
+ } sockaddr_t;
+
+ //------------------------------------------------------------------
+ // Classes that inherit from SocketAddress can see and modify these
+ //------------------------------------------------------------------
+ sockaddr_t m_socket_addr;
+};
+
+
+} // namespace lldb_private
+
+
+#endif // liblldb_SocketAddress_h_
diff --git a/include/lldb/Host/Symbols.h b/include/lldb/Host/Symbols.h
new file mode 100644
index 000000000000..9db68e1ecf15
--- /dev/null
+++ b/include/lldb/Host/Symbols.h
@@ -0,0 +1,69 @@
+//===-- Symbols.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Symbols_h_
+#define liblldb_Symbols_h_
+
+// C Includes
+#include <stdint.h>
+#include <sys/time.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Host/FileSpec.h"
+
+namespace lldb_private {
+
+class Symbols
+{
+public:
+ //----------------------------------------------------------------------
+ // Locate the executable file given a module specification.
+ //
+ // Locating the file should happen only on the local computer or using
+ // the current computers global settings.
+ //----------------------------------------------------------------------
+ static FileSpec
+ LocateExecutableObjectFile (const ModuleSpec &module_spec);
+
+ //----------------------------------------------------------------------
+ // Locate the symbol file given a module specification.
+ //
+ // Locating the file should happen only on the local computer or using
+ // the current computers global settings.
+ //----------------------------------------------------------------------
+ static FileSpec
+ LocateExecutableSymbolFile (const ModuleSpec &module_spec);
+
+ static FileSpec
+ FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,
+ const lldb_private::UUID *uuid,
+ const ArchSpec *arch);
+
+ //----------------------------------------------------------------------
+ // Locate the object and symbol file given a module specification.
+ //
+ // Locating the file can try to download the file from a corporate build
+ // respository, or using any other means necessary to locate both the
+ // unstripped object file and the debug symbols.
+ // The force_lookup argument controls whether the external program is called
+ // unconditionally to find the symbol file, or if the user's settings are
+ // checked to see if they've enabled the external program before calling.
+ //
+ //----------------------------------------------------------------------
+ static bool
+ DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool force_lookup = true);
+
+};
+
+} // namespace lldb_private
+
+
+#endif // liblldb_Symbols_h_
diff --git a/include/lldb/Host/Terminal.h b/include/lldb/Host/Terminal.h
new file mode 100644
index 000000000000..b334717c796b
--- /dev/null
+++ b/include/lldb/Host/Terminal.h
@@ -0,0 +1,254 @@
+//===-- Terminal.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Terminal_h_
+#define liblldb_Terminal_h_
+#if defined(__cplusplus)
+
+#include "lldb/lldb-private.h"
+
+struct termios;
+
+namespace lldb_private {
+
+class Terminal
+{
+public:
+
+ Terminal (int fd = -1) :
+ m_fd (fd)
+ {
+ }
+
+ ~Terminal ()
+ {
+ }
+
+ bool
+ IsATerminal () const;
+
+ int
+ GetFileDescriptor () const
+ {
+ return m_fd;
+ }
+
+ void
+ SetFileDescriptor (int fd)
+ {
+ m_fd = fd;
+ }
+
+ bool
+ FileDescriptorIsValid () const
+ {
+ return m_fd != -1;
+ }
+
+ void
+ Clear ()
+ {
+ m_fd = -1;
+ }
+
+ bool
+ SetEcho (bool enabled);
+
+ bool
+ SetCanonical (bool enabled);
+
+protected:
+ int m_fd; // This may or may not be a terminal file descriptor
+};
+
+
+//----------------------------------------------------------------------
+/// @class State Terminal.h "lldb/Host/Terminal.h"
+/// @brief A terminal state saving/restoring class.
+///
+/// This class can be used to remember the terminal state for a file
+/// descriptor and later restore that state as it originally was.
+//----------------------------------------------------------------------
+class TerminalState
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor
+ //------------------------------------------------------------------
+ TerminalState();
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~TerminalState();
+
+ //------------------------------------------------------------------
+ /// Save the TTY state for \a fd.
+ ///
+ /// Save the current state of the TTY for the file descriptor "fd"
+ /// and if "save_process_group" is true, attempt to save the process
+ /// group info for the TTY.
+ ///
+ /// @param[in] fd
+ /// The file descriptor to save the state of.
+ ///
+ /// @param[in] save_process_group
+ /// If \b true, save the process group settings, else do not
+ /// save the process group setttings for a TTY.
+ ///
+ /// @return
+ /// Returns \b true if \a fd describes a TTY and if the state
+ /// was able to be saved, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Save (int fd, bool save_process_group);
+
+ //------------------------------------------------------------------
+ /// Restore the TTY state to the cached state.
+ ///
+ /// Restore the state of the TTY using the cached values from a
+ /// previous call to TerminalState::Save(int,bool).
+ ///
+ /// @return
+ /// Returns \b true if the TTY state was successfully restored,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Restore () const;
+
+ //------------------------------------------------------------------
+ /// Test for valid cached TTY state information.
+ ///
+ /// @return
+ /// Returns \b true if this object has valid saved TTY state
+ /// settings that can be used to restore a previous state,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsValid() const;
+
+ void
+ Clear ();
+
+protected:
+
+ //------------------------------------------------------------------
+ /// Test if tflags is valid.
+ ///
+ /// @return
+ /// Returns \b true if \a m_tflags is valid and can be restored,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ TFlagsIsValid() const;
+
+ //------------------------------------------------------------------
+ /// Test if ttystate is valid.
+ ///
+ /// @return
+ /// Returns \b true if \a m_ttystate is valid and can be
+ /// restored, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ TTYStateIsValid() const;
+
+ //------------------------------------------------------------------
+ /// Test if the process group information is valid.
+ ///
+ /// @return
+ /// Returns \b true if \a m_process_group is valid and can be
+ /// restored, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ProcessGroupIsValid() const;
+
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ Terminal m_tty; ///< A terminal
+ int m_tflags; ///< Cached tflags information.
+ std::unique_ptr<struct termios> m_termios_ap; ///< Cached terminal state information.
+ lldb::pid_t m_process_group;///< Cached process group information.
+
+};
+
+//----------------------------------------------------------------------
+/// @class TerminalStateSwitcher Terminal.h "lldb/Host/Terminal.h"
+/// @brief A TTY state switching class.
+///
+/// This class can be used to remember 2 TTY states for a given file
+/// descriptor and switch between the two states.
+//----------------------------------------------------------------------
+class TerminalStateSwitcher
+{
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ //------------------------------------------------------------------
+ TerminalStateSwitcher();
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~TerminalStateSwitcher();
+
+ //------------------------------------------------------------------
+ /// Get the number of possible states to save.
+ ///
+ /// @return
+ /// The number of states that this TTY switcher object contains.
+ //------------------------------------------------------------------
+ uint32_t
+ GetNumberOfStates() const;
+
+ //------------------------------------------------------------------
+ /// Restore the TTY state for state at index \a idx.
+ ///
+ /// @return
+ /// Returns \b true if the TTY state was successfully restored,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Restore (uint32_t idx) const;
+
+ //------------------------------------------------------------------
+ /// Save the TTY state information for the state at index \a idx.
+ /// The TTY state is saved for the file descriptor \a fd and
+ /// the process group information will also be saved if requested
+ /// by \a save_process_group.
+ ///
+ /// @param[in] idx
+ /// The index into the state array where the state should be
+ /// saved.
+ ///
+ /// @param[in] fd
+ /// The file descriptor for which to save the settings.
+ ///
+ /// @param[in] save_process_group
+ /// If \b true, save the process group information for the TTY.
+ ///
+ /// @return
+ /// Returns \b true if the save was successful, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ Save (uint32_t idx, int fd, bool save_process_group);
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ mutable uint32_t m_currentState; ///< The currently active TTY state index.
+ TerminalState m_ttystates[2]; ///< The array of TTY states that holds saved TTY info.
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // #ifndef liblldb_Terminal_h_
diff --git a/include/lldb/Host/TimeValue.h b/include/lldb/Host/TimeValue.h
new file mode 100644
index 000000000000..8c43d6d0e5ff
--- /dev/null
+++ b/include/lldb/Host/TimeValue.h
@@ -0,0 +1,107 @@
+//===-- TimeValue.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TimeValue_h_
+#define liblldb_TimeValue_h_
+
+// C Includes
+#include <stdint.h>
+#include <sys/time.h>
+
+// BEGIN: MinGW work around
+#if !defined(_STRUCT_TIMESPEC) && !defined(HAVE_STRUCT_TIMESPEC)
+#include <pthread.h>
+#endif
+// END: MinGW work around
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class TimeValue
+{
+public:
+ static const uint64_t MicroSecPerSec = 1000000UL;
+ static const uint64_t NanoSecPerSec = 1000000000UL;
+ static const uint64_t NanoSecPerMicroSec = 1000U;
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ TimeValue();
+ TimeValue(const TimeValue& rhs);
+ TimeValue(const struct timespec& ts);
+ TimeValue(const struct timeval& tv);
+ ~TimeValue();
+
+ //------------------------------------------------------------------
+ // Operators
+ //------------------------------------------------------------------
+ const TimeValue&
+ operator=(const TimeValue& rhs);
+
+ void
+ Clear ();
+
+ uint64_t
+ GetAsNanoSecondsSinceJan1_1970() const;
+
+ uint64_t
+ GetAsMicroSecondsSinceJan1_1970() const;
+
+ uint64_t
+ GetAsSecondsSinceJan1_1970() const;
+
+ struct timespec
+ GetAsTimeSpec () const;
+
+ struct timeval
+ GetAsTimeVal () const;
+
+ bool
+ IsValid () const;
+
+ void
+ OffsetWithSeconds (uint64_t sec);
+
+ void
+ OffsetWithMicroSeconds (uint64_t usec);
+
+ void
+ OffsetWithNanoSeconds (uint64_t nsec);
+
+ static TimeValue
+ Now();
+
+ void
+ Dump (Stream *s, uint32_t width = 0) const;
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from TimeValue can see and modify these
+ //------------------------------------------------------------------
+ uint64_t m_nano_seconds;
+};
+
+bool operator == (const TimeValue &lhs, const TimeValue &rhs);
+bool operator != (const TimeValue &lhs, const TimeValue &rhs);
+bool operator < (const TimeValue &lhs, const TimeValue &rhs);
+bool operator <= (const TimeValue &lhs, const TimeValue &rhs);
+bool operator > (const TimeValue &lhs, const TimeValue &rhs);
+bool operator >= (const TimeValue &lhs, const TimeValue &rhs);
+
+uint64_t operator -(const TimeValue &lhs, const TimeValue &rhs);
+
+} // namespace lldb_private
+
+
+#endif // liblldb_TimeValue_h_
diff --git a/include/lldb/Host/freebsd/Config.h b/include/lldb/Host/freebsd/Config.h
new file mode 100644
index 000000000000..49d97dd5793c
--- /dev/null
+++ b/include/lldb/Host/freebsd/Config.h
@@ -0,0 +1,28 @@
+//===-- Config.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//----------------------------------------------------------------------
+// LLDB currently doesn't have a dynamic configuration mechanism, so we
+// are going to hardcode things for now. Eventually these files will
+// be auto generated by some configuration script that can detect
+// platform functionality availability.
+//----------------------------------------------------------------------
+
+#ifndef liblldb_Platform_Config_h_
+#define liblldb_Platform_Config_h_
+
+#define LLDB_CONFIG_TERMIOS_SUPPORTED 1
+
+#define LLDB_CONFIG_TILDE_RESOLVES_TO_USER 1
+
+//#define LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 1
+
+//#define LLDB_CONFIG_FCNTL_GETPATH_SUPPORTED 1
+
+#endif // #ifndef liblldb_Platform_Config_h_
diff --git a/include/lldb/Interpreter/Args.h b/include/lldb/Interpreter/Args.h
new file mode 100644
index 000000000000..d06c3e56aecd
--- /dev/null
+++ b/include/lldb/Interpreter/Args.h
@@ -0,0 +1,467 @@
+//===-- Args.h --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Command_h_
+#define liblldb_Command_h_
+
+// C Includes
+#include <getopt.h>
+
+// C++ Includes
+#include <list>
+#include <string>
+#include <vector>
+#include <utility>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private-types.h"
+#include "lldb/lldb-types.h"
+#include "lldb/Core/Error.h"
+
+namespace lldb_private {
+
+typedef std::pair<int, std::string> OptionArgValue;
+typedef std::pair<std::string, OptionArgValue> OptionArgPair;
+typedef std::vector<OptionArgPair> OptionArgVector;
+typedef std::shared_ptr<OptionArgVector> OptionArgVectorSP;
+
+struct OptionArgElement
+{
+ enum {
+ eUnrecognizedArg = -1,
+ eBareDash = -2,
+ eBareDoubleDash = -3
+ };
+
+ OptionArgElement (int defs_index, int pos, int arg_pos) :
+ opt_defs_index(defs_index),
+ opt_pos (pos),
+ opt_arg_pos (arg_pos)
+ {
+ }
+
+ int opt_defs_index;
+ int opt_pos;
+ int opt_arg_pos;
+};
+
+typedef std::vector<OptionArgElement> OptionElementVector;
+
+//----------------------------------------------------------------------
+/// @class Args Args.h "lldb/Interpreter/Args.h"
+/// @brief A command line argument class.
+///
+/// The Args class is designed to be fed a command line. The
+/// command line is copied into an internal buffer and then split up
+/// into arguments. Arguments are space delimited if there are no quotes
+/// (single, double, or backtick quotes) surrounding the argument. Spaces
+/// can be escaped using a \ character to avoid having to surround an
+/// argument that contains a space with quotes.
+//----------------------------------------------------------------------
+class Args
+{
+public:
+
+ //------------------------------------------------------------------
+ /// Construct with an option command string.
+ ///
+ /// @param[in] command
+ /// A NULL terminated command that will be copied and split up
+ /// into arguments.
+ ///
+ /// @see Args::SetCommandString(const char *)
+ //------------------------------------------------------------------
+ Args (const char *command = NULL);
+
+ Args (const char *command, size_t len);
+
+ Args (const Args &rhs);
+
+ const Args &
+ operator= (const Args &rhs);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~Args();
+
+ //------------------------------------------------------------------
+ /// Dump all arguments to the stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump all arguments in the argument
+ /// vector.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s);
+
+ //------------------------------------------------------------------
+ /// Sets the command string contained by this object.
+ ///
+ /// The command string will be copied and split up into arguments
+ /// that can be accessed via the accessor functions.
+ ///
+ /// @param[in] command
+ /// A NULL terminated command that will be copied and split up
+ /// into arguments.
+ ///
+ /// @see Args::GetArgumentCount() const
+ /// @see Args::GetArgumentAtIndex (size_t) const
+ /// @see Args::GetArgumentVector ()
+ /// @see Args::Shift ()
+ /// @see Args::Unshift (const char *)
+ //------------------------------------------------------------------
+ void
+ SetCommandString (const char *command);
+
+ void
+ SetCommandString (const char *command, size_t len);
+
+ bool
+ GetCommandString (std::string &command) const;
+
+ bool
+ GetQuotedCommandString (std::string &command) const;
+
+ //------------------------------------------------------------------
+ /// Gets the number of arguments left in this command object.
+ ///
+ /// @return
+ /// The number or arguments in this object.
+ //------------------------------------------------------------------
+ size_t
+ GetArgumentCount () const;
+
+ //------------------------------------------------------------------
+ /// Gets the NULL terminated C string argument pointer for the
+ /// argument at index \a idx.
+ ///
+ /// @return
+ /// The NULL terminated C string argument pointer if \a idx is a
+ /// valid argument index, NULL otherwise.
+ //------------------------------------------------------------------
+ const char *
+ GetArgumentAtIndex (size_t idx) const;
+
+ char
+ GetArgumentQuoteCharAtIndex (size_t idx) const;
+
+ //------------------------------------------------------------------
+ /// Gets the argument vector.
+ ///
+ /// The value returned by this function can be used by any function
+ /// that takes and vector. The return value is just like \a argv
+ /// in the standard C entry point function:
+ /// \code
+ /// int main (int argc, const char **argv);
+ /// \endcode
+ ///
+ /// @return
+ /// An array of NULL terminated C string argument pointers that
+ /// also has a terminating NULL C string pointer
+ //------------------------------------------------------------------
+ char **
+ GetArgumentVector ();
+
+ //------------------------------------------------------------------
+ /// Gets the argument vector.
+ ///
+ /// The value returned by this function can be used by any function
+ /// that takes and vector. The return value is just like \a argv
+ /// in the standard C entry point function:
+ /// \code
+ /// int main (int argc, const char **argv);
+ /// \endcode
+ ///
+ /// @return
+ /// An array of NULL terminate C string argument pointers that
+ /// also has a terminating NULL C string pointer
+ //------------------------------------------------------------------
+ const char **
+ GetConstArgumentVector () const;
+
+
+ //------------------------------------------------------------------
+ /// Appends a new argument to the end of the list argument list.
+ ///
+ /// @param[in] arg_cstr
+ /// The new argument as a NULL terminated C string.
+ ///
+ /// @param[in] quote_char
+ /// If the argument was originally quoted, put in the quote char here.
+ ///
+ /// @return
+ /// The NULL terminated C string of the copy of \a arg_cstr.
+ //------------------------------------------------------------------
+ const char *
+ AppendArgument (const char *arg_cstr, char quote_char = '\0');
+
+ void
+ AppendArguments (const Args &rhs);
+
+ void
+ AppendArguments (const char **argv);
+
+ //------------------------------------------------------------------
+ /// Insert the argument value at index \a idx to \a arg_cstr.
+ ///
+ /// @param[in] idx
+ /// The index of where to insert the argument.
+ ///
+ /// @param[in] arg_cstr
+ /// The new argument as a NULL terminated C string.
+ ///
+ /// @param[in] quote_char
+ /// If the argument was originally quoted, put in the quote char here.
+ ///
+ /// @return
+ /// The NULL terminated C string of the copy of \a arg_cstr.
+ //------------------------------------------------------------------
+ const char *
+ InsertArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char = '\0');
+
+ //------------------------------------------------------------------
+ /// Replaces the argument value at index \a idx to \a arg_cstr
+ /// if \a idx is a valid argument index.
+ ///
+ /// @param[in] idx
+ /// The index of the argument that will have its value replaced.
+ ///
+ /// @param[in] arg_cstr
+ /// The new argument as a NULL terminated C string.
+ ///
+ /// @param[in] quote_char
+ /// If the argument was originally quoted, put in the quote char here.
+ ///
+ /// @return
+ /// The NULL terminated C string of the copy of \a arg_cstr if
+ /// \a idx was a valid index, NULL otherwise.
+ //------------------------------------------------------------------
+ const char *
+ ReplaceArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char = '\0');
+
+ //------------------------------------------------------------------
+ /// Deletes the argument value at index
+ /// if \a idx is a valid argument index.
+ ///
+ /// @param[in] idx
+ /// The index of the argument that will have its value replaced.
+ ///
+ //------------------------------------------------------------------
+ void
+ DeleteArgumentAtIndex (size_t idx);
+
+ //------------------------------------------------------------------
+ /// Sets the argument vector value, optionally copying all
+ /// arguments into an internal buffer.
+ ///
+ /// Sets the arguments to match those found in \a argv. All argument
+ /// strings will be copied into an internal buffers.
+ //
+ // FIXME: Handle the quote character somehow.
+ //------------------------------------------------------------------
+ void
+ SetArguments (size_t argc, const char **argv);
+
+ void
+ SetArguments (const char **argv);
+
+ //------------------------------------------------------------------
+ /// Shifts the first argument C string value of the array off the
+ /// argument array.
+ ///
+ /// The string value will be freed, so a copy of the string should
+ /// be made by calling Args::GetArgumentAtIndex (size_t) const
+ /// first and copying the returned value before calling
+ /// Args::Shift().
+ ///
+ /// @see Args::GetArgumentAtIndex (size_t) const
+ //------------------------------------------------------------------
+ void
+ Shift ();
+
+ //------------------------------------------------------------------
+ /// Inserts a class owned copy of \a arg_cstr at the beginning of
+ /// the argument vector.
+ ///
+ /// A copy \a arg_cstr will be made.
+ ///
+ /// @param[in] arg_cstr
+ /// The argument to push on the front the the argument stack.
+ ///
+ /// @param[in] quote_char
+ /// If the argument was originally quoted, put in the quote char here.
+ ///
+ /// @return
+ /// A pointer to the copy of \a arg_cstr that was made.
+ //------------------------------------------------------------------
+ const char *
+ Unshift (const char *arg_cstr, char quote_char = '\0');
+
+ //------------------------------------------------------------------
+ /// Parse the arguments in the contained arguments.
+ ///
+ /// The arguments that are consumed by the argument parsing process
+ /// will be removed from the argument vector. The arguements that
+ /// get processed start at the second argument. The first argument
+ /// is assumed to be the command and will not be touched.
+ ///
+ /// @see class Options
+ //------------------------------------------------------------------
+ Error
+ ParseOptions (Options &options);
+
+ size_t
+ FindArgumentIndexForOption (struct option *long_options, int long_options_index);
+
+ bool
+ IsPositionalArgument (const char *arg);
+
+ // The following works almost identically to ParseOptions, except that no option is required to have arguments,
+ // and it builds up the option_arg_vector as it parses the options.
+
+ void
+ ParseAliasOptions (Options &options, CommandReturnObject &result, OptionArgVector *option_arg_vector,
+ std::string &raw_input_line);
+
+ void
+ ParseArgsForCompletion (Options &options, OptionElementVector &option_element_vector, uint32_t cursor_index);
+
+ //------------------------------------------------------------------
+ // Clear the arguments.
+ //
+ // For re-setting or blanking out the list of arguments.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ static const char *
+ StripSpaces (std::string &s,
+ bool leading = true,
+ bool trailing = true,
+ bool return_null_if_empty = true);
+
+ static int32_t
+ StringToSInt32 (const char *s, int32_t fail_value = 0, int base = 0, bool *success_ptr = NULL);
+
+ static uint32_t
+ StringToUInt32 (const char *s, uint32_t fail_value = 0, int base = 0, bool *success_ptr = NULL);
+
+ static int64_t
+ StringToSInt64 (const char *s, int64_t fail_value = 0, int base = 0, bool *success_ptr = NULL);
+
+ static uint64_t
+ StringToUInt64 (const char *s, uint64_t fail_value = 0, int base = 0, bool *success_ptr = NULL);
+
+ static bool
+ UInt64ValueIsValidForByteSize (uint64_t uval64, size_t total_byte_size)
+ {
+ if (total_byte_size > 8)
+ return false;
+
+ if (total_byte_size == 8)
+ return true;
+
+ const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
+ return uval64 <= max;
+ }
+
+ static bool
+ SInt64ValueIsValidForByteSize (int64_t sval64, size_t total_byte_size)
+ {
+ if (total_byte_size > 8)
+ return false;
+
+ if (total_byte_size == 8)
+ return true;
+
+ const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
+ const int64_t min = ~(max);
+ return min <= sval64 && sval64 <= max;
+ }
+
+ static lldb::addr_t
+ StringToAddress (const ExecutionContext *exe_ctx,
+ const char *s,
+ lldb::addr_t fail_value,
+ Error *error);
+
+ static bool
+ StringToBoolean (const char *s, bool fail_value, bool *success_ptr);
+
+ static int64_t
+ StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error);
+
+ static lldb::ScriptLanguage
+ StringToScriptLanguage (const char *s, lldb::ScriptLanguage fail_value, bool *success_ptr);
+
+ static Error
+ StringToFormat (const char *s,
+ lldb::Format &format,
+ size_t *byte_size_ptr); // If non-NULL, then a byte size can precede the format character
+
+ static lldb::Encoding
+ StringToEncoding (const char *s,
+ lldb::Encoding fail_value = lldb::eEncodingInvalid);
+
+ static uint32_t
+ StringToGenericRegister (const char *s);
+
+ static const char *
+ StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update);
+
+ static const char *
+ GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg);
+
+ // EncodeEscapeSequences will change the textual representation of common
+ // escape sequences like "\n" (two characters) into a single '\n'. It does
+ // this for all of the supported escaped sequences and for the \0ooo (octal)
+ // and \xXX (hex). The resulting "dst" string will contain the character
+ // versions of all supported escape sequences. The common supported escape
+ // sequences are: "\a", "\b", "\f", "\n", "\r", "\t", "\v", "\'", "\"", "\\".
+
+ static void
+ EncodeEscapeSequences (const char *src, std::string &dst);
+
+ // ExpandEscapeSequences will change a string of possibly non-printable
+ // characters and expand them into text. So '\n' will turn into two chracters
+ // like "\n" which is suitable for human reading. When a character is not
+ // printable and isn't one of the common in escape sequences listed in the
+ // help for EncodeEscapeSequences, then it will be encoded as octal. Printable
+ // characters are left alone.
+ static void
+ ExpandEscapedCharacters (const char *src, std::string &dst);
+
+ // This one isn't really relevant to Arguments per se, but we're using the Args as a
+ // general strings container, so...
+ void
+ LongestCommonPrefix (std::string &common_prefix);
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from Args can see and modify these
+ //------------------------------------------------------------------
+ typedef std::list<std::string> arg_sstr_collection;
+ typedef std::vector<const char *> arg_cstr_collection;
+ typedef std::vector<char> arg_quote_char_collection;
+ arg_sstr_collection m_args;
+ arg_cstr_collection m_argv; ///< The current argument vector.
+ arg_quote_char_collection m_args_quote_char;
+
+ void
+ UpdateArgsAfterOptionParsing ();
+
+ void
+ UpdateArgvFromArgs ();
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Command_h_
diff --git a/include/lldb/Interpreter/CommandCompletions.h b/include/lldb/Interpreter/CommandCompletions.h
new file mode 100644
index 000000000000..c4ab1b61adeb
--- /dev/null
+++ b/include/lldb/Interpreter/CommandCompletions.h
@@ -0,0 +1,307 @@
+//===-- CommandCompletions.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_CommandCompletions_h_
+#define lldb_CommandCompletions_h_
+
+// C Includes
+// C++ Includes
+#include <set>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/SearchFilter.h"
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Core/RegularExpression.h"
+
+namespace lldb_private
+{
+class CommandCompletions
+{
+public:
+
+ //----------------------------------------------------------------------
+ // This is the command completion callback that is used to complete the argument of the option
+ // it is bound to (in the OptionDefinition table below). Return the total number of matches.
+ //----------------------------------------------------------------------
+ typedef int (*CompletionCallback) (CommandInterpreter &interpreter,
+ const char *completion_str, // This is the argument we are completing
+ int match_start_point, // This is the point in the list of matches that you should start returning elements
+ int max_return_elements, // This is the number of matches requested.
+ lldb_private::SearchFilter *searcher,// A search filter to limit the search...
+ bool &word_complete,
+ lldb_private::StringList &matches); // The array of matches we return.
+ typedef enum
+ {
+ eNoCompletion = 0u,
+ eSourceFileCompletion = (1u << 0),
+ eDiskFileCompletion = (1u << 1),
+ eDiskDirectoryCompletion = (1u << 2),
+ eSymbolCompletion = (1u << 3),
+ eModuleCompletion = (1u << 4),
+ eSettingsNameCompletion = (1u << 5),
+ ePlatformPluginCompletion = (1u << 6),
+ eArchitectureCompletion = (1u << 7),
+ eVariablePathCompletion = (1u << 8),
+ // This item serves two purposes. It is the last element in the enum,
+ // so you can add custom enums starting from here in your Option class.
+ // Also if you & in this bit the base code will not process the option.
+ eCustomCompletion = (1u << 9)
+
+ } CommonCompletionTypes;
+
+ struct CommonCompletionElement
+ {
+ uint32_t type;
+ CompletionCallback callback;
+ };
+
+ static bool InvokeCommonCompletionCallbacks (CommandInterpreter &interpreter,
+ uint32_t completion_mask,
+ const char *completion_str,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ StringList &matches);
+
+ //----------------------------------------------------------------------
+ // These are the generic completer functions:
+ //----------------------------------------------------------------------
+ static int
+ DiskFiles (CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ StringList &matches);
+ static int
+ DiskDirectories (CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ StringList &matches);
+
+ static int
+ SourceFiles (CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ StringList &matches);
+
+ static int
+ Modules (CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ lldb_private::StringList &matches);
+
+ static int
+ Symbols (CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ lldb_private::StringList &matches);
+
+ static int
+ SettingsNames (CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ lldb_private::StringList &matches);
+
+ static int
+ PlatformPluginNames (CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ lldb_private::StringList &matches);
+
+
+ static int
+ ArchitectureNames (CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ lldb_private::StringList &matches);
+
+ static int
+ VariablePath (CommandInterpreter &interpreter,
+ const char *partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher,
+ bool &word_complete,
+ lldb_private::StringList &matches);
+
+ //----------------------------------------------------------------------
+ // The Completer class is a convenient base class for building searchers
+ // that go along with the SearchFilter passed to the standard Completer
+ // functions.
+ //----------------------------------------------------------------------
+ class Completer : public Searcher
+ {
+ public:
+ Completer (CommandInterpreter &interpreter,
+ const char *completion_str,
+ int match_start_point,
+ int max_return_elements,
+ StringList &matches);
+
+ virtual ~Completer ();
+
+ virtual CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool complete) = 0;
+
+ virtual Depth
+ GetDepth () = 0;
+
+ virtual size_t
+ DoCompletion (SearchFilter *filter) = 0;
+
+ protected:
+ CommandInterpreter &m_interpreter;
+ std::string m_completion_str;
+ int m_match_start_point;
+ int m_max_return_elements;
+ StringList &m_matches;
+ private:
+ DISALLOW_COPY_AND_ASSIGN (Completer);
+ };
+
+ //----------------------------------------------------------------------
+ // SouceFileCompleter implements the source file completer
+ //----------------------------------------------------------------------
+ class SourceFileCompleter : public Completer
+ {
+ public:
+
+ SourceFileCompleter (CommandInterpreter &interpreter,
+ bool include_support_files,
+ const char *completion_str,
+ int match_start_point,
+ int max_return_elements,
+ StringList &matches);
+
+ virtual Searcher::Depth GetDepth ();
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool complete);
+
+ size_t
+ DoCompletion (SearchFilter *filter);
+
+ private:
+ bool m_include_support_files;
+ FileSpecList m_matching_files;
+ const char *m_file_name;
+ const char *m_dir_name;
+ DISALLOW_COPY_AND_ASSIGN (SourceFileCompleter);
+
+ };
+
+ //----------------------------------------------------------------------
+ // ModuleCompleter implements the module completer
+ //----------------------------------------------------------------------
+ class ModuleCompleter : public Completer
+ {
+ public:
+
+ ModuleCompleter (CommandInterpreter &interpreter,
+ const char *completion_str,
+ int match_start_point,
+ int max_return_elements,
+ StringList &matches);
+
+ virtual Searcher::Depth GetDepth ();
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool complete);
+
+ size_t
+ DoCompletion (SearchFilter *filter);
+
+ private:
+ const char *m_file_name;
+ const char *m_dir_name;
+ DISALLOW_COPY_AND_ASSIGN (ModuleCompleter);
+
+ };
+
+ //----------------------------------------------------------------------
+ // SymbolCompleter implements the symbol completer
+ //----------------------------------------------------------------------
+ class SymbolCompleter : public Completer
+ {
+ public:
+
+ SymbolCompleter (CommandInterpreter &interpreter,
+ const char *completion_str,
+ int match_start_point,
+ int max_return_elements,
+ StringList &matches);
+
+ virtual Searcher::Depth GetDepth ();
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool complete);
+
+ size_t
+ DoCompletion (SearchFilter *filter);
+
+ private:
+// struct NameCmp {
+// bool operator() (const ConstString& lhs, const ConstString& rhs) const
+// {
+// return lhs < rhs;
+// }
+// };
+
+ RegularExpression m_regex;
+ typedef std::set<ConstString> collection;
+ collection m_match_set;
+ DISALLOW_COPY_AND_ASSIGN (SymbolCompleter);
+
+ };
+
+private:
+ static CommonCompletionElement g_common_completions[];
+
+};
+
+} // namespace lldb_private
+#endif // lldb_CommandCompletions_h_
diff --git a/include/lldb/Interpreter/CommandHistory.h b/include/lldb/Interpreter/CommandHistory.h
new file mode 100644
index 000000000000..dbe6e99bb5b1
--- /dev/null
+++ b/include/lldb/Interpreter/CommandHistory.h
@@ -0,0 +1,76 @@
+//===-- CommandHistory.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CommandHistory_h_
+#define liblldb_CommandHistory_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+class CommandHistory
+{
+public:
+ CommandHistory ();
+
+ ~CommandHistory ();
+
+ size_t
+ GetSize () const;
+
+ bool
+ IsEmpty () const;
+
+ const char*
+ FindString (const char* input_str) const;
+
+ const char*
+ GetStringAtIndex (size_t idx) const;
+
+ const char*
+ operator [] (size_t idx) const;
+
+ const char*
+ GetRecentmostString () const;
+
+ void
+ AppendString (const std::string& str,
+ bool reject_if_dupe = true);
+
+ void
+ Clear ();
+
+ void
+ Dump (Stream& stream,
+ size_t start_idx = 0,
+ size_t stop_idx = SIZE_MAX) const;
+
+ static const char g_repeat_char = '!';
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(CommandHistory);
+
+ typedef std::vector<std::string> History;
+ mutable Mutex m_mutex;
+ History m_history;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CommandHistory_h_
diff --git a/include/lldb/Interpreter/CommandInterpreter.h b/include/lldb/Interpreter/CommandInterpreter.h
new file mode 100644
index 000000000000..31fcc38eed9a
--- /dev/null
+++ b/include/lldb/Interpreter/CommandInterpreter.h
@@ -0,0 +1,486 @@
+//===-- CommandInterpreter.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CommandInterpreter_h_
+#define liblldb_CommandInterpreter_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Interpreter/CommandHistory.h"
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Core/Event.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/StringList.h"
+
+namespace lldb_private {
+
+class CommandInterpreter :
+ public Broadcaster,
+ public Properties
+{
+public:
+ typedef std::map<std::string, OptionArgVectorSP> OptionArgMap;
+
+ enum
+ {
+ eBroadcastBitThreadShouldExit = (1 << 0),
+ eBroadcastBitResetPrompt = (1 << 1),
+ eBroadcastBitQuitCommandReceived = (1 << 2), // User entered quit
+ eBroadcastBitAsynchronousOutputData = (1 << 3),
+ eBroadcastBitAsynchronousErrorData = (1 << 4)
+ };
+
+ enum ChildrenTruncatedWarningStatus // tristate boolean to manage children truncation warning
+ {
+ eNoTruncation = 0, // never truncated
+ eUnwarnedTruncation = 1, // truncated but did not notify
+ eWarnedTruncation = 2 // truncated and notified
+ };
+
+ enum CommandTypes
+ {
+ eCommandTypesBuiltin = 0x0001, // native commands such as "frame"
+ eCommandTypesUserDef = 0x0002, // scripted commands
+ eCommandTypesAliases = 0x0004, // aliases such as "po"
+ eCommandTypesAllThem = 0xFFFF // all commands
+ };
+
+ // These two functions fill out the Broadcaster interface:
+
+ static ConstString &GetStaticBroadcasterClass ();
+
+ virtual ConstString &GetBroadcasterClass() const
+ {
+ return GetStaticBroadcasterClass();
+ }
+
+ void
+ SourceInitFile (bool in_cwd,
+ CommandReturnObject &result);
+
+ CommandInterpreter (Debugger &debugger,
+ lldb::ScriptLanguage script_language,
+ bool synchronous_execution);
+
+ virtual
+ ~CommandInterpreter ();
+
+ bool
+ AddCommand (const char *name,
+ const lldb::CommandObjectSP &cmd_sp,
+ bool can_replace);
+
+ bool
+ AddUserCommand (std::string name,
+ const lldb::CommandObjectSP &cmd_sp,
+ bool can_replace);
+
+ lldb::CommandObjectSP
+ GetCommandSPExact (const char *cmd,
+ bool include_aliases);
+
+ CommandObject *
+ GetCommandObjectExact (const char *cmd_cstr,
+ bool include_aliases);
+
+ CommandObject *
+ GetCommandObject (const char *cmd,
+ StringList *matches = NULL);
+
+ bool
+ CommandExists (const char *cmd);
+
+ bool
+ AliasExists (const char *cmd);
+
+ bool
+ UserCommandExists (const char *cmd);
+
+ void
+ AddAlias (const char *alias_name,
+ lldb::CommandObjectSP& command_obj_sp);
+
+ bool
+ RemoveAlias (const char *alias_name);
+
+ bool
+ GetAliasFullName (const char *cmd, std::string &full_name);
+
+ bool
+ RemoveUser (const char *alias_name);
+
+ void
+ RemoveAllUser ()
+ {
+ m_user_dict.clear();
+ }
+
+ OptionArgVectorSP
+ GetAliasOptions (const char *alias_name);
+
+
+ bool
+ ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp,
+ const char *options_args,
+ OptionArgVectorSP &option_arg_vector_sp);
+
+ void
+ RemoveAliasOptions (const char *alias_name);
+
+ void
+ AddOrReplaceAliasOptions (const char *alias_name,
+ OptionArgVectorSP &option_arg_vector_sp);
+
+ CommandObject *
+ BuildAliasResult (const char *alias_name,
+ std::string &raw_input_string,
+ std::string &alias_result,
+ CommandReturnObject &result);
+
+ bool
+ HandleCommand (const char *command_line,
+ LazyBool add_to_history,
+ CommandReturnObject &result,
+ ExecutionContext *override_context = NULL,
+ bool repeat_on_empty_command = true,
+ bool no_context_switching = false);
+
+ //------------------------------------------------------------------
+ /// Execute a list of commands in sequence.
+ ///
+ /// @param[in] commands
+ /// The list of commands to execute.
+ /// @param[in/out] context
+ /// The execution context in which to run the commands. Can be NULL in which case the default
+ /// context will be used.
+ /// @param[in] stop_on_continue
+ /// If \b true execution will end on the first command that causes the process in the
+ /// execution context to continue. If \false, we won't check the execution status.
+ /// @param[in] stop_on_error
+ /// If \b true execution will end on the first command that causes an error.
+ /// @param[in] echo_commands
+ /// If \b true echo the command before executing it. If \false, execute silently.
+ /// @param[in] print_results
+ /// If \b true print the results of the command after executing it. If \false, execute silently.
+ /// @param[out] result
+ /// This is marked as succeeding with no output if all commands execute safely,
+ /// and failed with some explanation if we aborted executing the commands at some point.
+ //------------------------------------------------------------------
+ void
+ HandleCommands (const StringList &commands,
+ ExecutionContext *context,
+ bool stop_on_continue,
+ bool stop_on_error,
+ bool echo_commands,
+ bool print_results,
+ LazyBool add_to_history,
+ CommandReturnObject &result);
+
+ //------------------------------------------------------------------
+ /// Execute a list of commands from a file.
+ ///
+ /// @param[in] file
+ /// The file from which to read in commands.
+ /// @param[in/out] context
+ /// The execution context in which to run the commands. Can be NULL in which case the default
+ /// context will be used.
+ /// @param[in] stop_on_continue
+ /// If \b true execution will end on the first command that causes the process in the
+ /// execution context to continue. If \false, we won't check the execution status.
+ /// @param[in] stop_on_error
+ /// If \b true execution will end on the first command that causes an error.
+ /// @param[in] echo_commands
+ /// If \b true echo the command before executing it. If \false, execute silently.
+ /// @param[in] print_results
+ /// If \b true print the results of the command after executing it. If \false, execute silently.
+ /// @param[out] result
+ /// This is marked as succeeding with no output if all commands execute safely,
+ /// and failed with some explanation if we aborted executing the commands at some point.
+ //------------------------------------------------------------------
+ void
+ HandleCommandsFromFile (FileSpec &file,
+ ExecutionContext *context,
+ bool stop_on_continue,
+ bool stop_on_error,
+ bool echo_commands,
+ bool print_results,
+ LazyBool add_to_history,
+ CommandReturnObject &result);
+
+ CommandObject *
+ GetCommandObjectForCommand (std::string &command_line);
+
+ // This handles command line completion. You are given a pointer to the command string buffer, to the current cursor,
+ // and to the end of the string (in case it is not NULL terminated).
+ // You also passed in an StringList object to fill with the returns.
+ // The first element of the array will be filled with the string that you would need to insert at
+ // the cursor point to complete the cursor point to the longest common matching prefix.
+ // If you want to limit the number of elements returned, set max_return_elements to the number of elements
+ // you want returned. Otherwise set max_return_elements to -1.
+ // If you want to start some way into the match list, then set match_start_point to the desired start
+ // point.
+ // Returns:
+ // -1 if the completion character should be inserted
+ // -2 if the entire command line should be deleted and replaced with matches.GetStringAtIndex(0)
+ // INT_MAX if the number of matches is > max_return_elements, but it is expensive to compute.
+ // Otherwise, returns the number of matches.
+ //
+ // FIXME: Only max_return_elements == -1 is supported at present.
+
+ int
+ HandleCompletion (const char *current_line,
+ const char *cursor,
+ const char *last_char,
+ int match_start_point,
+ int max_return_elements,
+ StringList &matches);
+
+ // This version just returns matches, and doesn't compute the substring. It is here so the
+ // Help command can call it for the first argument.
+ // word_complete tells whether a the completions are considered a "complete" response (so the
+ // completer should complete the quote & put a space after the word.
+
+ int
+ HandleCompletionMatches (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+
+ int
+ GetCommandNamesMatchingPartialString (const char *cmd_cstr,
+ bool include_aliases,
+ StringList &matches);
+
+ void
+ GetHelp (CommandReturnObject &result,
+ uint32_t types = eCommandTypesAllThem);
+
+ void
+ GetAliasHelp (const char *alias_name,
+ const char *command_name,
+ StreamString &help_string);
+
+ void
+ OutputFormattedHelpText (Stream &stream,
+ const char *command_word,
+ const char *separator,
+ const char *help_text,
+ size_t max_word_len);
+
+ // this mimics OutputFormattedHelpText but it does perform a much simpler
+ // formatting, basically ensuring line alignment. This is only good if you have
+ // some complicated layout for your help text and want as little help as reasonable
+ // in properly displaying it. Most of the times, you simply want to type some text
+ // and have it printed in a reasonable way on screen. If so, use OutputFormattedHelpText
+ void
+ OutputHelpText (Stream &stream,
+ const char *command_word,
+ const char *separator,
+ const char *help_text,
+ uint32_t max_word_len);
+
+ Debugger &
+ GetDebugger ()
+ {
+ return m_debugger;
+ }
+
+ ExecutionContext
+ GetExecutionContext()
+ {
+ return m_exe_ctx_ref.Lock();
+ }
+
+ void
+ UpdateExecutionContext (ExecutionContext *override_context);
+
+ lldb::PlatformSP
+ GetPlatform (bool prefer_target_platform);
+
+ const char *
+ ProcessEmbeddedScriptCommands (const char *arg);
+
+ const char *
+ GetPrompt ();
+
+ void
+ SetPrompt (const char *);
+
+ bool Confirm (const char *message, bool default_answer);
+
+ static size_t
+ GetConfirmationInputReaderCallback (void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction action,
+ const char *bytes,
+ size_t bytes_len);
+
+ void
+ LoadCommandDictionary ();
+
+ void
+ Initialize ();
+
+ void
+ SetScriptLanguage (lldb::ScriptLanguage lang);
+
+
+ bool
+ HasCommands ();
+
+ bool
+ HasAliases ();
+
+ bool
+ HasUserCommands ();
+
+ bool
+ HasAliasOptions ();
+
+ void
+ BuildAliasCommandArgs (CommandObject *alias_cmd_obj,
+ const char *alias_name,
+ Args &cmd_args,
+ std::string &raw_input_string,
+ CommandReturnObject &result);
+
+ int
+ GetOptionArgumentPosition (const char *in_string);
+
+ ScriptInterpreter *
+ GetScriptInterpreter (bool can_create = true);
+
+ void
+ SkipLLDBInitFiles (bool skip_lldbinit_files)
+ {
+ m_skip_lldbinit_files = skip_lldbinit_files;
+ }
+
+ void
+ SkipAppInitFiles (bool skip_app_init_files)
+ {
+ m_skip_app_init_files = m_skip_lldbinit_files;
+ }
+
+ bool
+ GetSynchronous ();
+
+ size_t
+ FindLongestCommandWord (CommandObject::CommandMap &dict);
+
+ void
+ FindCommandsForApropos (const char *word,
+ StringList &commands_found,
+ StringList &commands_help,
+ bool search_builtin_commands,
+ bool search_user_commands);
+
+ bool
+ GetBatchCommandMode () { return m_batch_command_mode; }
+
+ void
+ SetBatchCommandMode (bool value) { m_batch_command_mode = value; }
+
+ void
+ ChildrenTruncated ()
+ {
+ if (m_truncation_warning == eNoTruncation)
+ m_truncation_warning = eUnwarnedTruncation;
+ }
+
+ bool
+ TruncationWarningNecessary ()
+ {
+ return (m_truncation_warning == eUnwarnedTruncation);
+ }
+
+ void
+ TruncationWarningGiven ()
+ {
+ m_truncation_warning = eWarnedTruncation;
+ }
+
+ const char *
+ TruncationWarningText ()
+ {
+ return "*** Some of your variables have more members than the debugger will show by default. To show all of them, you can either use the --show-all-children option to %s or raise the limit by changing the target.max-children-count setting.\n";
+ }
+
+ const CommandHistory&
+ GetCommandHistory () const
+ {
+ return m_command_history;
+ }
+
+ CommandHistory&
+ GetCommandHistory ()
+ {
+ return m_command_history;
+ }
+
+ //------------------------------------------------------------------
+ // Properties
+ //------------------------------------------------------------------
+ bool
+ GetExpandRegexAliases () const;
+
+ bool
+ GetPromptOnQuit () const;
+
+ bool
+ GetStopCmdSourceOnError () const;
+
+protected:
+ friend class Debugger;
+
+ void
+ SetSynchronous (bool value);
+
+ lldb::CommandObjectSP
+ GetCommandSP (const char *cmd, bool include_aliases = true, bool exact = true, StringList *matches = NULL);
+
+private:
+
+ Error
+ PreprocessCommand (std::string &command);
+
+ Debugger &m_debugger; // The debugger session that this interpreter is associated with
+ ExecutionContextRef m_exe_ctx_ref; // The current execution context to use when handling commands
+ bool m_synchronous_execution;
+ bool m_skip_lldbinit_files;
+ bool m_skip_app_init_files;
+ CommandObject::CommandMap m_command_dict; // Stores basic built-in commands (they cannot be deleted, removed or overwritten).
+ CommandObject::CommandMap m_alias_dict; // Stores user aliases/abbreviations for commands
+ CommandObject::CommandMap m_user_dict; // Stores user-defined commands
+ OptionArgMap m_alias_options; // Stores any options (with or without arguments) that go with any alias.
+ CommandHistory m_command_history;
+ std::string m_repeat_command; // Stores the command that will be executed for an empty command string.
+ std::unique_ptr<ScriptInterpreter> m_script_interpreter_ap;
+ char m_comment_char;
+ bool m_batch_command_mode;
+ ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated children and whether the user has been told
+ uint32_t m_command_source_depth;
+
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_CommandInterpreter_h_
diff --git a/include/lldb/Interpreter/CommandObject.h b/include/lldb/Interpreter/CommandObject.h
new file mode 100644
index 000000000000..2bfab0a8ecc4
--- /dev/null
+++ b/include/lldb/Interpreter/CommandObject.h
@@ -0,0 +1,608 @@
+//===-- CommandObject.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CommandObject_h_
+#define liblldb_CommandObject_h_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandCompletions.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/ExecutionContext.h"
+
+namespace lldb_private {
+
+class CommandObject
+{
+public:
+
+ typedef const char *(ArgumentHelpCallbackFunction) ();
+
+ struct ArgumentHelpCallback
+ {
+ ArgumentHelpCallbackFunction *help_callback;
+ bool self_formatting;
+
+ const char*
+ operator () () const
+ {
+ return (*help_callback)();
+ }
+
+ operator bool() const
+ {
+ return (help_callback != NULL);
+ }
+
+ };
+
+ struct ArgumentTableEntry // Entries in the main argument information table
+ {
+ lldb::CommandArgumentType arg_type;
+ const char *arg_name;
+ CommandCompletions::CommonCompletionTypes completion_type;
+ ArgumentHelpCallback help_function;
+ const char *help_text;
+ };
+
+ struct CommandArgumentData // Used to build individual command argument lists
+ {
+ lldb::CommandArgumentType arg_type;
+ ArgumentRepetitionType arg_repetition;
+ uint32_t arg_opt_set_association; // This arg might be associated only with some particular option set(s).
+ CommandArgumentData():
+ arg_type(lldb::eArgTypeNone),
+ arg_repetition(eArgRepeatPlain),
+ arg_opt_set_association(LLDB_OPT_SET_ALL) // By default, the arg associates to all option sets.
+ {}
+ };
+
+ typedef std::vector<CommandArgumentData> CommandArgumentEntry; // Used to build individual command argument lists
+
+ static ArgumentTableEntry g_arguments_data[lldb::eArgTypeLastArg]; // Main argument information table
+
+ typedef std::map<std::string, lldb::CommandObjectSP> CommandMap;
+
+ CommandObject (CommandInterpreter &interpreter,
+ const char *name,
+ const char *help = NULL,
+ const char *syntax = NULL,
+ uint32_t flags = 0);
+
+ virtual
+ ~CommandObject ();
+
+
+ static const char *
+ GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type);
+
+ static const char *
+ GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type);
+
+ CommandInterpreter &
+ GetCommandInterpreter ()
+ {
+ return m_interpreter;
+ }
+
+ const char *
+ GetHelp ();
+
+ virtual const char *
+ GetHelpLong ();
+
+ const char *
+ GetSyntax ();
+
+ const char *
+ GetCommandName ();
+
+ void
+ SetHelp (const char * str);
+
+ void
+ SetHelpLong (const char * str);
+
+ void
+ SetHelpLong (std::string str);
+
+ void
+ SetSyntax (const char *str);
+
+ // override this to return true if you want to enable the user to delete
+ // the Command object from the Command dictionary (aliases have their own
+ // deletion scheme, so they do not need to care about this)
+ virtual bool
+ IsRemovable () const { return false; }
+
+ bool
+ IsAlias () { return m_is_alias; }
+
+ void
+ SetIsAlias (bool value) { m_is_alias = value; }
+
+ virtual bool
+ IsMultiwordObject () { return false; }
+
+ virtual lldb::CommandObjectSP
+ GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL)
+ {
+ return lldb::CommandObjectSP();
+ }
+
+ virtual CommandObject *
+ GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL)
+ {
+ return NULL;
+ }
+
+ virtual void
+ AproposAllSubCommands (const char *prefix,
+ const char *search_word,
+ StringList &commands_found,
+ StringList &commands_help)
+ {
+ }
+
+ void
+ GenerateHelpText (CommandReturnObject &result);
+
+ virtual void
+ GenerateHelpText (Stream &result);
+
+ // this is needed in order to allow the SBCommand class to
+ // transparently try and load subcommands - it will fail on
+ // anything but a multiword command, but it avoids us doing
+ // type checkings and casts
+ virtual bool
+ LoadSubCommand (const char *cmd_name,
+ const lldb::CommandObjectSP& command_obj)
+ {
+ return false;
+ }
+
+ virtual bool
+ WantsRawCommandString() = 0;
+
+ // By default, WantsCompletion = !WantsRawCommandString.
+ // Subclasses who want raw command string but desire, for example,
+ // argument completion should override this method to return true.
+ virtual bool
+ WantsCompletion() { return !WantsRawCommandString(); }
+
+ virtual Options *
+ GetOptions ();
+
+ static const ArgumentTableEntry*
+ GetArgumentTable ();
+
+ static lldb::CommandArgumentType
+ LookupArgumentName (const char *arg_name);
+
+ static ArgumentTableEntry *
+ FindArgumentDataByType (lldb::CommandArgumentType arg_type);
+
+ int
+ GetNumArgumentEntries ();
+
+ CommandArgumentEntry *
+ GetArgumentEntryAtIndex (int idx);
+
+ static void
+ GetArgumentHelp (Stream &str, lldb::CommandArgumentType arg_type, CommandInterpreter &interpreter);
+
+ static const char *
+ GetArgumentName (lldb::CommandArgumentType arg_type);
+
+ // Generates a nicely formatted command args string for help command output.
+ // By default, all possible args are taken into account, for example,
+ // '<expr | variable-name>'. This can be refined by passing a second arg
+ // specifying which option set(s) we are interested, which could then, for
+ // example, produce either '<expr>' or '<variable-name>'.
+ void
+ GetFormattedCommandArguments (Stream &str, uint32_t opt_set_mask = LLDB_OPT_SET_ALL);
+
+ bool
+ IsPairType (ArgumentRepetitionType arg_repeat_type);
+
+ enum
+ {
+ //----------------------------------------------------------------------
+ // eFlagRequiresTarget
+ //
+ // Ensures a valid target is contained in m_exe_ctx prior to executing
+ // the command. If a target doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidTargetDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidTargetDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eFlagRequiresTarget = (1u << 0),
+ //----------------------------------------------------------------------
+ // eFlagRequiresProcess
+ //
+ // Ensures a valid process is contained in m_exe_ctx prior to executing
+ // the command. If a process doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidProcessDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidProcessDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eFlagRequiresProcess = (1u << 1),
+ //----------------------------------------------------------------------
+ // eFlagRequiresThread
+ //
+ // Ensures a valid thread is contained in m_exe_ctx prior to executing
+ // the command. If a thread doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidThreadDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidThreadDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eFlagRequiresThread = (1u << 2),
+ //----------------------------------------------------------------------
+ // eFlagRequiresFrame
+ //
+ // Ensures a valid frame is contained in m_exe_ctx prior to executing
+ // the command. If a frame doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidFrameDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidFrameDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eFlagRequiresFrame = (1u << 3),
+ //----------------------------------------------------------------------
+ // eFlagRequiresRegContext
+ //
+ // Ensures a valid register context (from the selected frame if there
+ // is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
+ // is availble from m_exe_ctx prior to executing the command. If a
+ // target doesn't exist or is invalid, the command will fail and
+ // CommandObject::GetInvalidRegContextDescription() will be returned as
+ // the error. CommandObject subclasses can override the virtual function
+ // for GetInvalidRegContextDescription() to provide custom strings when
+ // needed.
+ //----------------------------------------------------------------------
+ eFlagRequiresRegContext = (1u << 4),
+ //----------------------------------------------------------------------
+ // eFlagTryTargetAPILock
+ //
+ // Attempts to acquire the target lock if a target is selected in the
+ // command interpreter. If the command object fails to acquire the API
+ // lock, the command will fail with an appropriate error message.
+ //----------------------------------------------------------------------
+ eFlagTryTargetAPILock = (1u << 5),
+ //----------------------------------------------------------------------
+ // eFlagProcessMustBeLaunched
+ //
+ // Verifies that there is a launched process in m_exe_ctx, if there
+ // isn't, the command will fail with an appropriate error message.
+ //----------------------------------------------------------------------
+ eFlagProcessMustBeLaunched = (1u << 6),
+ //----------------------------------------------------------------------
+ // eFlagProcessMustBePaused
+ //
+ // Verifies that there is a paused process in m_exe_ctx, if there
+ // isn't, the command will fail with an appropriate error message.
+ //----------------------------------------------------------------------
+ eFlagProcessMustBePaused = (1u << 7)
+ };
+
+ bool
+ ParseOptions (Args& args, CommandReturnObject &result);
+
+ void
+ SetCommandName (const char *name);
+
+ // This function really deals with CommandObjectLists, but we didn't make a
+ // CommandObjectList class, so I'm sticking it here. But we really should have
+ // such a class. Anyway, it looks up the commands in the map that match the partial
+ // string cmd_str, inserts the matches into matches, and returns the number added.
+
+ static int
+ AddNamesMatchingPartialString (CommandMap &in_map, const char *cmd_str, StringList &matches);
+
+ //------------------------------------------------------------------
+ /// The input array contains a parsed version of the line. The insertion
+ /// point is given by cursor_index (the index in input of the word containing
+ /// the cursor) and cursor_char_position (the position of the cursor in that word.)
+ /// This default version handles calling option argument completions and then calls
+ /// HandleArgumentCompletion if the cursor is on an argument, not an option.
+ /// Don't override this method, override HandleArgumentCompletion instead unless
+ /// you have special reasons.
+ ///
+ /// @param[in] interpreter
+ /// The command interpreter doing the completion.
+ ///
+ /// @param[in] input
+ /// The command line parsed into words
+ ///
+ /// @param[in] cursor_index
+ /// The index in \ainput of the word in which the cursor lies.
+ ///
+ /// @param[in] cursor_char_pos
+ /// The character position of the cursor in its argument word.
+ ///
+ /// @param[in] match_start_point
+ /// @param[in] match_return_elements
+ /// FIXME: Not yet implemented... If there is a match that is expensive to compute, these are
+ /// here to allow you to compute the completions in batches. Start the completion from \amatch_start_point,
+ /// and return \amatch_return_elements elements.
+ ///
+ /// @param[out] word_complete
+ /// \btrue if this is a complete option value (a space will be inserted after the
+ /// completion.) \bfalse otherwise.
+ ///
+ /// @param[out] matches
+ /// The array of matches returned.
+ ///
+ /// FIXME: This is the wrong return value, since we also need to make a distinction between
+ /// total number of matches, and the window the user wants returned.
+ ///
+ /// @return
+ /// \btrue if we were in an option, \bfalse otherwise.
+ //------------------------------------------------------------------
+ virtual int
+ HandleCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+ //------------------------------------------------------------------
+ /// The input array contains a parsed version of the line. The insertion
+ /// point is given by cursor_index (the index in input of the word containing
+ /// the cursor) and cursor_char_position (the position of the cursor in that word.)
+ /// We've constructed the map of options and their arguments as well if that is
+ /// helpful for the completion.
+ ///
+ /// @param[in] interpreter
+ /// The command interpreter doing the completion.
+ ///
+ /// @param[in] input
+ /// The command line parsed into words
+ ///
+ /// @param[in] cursor_index
+ /// The index in \ainput of the word in which the cursor lies.
+ ///
+ /// @param[in] cursor_char_pos
+ /// The character position of the cursor in its argument word.
+ ///
+ /// @param[in] opt_element_vector
+ /// The results of the options parse of \a input.
+ ///
+ /// @param[in] match_start_point
+ /// @param[in] match_return_elements
+ /// See CommandObject::HandleCompletions for a description of how these work.
+ ///
+ /// @param[out] word_complete
+ /// \btrue if this is a complete option value (a space will be inserted after the
+ /// completion.) \bfalse otherwise.
+ ///
+ /// @param[out] matches
+ /// The array of matches returned.
+ ///
+ /// FIXME: This is the wrong return value, since we also need to make a distinction between
+ /// total number of matches, and the window the user wants returned.
+ ///
+ /// @return
+ /// The number of completions.
+ //------------------------------------------------------------------
+
+ virtual int
+ HandleArgumentCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
+ {
+ return 0;
+ }
+
+ bool
+ HelpTextContainsWord (const char *search_word);
+
+ //------------------------------------------------------------------
+ /// The flags accessor.
+ ///
+ /// @return
+ /// A reference to the Flags member variable.
+ //------------------------------------------------------------------
+ Flags&
+ GetFlags()
+ {
+ return m_flags;
+ }
+
+ //------------------------------------------------------------------
+ /// The flags const accessor.
+ ///
+ /// @return
+ /// A const reference to the Flags member variable.
+ //------------------------------------------------------------------
+ const Flags&
+ GetFlags() const
+ {
+ return m_flags;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the command that appropriate for a "repeat" of the current command.
+ ///
+ /// @param[in] current_command_line
+ /// The complete current command line.
+ ///
+ /// @return
+ /// NULL if there is no special repeat command - it will use the current command line.
+ /// Otherwise a pointer to the command to be repeated.
+ /// If the returned string is the empty string, the command won't be repeated.
+ //------------------------------------------------------------------
+ virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
+ {
+ return NULL;
+ }
+
+ CommandOverrideCallback
+ GetOverrideCallback () const
+ {
+ return m_command_override_callback;
+ }
+
+ void *
+ GetOverrideCallbackBaton () const
+ {
+ return m_command_override_baton;
+ }
+
+ void
+ SetOverrideCallback (CommandOverrideCallback callback, void *baton)
+ {
+ m_command_override_callback = callback;
+ m_command_override_baton = baton;
+ }
+
+ virtual bool
+ Execute (const char *args_string, CommandReturnObject &result) = 0;
+
+protected:
+ virtual const char *
+ GetInvalidTargetDescription()
+ {
+ return "invalid target, create a target using the 'target create' command";
+ }
+
+ virtual const char *
+ GetInvalidProcessDescription()
+ {
+ return "invalid process";
+ }
+
+ virtual const char *
+ GetInvalidThreadDescription()
+ {
+ return "invalid thread";
+ }
+
+ virtual const char *
+ GetInvalidFrameDescription()
+ {
+ return "invalid frame";
+ }
+
+ virtual const char *
+ GetInvalidRegContextDescription ()
+ {
+ return "invalid frame, no registers";
+ }
+
+ //------------------------------------------------------------------
+ /// Check the command to make sure anything required by this
+ /// command is available.
+ ///
+ /// @param[out] result
+ /// A command result object, if it is not okay to run the command
+ /// this will be filled in with a suitable error.
+ ///
+ /// @return
+ /// \b true if it is okay to run this command, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ CheckRequirements (CommandReturnObject &result);
+
+ void
+ Cleanup ();
+
+ CommandInterpreter &m_interpreter;
+ ExecutionContext m_exe_ctx;
+ Mutex::Locker m_api_locker;
+ std::string m_cmd_name;
+ std::string m_cmd_help_short;
+ std::string m_cmd_help_long;
+ std::string m_cmd_syntax;
+ bool m_is_alias;
+ Flags m_flags;
+ std::vector<CommandArgumentEntry> m_arguments;
+ CommandOverrideCallback m_command_override_callback;
+ void * m_command_override_baton;
+
+ // Helper function to populate IDs or ID ranges as the command argument data
+ // to the specified command argument entry.
+ static void
+ AddIDsArgumentData(CommandArgumentEntry &arg, lldb::CommandArgumentType ID, lldb::CommandArgumentType IDRange);
+
+};
+
+class CommandObjectParsed : public CommandObject
+{
+public:
+
+ CommandObjectParsed (CommandInterpreter &interpreter,
+ const char *name,
+ const char *help = NULL,
+ const char *syntax = NULL,
+ uint32_t flags = 0) :
+ CommandObject (interpreter, name, help, syntax, flags) {}
+
+ virtual
+ ~CommandObjectParsed () {};
+
+ virtual bool
+ Execute (const char *args_string, CommandReturnObject &result);
+
+protected:
+ virtual bool
+ DoExecute (Args& command,
+ CommandReturnObject &result) = 0;
+
+ virtual bool
+ WantsRawCommandString() { return false; };
+};
+
+class CommandObjectRaw : public CommandObject
+{
+public:
+
+ CommandObjectRaw (CommandInterpreter &interpreter,
+ const char *name,
+ const char *help = NULL,
+ const char *syntax = NULL,
+ uint32_t flags = 0) :
+ CommandObject (interpreter, name, help, syntax, flags) {}
+
+ virtual
+ ~CommandObjectRaw () {};
+
+ virtual bool
+ Execute (const char *args_string, CommandReturnObject &result);
+
+protected:
+ virtual bool
+ DoExecute (const char *command, CommandReturnObject &result) = 0;
+
+ virtual bool
+ WantsRawCommandString() { return true; };
+};
+
+
+} // namespace lldb_private
+
+
+#endif // liblldb_CommandObject_h_
diff --git a/include/lldb/Interpreter/CommandObjectMultiword.h b/include/lldb/Interpreter/CommandObjectMultiword.h
new file mode 100644
index 000000000000..491d43c4bd9d
--- /dev/null
+++ b/include/lldb/Interpreter/CommandObjectMultiword.h
@@ -0,0 +1,187 @@
+//===-- CommandObjectMultiword.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CommandObjectMultiword_h_
+#define liblldb_CommandObjectMultiword_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/CommandObject.h"
+
+namespace lldb_private {
+
+//-------------------------------------------------------------------------
+// CommandObjectMultiword
+//-------------------------------------------------------------------------
+
+class CommandObjectMultiword : public CommandObject
+{
+// These two want to iterate over the subcommand dictionary.
+friend class CommandInterpreter;
+friend class CommandObjectSyntax;
+public:
+ CommandObjectMultiword (CommandInterpreter &interpreter,
+ const char *name,
+ const char *help = NULL,
+ const char *syntax = NULL,
+ uint32_t flags = 0);
+
+ virtual
+ ~CommandObjectMultiword ();
+
+ virtual bool
+ IsMultiwordObject () { return true; }
+
+ virtual bool
+ LoadSubCommand (const char *cmd_name,
+ const lldb::CommandObjectSP& command_obj);
+
+ virtual void
+ GenerateHelpText (Stream &output_stream);
+
+ virtual lldb::CommandObjectSP
+ GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL);
+
+ virtual CommandObject *
+ GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL);
+
+ virtual void
+ AproposAllSubCommands (const char *prefix,
+ const char *search_word,
+ StringList &commands_found,
+ StringList &commands_help);
+
+ virtual bool
+ WantsRawCommandString() { return false; };
+
+ virtual int
+ HandleCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+ virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index);
+
+ virtual bool
+ Execute (const char *args_string,
+ CommandReturnObject &result);
+
+ virtual bool
+ IsRemovable() const { return m_can_be_removed; }
+
+ void
+ SetRemovable (bool removable)
+ {
+ m_can_be_removed = removable;
+ }
+
+protected:
+
+ CommandObject::CommandMap m_subcommand_dict;
+ bool m_can_be_removed;
+};
+
+
+class CommandObjectProxy : public CommandObject
+{
+public:
+ CommandObjectProxy (CommandInterpreter &interpreter,
+ const char *name,
+ const char *help = NULL,
+ const char *syntax = NULL,
+ uint32_t flags = 0);
+
+ virtual
+ ~CommandObjectProxy ();
+
+ // Subclasses must provide a command object that will be transparently
+ // used for this object.
+ virtual CommandObject *
+ GetProxyCommandObject() = 0;
+
+ virtual const char *
+ GetHelpLong ();
+
+ virtual bool
+ IsRemovable() const;
+
+ virtual bool
+ IsMultiwordObject ();
+
+ virtual lldb::CommandObjectSP
+ GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL);
+
+ virtual CommandObject *
+ GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL);
+
+ virtual void
+ AproposAllSubCommands (const char *prefix,
+ const char *search_word,
+ StringList &commands_found,
+ StringList &commands_help);
+
+ virtual bool
+ LoadSubCommand (const char *cmd_name,
+ const lldb::CommandObjectSP& command_obj);
+
+ virtual bool
+ WantsRawCommandString();
+
+ virtual bool
+ WantsCompletion();
+
+ virtual Options *
+ GetOptions ();
+
+
+ virtual int
+ HandleCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+ virtual int
+ HandleArgumentCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+ virtual const char *
+ GetRepeatCommand (Args &current_command_args,
+ uint32_t index);
+
+ virtual bool
+ Execute (const char *args_string,
+ CommandReturnObject &result);
+
+protected:
+
+ // These two want to iterate over the subcommand dictionary.
+ friend class CommandInterpreter;
+ friend class CommandObjectSyntax;
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CommandObjectMultiword_h_
diff --git a/include/lldb/Interpreter/CommandObjectRegexCommand.h b/include/lldb/Interpreter/CommandObjectRegexCommand.h
new file mode 100644
index 000000000000..8855680d5f8b
--- /dev/null
+++ b/include/lldb/Interpreter/CommandObjectRegexCommand.h
@@ -0,0 +1,81 @@
+//===-- CommandObjectRegexCommand.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CommandObjectRegexCommand_h_
+#define liblldb_CommandObjectRegexCommand_h_
+
+// C Includes
+// C++ Includes
+#include <list>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Interpreter/CommandObject.h"
+
+namespace lldb_private {
+
+//-------------------------------------------------------------------------
+// CommandObjectRegexCommand
+//-------------------------------------------------------------------------
+
+class CommandObjectRegexCommand : public CommandObjectRaw
+{
+public:
+
+ CommandObjectRegexCommand (CommandInterpreter &interpreter,
+ const char *name,
+ const char *help,
+ const char *syntax,
+ uint32_t max_matches,
+ uint32_t completion_type_mask = 0);
+
+ virtual
+ ~CommandObjectRegexCommand ();
+
+ bool
+ AddRegexCommand (const char *re_cstr, const char *command_cstr);
+
+ bool
+ HasRegexEntries () const
+ {
+ return !m_entries.empty();
+ }
+
+ virtual int
+ HandleCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+protected:
+ virtual bool
+ DoExecute (const char *command, CommandReturnObject &result);
+
+ struct Entry
+ {
+ RegularExpression regex;
+ std::string command;
+ };
+
+ typedef std::list<Entry> EntryCollection;
+ const uint32_t m_max_matches;
+ const uint32_t m_completion_type_mask;
+ EntryCollection m_entries;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (CommandObjectRegexCommand);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CommandObjectRegexCommand_h_
diff --git a/include/lldb/Interpreter/CommandReturnObject.h b/include/lldb/Interpreter/CommandReturnObject.h
new file mode 100644
index 000000000000..acd03992e5e6
--- /dev/null
+++ b/include/lldb/Interpreter/CommandReturnObject.h
@@ -0,0 +1,183 @@
+//===-- CommandReturnObject.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CommandReturnObject_h_
+#define liblldb_CommandReturnObject_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/STLUtils.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/StreamTee.h"
+
+namespace lldb_private {
+
+
+class CommandReturnObject
+{
+public:
+
+ CommandReturnObject ();
+
+ ~CommandReturnObject ();
+
+ const char *
+ GetOutputData ()
+ {
+ lldb::StreamSP stream_sp (m_out_stream.GetStreamAtIndex (eStreamStringIndex));
+ if (stream_sp)
+ return static_cast<StreamString *>(stream_sp.get())->GetData();
+ return "";
+ }
+
+ const char *
+ GetErrorData ()
+ {
+ lldb::StreamSP stream_sp (m_err_stream.GetStreamAtIndex (eStreamStringIndex));
+ if (stream_sp)
+ return static_cast<StreamString *>(stream_sp.get())->GetData();
+ else
+ return "";
+ }
+
+ Stream &
+ GetOutputStream ()
+ {
+ // Make sure we at least have our normal string stream output stream
+ lldb::StreamSP stream_sp (m_out_stream.GetStreamAtIndex (eStreamStringIndex));
+ if (!stream_sp)
+ {
+ stream_sp.reset (new StreamString());
+ m_out_stream.SetStreamAtIndex (eStreamStringIndex, stream_sp);
+ }
+ return m_out_stream;
+ }
+
+ Stream &
+ GetErrorStream ()
+ {
+ // Make sure we at least have our normal string stream output stream
+ lldb::StreamSP stream_sp (m_err_stream.GetStreamAtIndex (eStreamStringIndex));
+ if (!stream_sp)
+ {
+ stream_sp.reset (new StreamString());
+ m_err_stream.SetStreamAtIndex (eStreamStringIndex, stream_sp);
+ }
+ return m_err_stream;
+ }
+
+ void
+ SetImmediateOutputFile (FILE *fh, bool transfer_fh_ownership = false)
+ {
+ lldb::StreamSP stream_sp (new StreamFile (fh, transfer_fh_ownership));
+ m_out_stream.SetStreamAtIndex (eImmediateStreamIndex, stream_sp);
+ }
+
+ void
+ SetImmediateErrorFile (FILE *fh, bool transfer_fh_ownership = false)
+ {
+ lldb::StreamSP stream_sp (new StreamFile (fh, transfer_fh_ownership));
+ m_err_stream.SetStreamAtIndex (eImmediateStreamIndex, stream_sp);
+ }
+
+ void
+ SetImmediateOutputStream (const lldb::StreamSP &stream_sp)
+ {
+ m_out_stream.SetStreamAtIndex (eImmediateStreamIndex, stream_sp);
+ }
+
+ void
+ SetImmediateErrorStream (const lldb::StreamSP &stream_sp)
+ {
+ m_err_stream.SetStreamAtIndex (eImmediateStreamIndex, stream_sp);
+ }
+
+ lldb::StreamSP
+ GetImmediateOutputStream ()
+ {
+ return m_out_stream.GetStreamAtIndex (eImmediateStreamIndex);
+ }
+
+ lldb::StreamSP
+ GetImmediateErrorStream ()
+ {
+ return m_err_stream.GetStreamAtIndex (eImmediateStreamIndex);
+ }
+
+ void
+ Clear();
+
+ void
+ AppendMessage (const char *in_string);
+
+ void
+ AppendMessageWithFormat (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ AppendRawWarning (const char *in_string);
+
+ void
+ AppendWarning (const char *in_string);
+
+ void
+ AppendWarningWithFormat (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ AppendError (const char *in_string);
+
+ void
+ AppendRawError (const char *in_string);
+
+ void
+ AppendErrorWithFormat (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ SetError (const Error &error,
+ const char *fallback_error_cstr = NULL);
+
+ void
+ SetError (const char *error_cstr);
+
+ lldb::ReturnStatus
+ GetStatus();
+
+ void
+ SetStatus (lldb::ReturnStatus status);
+
+ bool
+ Succeeded ();
+
+ bool
+ HasResult ();
+
+ bool GetDidChangeProcessState ();
+
+ void SetDidChangeProcessState (bool b);
+
+private:
+ enum
+ {
+ eStreamStringIndex = 0,
+ eImmediateStreamIndex = 1
+ };
+
+ StreamTee m_out_stream;
+ StreamTee m_err_stream;
+
+ lldb::ReturnStatus m_status;
+ bool m_did_change_process_state;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CommandReturnObject_h_
diff --git a/include/lldb/Interpreter/OptionGroupArchitecture.h b/include/lldb/Interpreter/OptionGroupArchitecture.h
new file mode 100644
index 000000000000..7cd1ca3d710d
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupArchitecture.h
@@ -0,0 +1,73 @@
+//===-- OptionGroupArchitecture.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupArchitecture_h_
+#define liblldb_OptionGroupArchitecture_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Core/ArchSpec.h"
+
+namespace lldb_private {
+
+//-------------------------------------------------------------------------
+// OptionGroupArchitecture
+//-------------------------------------------------------------------------
+
+class OptionGroupArchitecture : public OptionGroup
+{
+public:
+
+ OptionGroupArchitecture ();
+
+ virtual
+ ~OptionGroupArchitecture ();
+
+
+ virtual uint32_t
+ GetNumDefinitions ();
+
+ virtual const OptionDefinition*
+ GetDefinitions ();
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ bool
+ GetArchitecture (Platform *platform, ArchSpec &arch);
+
+ bool
+ ArchitectureWasSpecified () const
+ {
+ return !m_arch_str.empty();
+ }
+ const char *
+ GetArchitectureName ()
+ {
+ if (m_arch_str.empty())
+ return NULL;
+ return m_arch_str.c_str();
+ }
+
+protected:
+
+ std::string m_arch_str; // Save the arch triple in case a platform is specified after the architecture
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupArchitecture_h_
diff --git a/include/lldb/Interpreter/OptionGroupBoolean.h b/include/lldb/Interpreter/OptionGroupBoolean.h
new file mode 100644
index 000000000000..0d861b241694
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupBoolean.h
@@ -0,0 +1,83 @@
+//===-- OptionGroupBoolean.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupBoolean_h_
+#define liblldb_OptionGroupBoolean_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
+
+namespace lldb_private {
+ //-------------------------------------------------------------------------
+ // OptionGroupBoolean
+ //-------------------------------------------------------------------------
+
+ class OptionGroupBoolean : public OptionGroup
+ {
+ public:
+ // When 'no_argument_toggle_default' is true, then setting the option
+ // value does NOT require an argument, it sets the boolean value to the
+ // inverse of the default value
+ OptionGroupBoolean (uint32_t usage_mask,
+ bool required,
+ const char *long_option,
+ int short_option,
+ const char *usage_text,
+ bool default_value,
+ bool no_argument_toggle_default);
+
+ virtual
+ ~OptionGroupBoolean ();
+
+
+ virtual uint32_t
+ GetNumDefinitions ()
+ {
+ return 1;
+ }
+
+ virtual const OptionDefinition*
+ GetDefinitions ()
+ {
+ return &m_option_definition;
+ }
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ OptionValueBoolean &
+ GetOptionValue ()
+ {
+ return m_value;
+ }
+
+ const OptionValueBoolean &
+ GetOptionValue () const
+ {
+ return m_value;
+ }
+
+ protected:
+ OptionValueBoolean m_value;
+ OptionDefinition m_option_definition;
+
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupBoolean_h_
diff --git a/include/lldb/Interpreter/OptionGroupFile.h b/include/lldb/Interpreter/OptionGroupFile.h
new file mode 100644
index 000000000000..632a2dbdf220
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupFile.h
@@ -0,0 +1,142 @@
+//===-- OptionGroupFile.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupFile_h_
+#define liblldb_OptionGroupFile_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/OptionValueFileSpec.h"
+#include "lldb/Interpreter/OptionValueFileSpecList.h"
+
+namespace lldb_private {
+
+//-------------------------------------------------------------------------
+// OptionGroupFile
+//-------------------------------------------------------------------------
+
+class OptionGroupFile : public OptionGroup
+{
+public:
+
+ OptionGroupFile (uint32_t usage_mask,
+ bool required,
+ const char *long_option,
+ int short_option,
+ uint32_t completion_type,
+ lldb::CommandArgumentType argument_type,
+ const char *usage_text);
+
+ virtual
+ ~OptionGroupFile ();
+
+
+ virtual uint32_t
+ GetNumDefinitions ()
+ {
+ return 1;
+ }
+
+ virtual const OptionDefinition*
+ GetDefinitions ()
+ {
+ return &m_option_definition;
+ }
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ OptionValueFileSpec &
+ GetOptionValue ()
+ {
+ return m_file;
+ }
+
+ const OptionValueFileSpec &
+ GetOptionValue () const
+ {
+ return m_file;
+ }
+
+protected:
+ OptionValueFileSpec m_file;
+ OptionDefinition m_option_definition;
+
+};
+
+//-------------------------------------------------------------------------
+// OptionGroupFileList
+//-------------------------------------------------------------------------
+
+class OptionGroupFileList : public OptionGroup
+{
+public:
+
+ OptionGroupFileList (uint32_t usage_mask,
+ bool required,
+ const char *long_option,
+ int short_option,
+ uint32_t completion_type,
+ lldb::CommandArgumentType argument_type,
+ const char *usage_text);
+
+ virtual
+ ~OptionGroupFileList ();
+
+
+ virtual uint32_t
+ GetNumDefinitions ()
+ {
+ return 1;
+ }
+
+ virtual const OptionDefinition*
+ GetDefinitions ()
+ {
+ return &m_option_definition;
+ }
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+
+ OptionValueFileSpecList &
+ GetOptionValue ()
+ {
+ return m_file_list;
+ }
+
+ const OptionValueFileSpecList &
+ GetOptionValue () const
+ {
+ return m_file_list;
+ }
+
+protected:
+ OptionValueFileSpecList m_file_list;
+ OptionDefinition m_option_definition;
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupFile_h_
diff --git a/include/lldb/Interpreter/OptionGroupFormat.h b/include/lldb/Interpreter/OptionGroupFormat.h
new file mode 100644
index 000000000000..7419b0496668
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupFormat.h
@@ -0,0 +1,133 @@
+//===-- OptionGroupFormat.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupFormat_h_
+#define liblldb_OptionGroupFormat_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/OptionValueFormat.h"
+#include "lldb/Interpreter/OptionValueSInt64.h"
+#include "lldb/Interpreter/OptionValueUInt64.h"
+
+namespace lldb_private {
+
+//-------------------------------------------------------------------------
+// OptionGroupFormat
+//-------------------------------------------------------------------------
+
+class OptionGroupFormat : public OptionGroup
+{
+public:
+ static const uint32_t OPTION_GROUP_FORMAT = LLDB_OPT_SET_1;
+ static const uint32_t OPTION_GROUP_GDB_FMT = LLDB_OPT_SET_2;
+ static const uint32_t OPTION_GROUP_SIZE = LLDB_OPT_SET_3;
+ static const uint32_t OPTION_GROUP_COUNT = LLDB_OPT_SET_4;
+
+ OptionGroupFormat (lldb::Format default_format,
+ uint64_t default_byte_size = UINT64_MAX, // Pass UINT64_MAX to disable the "--size" option
+ uint64_t default_count = UINT64_MAX); // Pass UINT64_MAX to disable the "--count" option
+
+ virtual
+ ~OptionGroupFormat ();
+
+
+ virtual uint32_t
+ GetNumDefinitions ();
+
+ virtual const OptionDefinition*
+ GetDefinitions ();
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ lldb::Format
+ GetFormat () const
+ {
+ return m_format.GetCurrentValue();
+ }
+
+ OptionValueFormat &
+ GetFormatValue()
+ {
+ return m_format;
+ }
+
+ const OptionValueFormat &
+ GetFormatValue() const
+ {
+ return m_format;
+ }
+
+ OptionValueUInt64 &
+ GetByteSizeValue()
+ {
+ return m_byte_size;
+ }
+
+ const OptionValueUInt64 &
+ GetByteSizeValue() const
+ {
+ return m_byte_size;
+ }
+
+ OptionValueUInt64 &
+ GetCountValue()
+ {
+ return m_count;
+ }
+
+ const OptionValueUInt64 &
+ GetCountValue() const
+ {
+ return m_count;
+ }
+
+ bool
+ HasGDBFormat () const
+ {
+ return m_has_gdb_format;
+ }
+
+ bool
+ AnyOptionWasSet () const
+ {
+ return m_format.OptionWasSet() ||
+ m_byte_size.OptionWasSet() ||
+ m_count.OptionWasSet();
+ }
+
+protected:
+
+ bool
+ ParserGDBFormatLetter (CommandInterpreter &interpreter,
+ char format_letter,
+ lldb::Format &format,
+ uint32_t &byte_size);
+
+ OptionValueFormat m_format;
+ OptionValueUInt64 m_byte_size;
+ OptionValueUInt64 m_count;
+ char m_prev_gdb_format;
+ char m_prev_gdb_size;
+
+ bool m_has_gdb_format;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupFormat_h_
diff --git a/include/lldb/Interpreter/OptionGroupOutputFile.h b/include/lldb/Interpreter/OptionGroupOutputFile.h
new file mode 100644
index 000000000000..533cd6ee8eb3
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupOutputFile.h
@@ -0,0 +1,76 @@
+//===-- OptionGroupOutputFile.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupOutputFile_h_
+#define liblldb_OptionGroupOutputFile_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueFileSpec.h"
+
+namespace lldb_private {
+//-------------------------------------------------------------------------
+// OptionGroupOutputFile
+//-------------------------------------------------------------------------
+
+class OptionGroupOutputFile : public OptionGroup
+{
+public:
+
+ OptionGroupOutputFile ();
+
+ virtual
+ ~OptionGroupOutputFile ();
+
+
+ virtual uint32_t
+ GetNumDefinitions ();
+
+ virtual const OptionDefinition*
+ GetDefinitions ();
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ const OptionValueFileSpec &
+ GetFile ()
+ {
+ return m_file;
+ }
+
+ const OptionValueBoolean &
+ GetAppend ()
+ {
+ return m_append;
+ }
+
+ bool
+ AnyOptionWasSet () const
+ {
+ return m_file.OptionWasSet() || m_append.OptionWasSet();
+ }
+
+protected:
+ OptionValueFileSpec m_file;
+ OptionValueBoolean m_append;
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupOutputFile_h_
diff --git a/include/lldb/Interpreter/OptionGroupPlatform.h b/include/lldb/Interpreter/OptionGroupPlatform.h
new file mode 100644
index 000000000000..970ad328ccb7
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupPlatform.h
@@ -0,0 +1,120 @@
+//===-- OptionGroupPlatform.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupPlatform_h_
+#define liblldb_OptionGroupPlatform_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Interpreter/Options.h"
+
+namespace lldb_private {
+
+//-------------------------------------------------------------------------
+// PlatformOptionGroup
+//
+// Make platform options available to any commands that need the settings.
+//-------------------------------------------------------------------------
+class OptionGroupPlatform : public OptionGroup
+{
+public:
+
+ OptionGroupPlatform (bool include_platform_option) :
+ OptionGroup(),
+ m_platform_name (),
+ m_sdk_sysroot (),
+ m_os_version_major (UINT32_MAX),
+ m_os_version_minor (UINT32_MAX),
+ m_os_version_update (UINT32_MAX),
+ m_include_platform_option (include_platform_option)
+ {
+ }
+
+ virtual
+ ~OptionGroupPlatform ()
+ {
+ }
+
+ virtual uint32_t
+ GetNumDefinitions ();
+
+ virtual const OptionDefinition*
+ GetDefinitions ();
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ lldb::PlatformSP
+ CreatePlatformWithOptions (CommandInterpreter &interpreter,
+ const ArchSpec &arch,
+ bool make_selected,
+ Error& error,
+ ArchSpec &platform_arch) const;
+
+ bool
+ PlatformWasSpecified () const
+ {
+ return !m_platform_name.empty();
+ }
+
+ void
+ SetPlatformName (const char *platform_name)
+ {
+ if (platform_name && platform_name[0])
+ m_platform_name.assign (platform_name);
+ else
+ m_platform_name.clear();
+ }
+
+ const ConstString &
+ GetSDKRootDirectory () const
+ {
+ return m_sdk_sysroot;
+ }
+
+ void
+ SetSDKRootDirectory (const ConstString &sdk_root_directory)
+ {
+ m_sdk_sysroot = sdk_root_directory;
+ }
+
+ const ConstString &
+ GetSDKBuild () const
+ {
+ return m_sdk_build;
+ }
+
+ void
+ SetSDKBuild (const ConstString &sdk_build)
+ {
+ m_sdk_build = sdk_build;
+ }
+
+
+protected:
+ std::string m_platform_name;
+ ConstString m_sdk_sysroot;
+ ConstString m_sdk_build;
+ uint32_t m_os_version_major;
+ uint32_t m_os_version_minor;
+ uint32_t m_os_version_update;
+ bool m_include_platform_option;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupPlatform_h_
diff --git a/include/lldb/Interpreter/OptionGroupString.h b/include/lldb/Interpreter/OptionGroupString.h
new file mode 100644
index 000000000000..e62a81bc4118
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupString.h
@@ -0,0 +1,82 @@
+//===-- OptionGroupString.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupString_h_
+#define liblldb_OptionGroupString_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/OptionValueString.h"
+
+namespace lldb_private {
+ //-------------------------------------------------------------------------
+ // OptionGroupString
+ //-------------------------------------------------------------------------
+
+ class OptionGroupString : public OptionGroup
+ {
+ public:
+
+ OptionGroupString (uint32_t usage_mask,
+ bool required,
+ const char *long_option,
+ int short_option,
+ uint32_t completion_type,
+ lldb::CommandArgumentType argument_type,
+ const char *usage_text,
+ const char *default_value);
+
+ virtual
+ ~OptionGroupString ();
+
+
+ virtual uint32_t
+ GetNumDefinitions ()
+ {
+ return 1;
+ }
+
+ virtual const OptionDefinition*
+ GetDefinitions ()
+ {
+ return &m_option_definition;
+ }
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ OptionValueString &
+ GetOptionValue ()
+ {
+ return m_value;
+ }
+
+ const OptionValueString &
+ GetOptionValue () const
+ {
+ return m_value;
+ }
+
+ protected:
+ OptionValueString m_value;
+ OptionDefinition m_option_definition;
+
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupString_h_
diff --git a/include/lldb/Interpreter/OptionGroupUInt64.h b/include/lldb/Interpreter/OptionGroupUInt64.h
new file mode 100644
index 000000000000..c5f9e85d2f8f
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupUInt64.h
@@ -0,0 +1,82 @@
+//===-- OptionGroupUInt64.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupUInt64_h_
+#define liblldb_OptionGroupUInt64_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/OptionValueUInt64.h"
+
+namespace lldb_private {
+ //-------------------------------------------------------------------------
+ // OptionGroupUInt64
+ //-------------------------------------------------------------------------
+
+ class OptionGroupUInt64 : public OptionGroup
+ {
+ public:
+
+ OptionGroupUInt64 (uint32_t usage_mask,
+ bool required,
+ const char *long_option,
+ int short_option,
+ uint32_t completion_type,
+ lldb::CommandArgumentType argument_type,
+ const char *usage_text,
+ uint64_t default_value);
+
+ virtual
+ ~OptionGroupUInt64 ();
+
+
+ virtual uint32_t
+ GetNumDefinitions ()
+ {
+ return 1;
+ }
+
+ virtual const OptionDefinition*
+ GetDefinitions ()
+ {
+ return &m_option_definition;
+ }
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ OptionValueUInt64 &
+ GetOptionValue ()
+ {
+ return m_value;
+ }
+
+ const OptionValueUInt64 &
+ GetOptionValue () const
+ {
+ return m_value;
+ }
+
+ protected:
+ OptionValueUInt64 m_value;
+ OptionDefinition m_option_definition;
+
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupUInt64_h_
diff --git a/include/lldb/Interpreter/OptionGroupUUID.h b/include/lldb/Interpreter/OptionGroupUUID.h
new file mode 100644
index 000000000000..ea968d737969
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupUUID.h
@@ -0,0 +1,61 @@
+//===-- OptionGroupUUID.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupUUID_h_
+#define liblldb_OptionGroupUUID_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/OptionValueUUID.h"
+
+namespace lldb_private {
+//-------------------------------------------------------------------------
+// OptionGroupUUID
+//-------------------------------------------------------------------------
+
+class OptionGroupUUID : public OptionGroup
+{
+public:
+
+ OptionGroupUUID ();
+
+ virtual
+ ~OptionGroupUUID ();
+
+
+ virtual uint32_t
+ GetNumDefinitions ();
+
+ virtual const OptionDefinition*
+ GetDefinitions ();
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ const OptionValueUUID &
+ GetOptionValue () const
+ {
+ return m_uuid;
+ }
+
+protected:
+ OptionValueUUID m_uuid;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupUUID_h_
diff --git a/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h b/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
new file mode 100644
index 000000000000..da05e127d5d1
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
@@ -0,0 +1,85 @@
+//===-- OptionGroupValueObjectDisplay.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupValueObjectDisplay_h_
+#define liblldb_OptionGroupValueObjectDisplay_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Interpreter/Options.h"
+
+namespace lldb_private {
+
+//-------------------------------------------------------------------------
+// OptionGroupValueObjectDisplay
+//-------------------------------------------------------------------------
+
+class OptionGroupValueObjectDisplay : public OptionGroup
+{
+public:
+
+ OptionGroupValueObjectDisplay ();
+
+ virtual
+ ~OptionGroupValueObjectDisplay ();
+
+
+ virtual uint32_t
+ GetNumDefinitions ();
+
+ virtual const OptionDefinition*
+ GetDefinitions ();
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ bool
+ AnyOptionWasSet () const
+ {
+ return show_types == true ||
+ no_summary_depth != 0 ||
+ show_location == true ||
+ flat_output == true ||
+ use_objc == true ||
+ max_depth != UINT32_MAX ||
+ ptr_depth != 0 ||
+ use_synth == false ||
+ be_raw == true ||
+ ignore_cap == true;
+ }
+
+ ValueObject::DumpValueObjectOptions
+ GetAsDumpOptions (bool objc_is_compact = false,
+ lldb::Format format = lldb::eFormatDefault,
+ lldb::TypeSummaryImplSP summary_sp = lldb::TypeSummaryImplSP());
+
+ bool show_types;
+ uint32_t no_summary_depth;
+ bool show_location;
+ bool flat_output;
+ bool use_objc;
+ uint32_t max_depth;
+ uint32_t ptr_depth;
+ lldb::DynamicValueType use_dynamic;
+ bool use_synth;
+ bool be_raw;
+ bool ignore_cap;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupValueObjectDisplay_h_
diff --git a/include/lldb/Interpreter/OptionGroupVariable.h b/include/lldb/Interpreter/OptionGroupVariable.h
new file mode 100644
index 000000000000..40f4d436bc69
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupVariable.h
@@ -0,0 +1,65 @@
+//===-- OptionGroupVariable.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupVariable_h_
+#define liblldb_OptionGroupVariable_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/Options.h"
+
+namespace lldb_private {
+
+//-------------------------------------------------------------------------
+// OptionGroupVariable
+//-------------------------------------------------------------------------
+
+ class OptionGroupVariable : public OptionGroup
+ {
+ public:
+
+ OptionGroupVariable (bool show_frame_options);
+
+ virtual
+ ~OptionGroupVariable ();
+
+ virtual uint32_t
+ GetNumDefinitions ();
+
+ virtual const OptionDefinition*
+ GetDefinitions ();
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_arg);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ bool include_frame_options:1,
+ show_args:1, // Frame option only (include_frame_options == true)
+ show_locals:1, // Frame option only (include_frame_options == true)
+ show_globals:1, // Frame option only (include_frame_options == true)
+ use_regex:1,
+ show_scope:1,
+ show_decl:1;
+ OptionValueString summary; // the name of a named summary
+ OptionValueString summary_string; // a summary string
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OptionGroupVariable);
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupVariable_h_
diff --git a/include/lldb/Interpreter/OptionGroupWatchpoint.h b/include/lldb/Interpreter/OptionGroupWatchpoint.h
new file mode 100644
index 000000000000..1298da80750e
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupWatchpoint.h
@@ -0,0 +1,71 @@
+//===-- OptionGroupWatchpoint.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionGroupWatchpoint_h_
+#define liblldb_OptionGroupWatchpoint_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/Options.h"
+
+namespace lldb_private {
+
+//-------------------------------------------------------------------------
+// OptionGroupWatchpoint
+//-------------------------------------------------------------------------
+
+ class OptionGroupWatchpoint : public OptionGroup
+ {
+ public:
+
+ static bool
+ IsWatchSizeSupported(uint32_t watch_size);
+
+ OptionGroupWatchpoint ();
+
+ virtual
+ ~OptionGroupWatchpoint ();
+
+ virtual uint32_t
+ GetNumDefinitions ();
+
+ virtual const OptionDefinition*
+ GetDefinitions ();
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_arg);
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter);
+
+ // Note:
+ // eWatchRead == LLDB_WATCH_TYPE_READ; and
+ // eWatchWrite == LLDB_WATCH_TYPE_WRITE
+ typedef enum WatchType {
+ eWatchInvalid = 0,
+ eWatchRead,
+ eWatchWrite,
+ eWatchReadWrite
+ } WatchType;
+
+ WatchType watch_type;
+ uint32_t watch_size;
+ bool watch_type_specified;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OptionGroupWatchpoint);
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupWatchpoint_h_
diff --git a/include/lldb/Interpreter/OptionValue.h b/include/lldb/Interpreter/OptionValue.h
new file mode 100644
index 000000000000..33e7fc5f818b
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValue.h
@@ -0,0 +1,384 @@
+//===-- OptionValue.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValue_h_
+#define liblldb_OptionValue_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-defines.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Error.h"
+
+namespace lldb_private {
+
+ //---------------------------------------------------------------------
+ // OptionValue
+ //---------------------------------------------------------------------
+ class OptionValue
+ {
+ public:
+ typedef enum {
+ eTypeInvalid = 0,
+ eTypeArch,
+ eTypeArgs,
+ eTypeArray,
+ eTypeBoolean,
+ eTypeDictionary,
+ eTypeEnum,
+ eTypeFileSpec,
+ eTypeFileSpecList,
+ eTypeFormat,
+ eTypePathMap,
+ eTypeProperties,
+ eTypeRegex,
+ eTypeSInt64,
+ eTypeString,
+ eTypeUInt64,
+ eTypeUUID
+ } Type;
+
+ enum {
+ eDumpOptionName = (1u << 0),
+ eDumpOptionType = (1u << 1),
+ eDumpOptionValue = (1u << 2),
+ eDumpOptionDescription = (1u << 3),
+ eDumpOptionRaw = (1u << 4),
+ eDumpGroupValue = (eDumpOptionName | eDumpOptionType | eDumpOptionValue),
+ eDumpGroupHelp = (eDumpOptionName | eDumpOptionType | eDumpOptionDescription)
+ };
+
+
+ OptionValue () :
+ m_value_was_set (false)
+ {
+ }
+
+ OptionValue (const OptionValue &rhs) :
+ m_value_was_set (rhs.m_value_was_set)
+ {
+ }
+
+ virtual ~OptionValue ()
+ {
+ }
+ //-----------------------------------------------------------------
+ // Subclasses should override these functions
+ //-----------------------------------------------------------------
+ virtual Type
+ GetType () const = 0;
+
+ // If this value is always hidden, the avoid showing any info on this
+ // value, just show the info for the child values.
+ virtual bool
+ ValueIsTransparent () const
+ {
+ return GetType() == eTypeProperties;
+ }
+
+ virtual const char *
+ GetTypeAsCString () const
+ {
+ return GetBuiltinTypeAsCString(GetType());
+ }
+
+
+ static const char *
+ GetBuiltinTypeAsCString (Type t);
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) = 0;
+
+ virtual Error
+ SetValueFromCString (const char *value, VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear () = 0;
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const = 0;
+
+ virtual size_t
+ AutoComplete (CommandInterpreter &interpreter,
+ const char *s,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+ //-----------------------------------------------------------------
+ // Subclasses can override these functions
+ //-----------------------------------------------------------------
+ virtual lldb::OptionValueSP
+ GetSubValue (const ExecutionContext *exe_ctx,
+ const char *name,
+ bool will_modify,
+ Error &error) const
+ {
+ error.SetErrorStringWithFormat("'%s' is not a value subvalue", name);
+ return lldb::OptionValueSP();
+ }
+
+ virtual Error
+ SetSubValue (const ExecutionContext *exe_ctx,
+ VarSetOperationType op,
+ const char *name,
+ const char *value);
+
+ virtual bool
+ IsAggregateValue () const
+ {
+ return false;
+ }
+
+ virtual ConstString
+ GetName() const
+ {
+ return ConstString();
+ }
+
+ virtual bool
+ DumpQualifiedName (Stream &strm) const;
+ //-----------------------------------------------------------------
+ // Subclasses should NOT override these functions as they use the
+ // above functions to implement functionality
+ //-----------------------------------------------------------------
+ uint32_t
+ GetTypeAsMask ()
+ {
+ return 1u << GetType();
+ }
+
+ static uint32_t
+ ConvertTypeToMask (OptionValue::Type type)
+ {
+ return 1u << type;
+ }
+
+ static OptionValue::Type
+ ConvertTypeMaskToType (uint32_t type_mask)
+ {
+ // If only one bit is set, then return an appropriate enumeration
+ switch (type_mask)
+ {
+ case 1u << eTypeArch: return eTypeArch;
+ case 1u << eTypeArgs: return eTypeArgs;
+ case 1u << eTypeArray: return eTypeArray;
+ case 1u << eTypeBoolean: return eTypeBoolean;
+ case 1u << eTypeDictionary: return eTypeDictionary;
+ case 1u << eTypeEnum: return eTypeEnum;
+ case 1u << eTypeFileSpec: return eTypeFileSpec;
+ case 1u << eTypeFileSpecList: return eTypeFileSpecList;
+ case 1u << eTypeFormat: return eTypeFormat;
+ case 1u << eTypePathMap: return eTypePathMap;
+ case 1u << eTypeProperties: return eTypeProperties;
+ case 1u << eTypeRegex: return eTypeRegex;
+ case 1u << eTypeSInt64: return eTypeSInt64;
+ case 1u << eTypeString: return eTypeString;
+ case 1u << eTypeUInt64: return eTypeUInt64;
+ case 1u << eTypeUUID: return eTypeUUID;
+ }
+ // Else return invalid
+ return eTypeInvalid;
+ }
+
+ static lldb::OptionValueSP
+ CreateValueFromCStringForTypeMask (const char *value_cstr,
+ uint32_t type_mask,
+ Error &error);
+
+ // Get this value as a uint64_t value if it is encoded as a boolean,
+ // uint64_t or int64_t. Other types will cause "fail_value" to be
+ // returned
+ uint64_t
+ GetUInt64Value (uint64_t fail_value, bool *success_ptr);
+
+ OptionValueArch *
+ GetAsArch ();
+
+ const OptionValueArch *
+ GetAsArch () const;
+
+ OptionValueArray *
+ GetAsArray ();
+
+ const OptionValueArray *
+ GetAsArray () const;
+
+ OptionValueArgs *
+ GetAsArgs ();
+
+ const OptionValueArgs *
+ GetAsArgs () const;
+
+ OptionValueBoolean *
+ GetAsBoolean ();
+
+ const OptionValueBoolean *
+ GetAsBoolean () const;
+
+ OptionValueDictionary *
+ GetAsDictionary ();
+
+ const OptionValueDictionary *
+ GetAsDictionary () const;
+
+ OptionValueEnumeration *
+ GetAsEnumeration ();
+
+ const OptionValueEnumeration *
+ GetAsEnumeration () const;
+
+ OptionValueFileSpec *
+ GetAsFileSpec ();
+
+ const OptionValueFileSpec *
+ GetAsFileSpec () const;
+
+ OptionValueFileSpecList *
+ GetAsFileSpecList ();
+
+ const OptionValueFileSpecList *
+ GetAsFileSpecList () const;
+
+ OptionValueFormat *
+ GetAsFormat ();
+
+ const OptionValueFormat *
+ GetAsFormat () const;
+
+ OptionValuePathMappings *
+ GetAsPathMappings ();
+
+ const OptionValuePathMappings *
+ GetAsPathMappings () const;
+
+ OptionValueProperties *
+ GetAsProperties ();
+
+ const OptionValueProperties *
+ GetAsProperties () const;
+
+ OptionValueRegex *
+ GetAsRegex ();
+
+ const OptionValueRegex *
+ GetAsRegex () const;
+
+ OptionValueSInt64 *
+ GetAsSInt64 ();
+
+ const OptionValueSInt64 *
+ GetAsSInt64 () const;
+
+ OptionValueString *
+ GetAsString ();
+
+ const OptionValueString *
+ GetAsString () const;
+
+ OptionValueUInt64 *
+ GetAsUInt64 ();
+
+ const OptionValueUInt64 *
+ GetAsUInt64 () const;
+
+ OptionValueUUID *
+ GetAsUUID ();
+
+ const OptionValueUUID *
+ GetAsUUID () const;
+
+ bool
+ GetBooleanValue (bool fail_value = false) const;
+
+ bool
+ SetBooleanValue (bool new_value);
+
+ int64_t
+ GetEnumerationValue (int64_t fail_value = -1) const;
+
+ bool
+ SetEnumerationValue (int64_t value);
+
+ FileSpec
+ GetFileSpecValue () const;
+
+ bool
+ SetFileSpecValue (const FileSpec &file_spec);
+
+ FileSpecList
+ GetFileSpecListValue () const;
+
+ lldb::Format
+ GetFormatValue (lldb::Format fail_value = lldb::eFormatDefault) const;
+
+ bool
+ SetFormatValue (lldb::Format new_value);
+
+ const RegularExpression *
+ GetRegexValue () const;
+
+ int64_t
+ GetSInt64Value (int64_t fail_value = 0) const;
+
+ bool
+ SetSInt64Value (int64_t new_value);
+
+ const char *
+ GetStringValue (const char *fail_value = NULL) const;
+
+ bool
+ SetStringValue (const char *new_value);
+
+ uint64_t
+ GetUInt64Value (uint64_t fail_value = 0) const;
+
+ bool
+ SetUInt64Value (uint64_t new_value);
+
+ UUID
+ GetUUIDValue () const;
+
+ bool
+ SetUUIDValue (const UUID &uuid);
+
+ bool
+ OptionWasSet () const
+ {
+ return m_value_was_set;
+ }
+
+ void
+ SetOptionWasSet ()
+ {
+ m_value_was_set = true;
+ }
+
+ void
+ SetParent (const lldb::OptionValueSP &parent_sp)
+ {
+ m_parent_wp = parent_sp;
+ }
+ protected:
+ lldb::OptionValueWP m_parent_wp;
+ bool m_value_was_set; // This can be used to see if a value has been set
+ // by a call to SetValueFromCString(). It is often
+ // handy to know if an option value was set from
+ // the command line or as a setting, versus if we
+ // just have the default value that was already
+ // populated in the option value.
+
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValue_h_
diff --git a/include/lldb/Interpreter/OptionValueArch.h b/include/lldb/Interpreter/OptionValueArch.h
new file mode 100644
index 000000000000..662e1ec9f627
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueArch.h
@@ -0,0 +1,139 @@
+//===-- OptionValueArch.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueArch_h_
+#define liblldb_OptionValueArch_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueArch : public OptionValue
+{
+public:
+ OptionValueArch () :
+ OptionValue(),
+ m_current_value (),
+ m_default_value ()
+ {
+ }
+
+ OptionValueArch (const char *triple) :
+ OptionValue(),
+ m_current_value (triple),
+ m_default_value ()
+ {
+ m_default_value = m_current_value;
+ }
+
+ OptionValueArch (const ArchSpec &value) :
+ OptionValue(),
+ m_current_value (value),
+ m_default_value (value)
+ {
+ }
+
+ OptionValueArch (const ArchSpec &current_value,
+ const ArchSpec &default_value) :
+ OptionValue(),
+ m_current_value (current_value),
+ m_default_value (default_value)
+ {
+ }
+
+ virtual
+ ~OptionValueArch()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeArch;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_current_value = m_default_value;
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ virtual size_t
+ AutoComplete (CommandInterpreter &interpreter,
+ const char *s,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ ArchSpec &
+ GetCurrentValue()
+ {
+ return m_current_value;
+ }
+
+ const ArchSpec &
+ GetCurrentValue() const
+ {
+ return m_current_value;
+ }
+
+ const ArchSpec &
+ GetDefaultValue() const
+ {
+ return m_default_value;
+ }
+
+ void
+ SetCurrentValue (const ArchSpec &value, bool set_value_was_set)
+ {
+ m_current_value = value;
+ if (set_value_was_set)
+ m_value_was_set = true;
+ }
+
+ void
+ SetDefaultValue (const ArchSpec &value)
+ {
+ m_default_value = value;
+ }
+
+protected:
+ ArchSpec m_current_value;
+ ArchSpec m_default_value;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueArch_h_
diff --git a/include/lldb/Interpreter/OptionValueArgs.h b/include/lldb/Interpreter/OptionValueArgs.h
new file mode 100644
index 000000000000..365a52a8b39f
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueArgs.h
@@ -0,0 +1,46 @@
+//===-- OptionValueArgs.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueArgs_h_
+#define liblldb_OptionValueArgs_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/OptionValueArray.h"
+
+namespace lldb_private {
+
+class OptionValueArgs : public OptionValueArray
+{
+public:
+ OptionValueArgs () :
+ OptionValueArray (OptionValue::ConvertTypeToMask (OptionValue::eTypeString))
+ {
+ }
+
+ virtual
+ ~OptionValueArgs()
+ {
+ }
+
+ size_t
+ GetArgs (Args &args);
+
+ virtual Type
+ GetType() const
+ {
+ return eTypeArgs;
+ }
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueArgs_h_
diff --git a/include/lldb/Interpreter/OptionValueArray.h b/include/lldb/Interpreter/OptionValueArray.h
new file mode 100644
index 000000000000..39ae2f6f43d6
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueArray.h
@@ -0,0 +1,178 @@
+//===-- OptionValueArray.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueArray_h_
+#define liblldb_OptionValueArray_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueArray : public OptionValue
+{
+public:
+ OptionValueArray (uint32_t type_mask = UINT32_MAX, bool raw_value_dump = false) :
+ m_type_mask (type_mask),
+ m_values (),
+ m_raw_value_dump(raw_value_dump)
+ {
+ }
+
+ virtual
+ ~OptionValueArray()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeArray;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_values.clear();
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ virtual bool
+ IsAggregateValue () const
+ {
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ GetSubValue (const ExecutionContext *exe_ctx,
+ const char *name,
+ bool will_modify,
+ Error &error) const;
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ size_t
+ GetSize () const
+ {
+ return m_values.size();
+ }
+
+ lldb::OptionValueSP
+ operator[](size_t idx) const
+ {
+ lldb::OptionValueSP value_sp;
+ if (idx < m_values.size())
+ value_sp = m_values[idx];
+ return value_sp;
+ }
+
+ lldb::OptionValueSP
+ GetValueAtIndex (size_t idx) const
+ {
+ lldb::OptionValueSP value_sp;
+ if (idx < m_values.size())
+ value_sp = m_values[idx];
+ return value_sp;
+ }
+
+ bool
+ AppendValue (const lldb::OptionValueSP &value_sp)
+ {
+ // Make sure the value_sp object is allowed to contain
+ // values of the type passed in...
+ if (value_sp && (m_type_mask & value_sp->GetTypeAsMask()))
+ {
+ m_values.push_back(value_sp);
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ InsertValue (size_t idx, const lldb::OptionValueSP &value_sp)
+ {
+ // Make sure the value_sp object is allowed to contain
+ // values of the type passed in...
+ if (value_sp && (m_type_mask & value_sp->GetTypeAsMask()))
+ {
+ if (idx < m_values.size())
+ m_values.insert(m_values.begin() + idx, value_sp);
+ else
+ m_values.push_back(value_sp);
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ ReplaceValue (size_t idx, const lldb::OptionValueSP &value_sp)
+ {
+ // Make sure the value_sp object is allowed to contain
+ // values of the type passed in...
+ if (value_sp && (m_type_mask & value_sp->GetTypeAsMask()))
+ {
+ if (idx < m_values.size())
+ {
+ m_values[idx] = value_sp;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool
+ DeleteValue (size_t idx)
+ {
+ if (idx < m_values.size())
+ {
+ m_values.erase (m_values.begin() + idx);
+ return true;
+ }
+ return false;
+ }
+
+ size_t
+ GetArgs (Args &args) const;
+
+ Error
+ SetArgs (const Args &args, VarSetOperationType op);
+
+protected:
+ typedef std::vector<lldb::OptionValueSP> collection;
+
+ uint32_t m_type_mask;
+ collection m_values;
+ bool m_raw_value_dump;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueArray_h_
diff --git a/include/lldb/Interpreter/OptionValueBoolean.h b/include/lldb/Interpreter/OptionValueBoolean.h
new file mode 100644
index 000000000000..2b935e9e03e6
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueBoolean.h
@@ -0,0 +1,141 @@
+//===-- OptionValueBoolean.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueBoolean_h_
+#define liblldb_OptionValueBoolean_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueBoolean : public OptionValue
+{
+public:
+ OptionValueBoolean (bool value) :
+ OptionValue(),
+ m_current_value (value),
+ m_default_value (value)
+ {
+ }
+ OptionValueBoolean (bool current_value,
+ bool default_value) :
+ OptionValue(),
+ m_current_value (current_value),
+ m_default_value (default_value)
+ {
+ }
+
+ virtual
+ ~OptionValueBoolean()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeBoolean;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_current_value = m_default_value;
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual size_t
+ AutoComplete (CommandInterpreter &interpreter,
+ const char *s,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Convert to bool operator.
+ ///
+ /// This allows code to check a OptionValueBoolean in conditions.
+ ///
+ /// @code
+ /// OptionValueBoolean bool_value(...);
+ /// if (bool_value)
+ /// { ...
+ /// @endcode
+ ///
+ /// @return
+ /// /b True this object contains a valid namespace decl, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ operator bool() const
+ {
+ return m_current_value;
+ }
+
+ const bool &
+ operator = (bool b)
+ {
+ m_current_value = b;
+ return m_current_value;
+ }
+
+ bool
+ GetCurrentValue() const
+ {
+ return m_current_value;
+ }
+
+ bool
+ GetDefaultValue() const
+ {
+ return m_default_value;
+ }
+
+ void
+ SetCurrentValue (bool value)
+ {
+ m_current_value = value;
+ }
+
+ void
+ SetDefaultValue (bool value)
+ {
+ m_default_value = value;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+protected:
+ bool m_current_value;
+ bool m_default_value;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueBoolean_h_
diff --git a/include/lldb/Interpreter/OptionValueDictionary.h b/include/lldb/Interpreter/OptionValueDictionary.h
new file mode 100644
index 000000000000..5fb698b9f221
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueDictionary.h
@@ -0,0 +1,139 @@
+//===-- OptionValueDictionary.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueDictionary_h_
+#define liblldb_OptionValueDictionary_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueDictionary : public OptionValue
+{
+public:
+ OptionValueDictionary (uint32_t type_mask = UINT32_MAX, bool raw_value_dump = true) :
+ OptionValue(),
+ m_type_mask (type_mask),
+ m_values (),
+ m_raw_value_dump (raw_value_dump)
+ {
+ }
+
+ virtual
+ ~OptionValueDictionary()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeDictionary;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_values.clear();
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ virtual bool
+ IsAggregateValue () const
+ {
+ return true;
+ }
+
+ bool
+ IsHomogenous() const
+ {
+ return ConvertTypeMaskToType (m_type_mask) != eTypeInvalid;
+ }
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ size_t
+ GetNumValues() const
+ {
+ return m_values.size();
+ }
+
+ lldb::OptionValueSP
+ GetValueForKey (const ConstString &key) const;
+
+ virtual lldb::OptionValueSP
+ GetSubValue (const ExecutionContext *exe_ctx,
+ const char *name,
+ bool will_modify,
+ Error &error) const;
+
+ virtual Error
+ SetSubValue (const ExecutionContext *exe_ctx,
+ VarSetOperationType op,
+ const char *name,
+ const char *value);
+
+ //---------------------------------------------------------------------
+ // String value getters and setters
+ //---------------------------------------------------------------------
+ const char *
+ GetStringValueForKey (const ConstString &key);
+
+ bool
+ SetStringValueForKey (const ConstString &key,
+ const char *value,
+ bool can_replace = true);
+
+
+ bool
+ SetValueForKey (const ConstString &key,
+ const lldb::OptionValueSP &value_sp,
+ bool can_replace = true);
+
+ bool
+ DeleteValueForKey (const ConstString &key);
+
+ size_t
+ GetArgs (Args &args) const;
+
+ Error
+ SetArgs (const Args &args, VarSetOperationType op);
+
+protected:
+ typedef std::map<ConstString, lldb::OptionValueSP> collection;
+ uint32_t m_type_mask;
+ collection m_values;
+ bool m_raw_value_dump;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueDictionary_h_
diff --git a/include/lldb/Interpreter/OptionValueEnumeration.h b/include/lldb/Interpreter/OptionValueEnumeration.h
new file mode 100644
index 000000000000..012eeb68ac0e
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueEnumeration.h
@@ -0,0 +1,126 @@
+//===-- OptionValueEnumeration.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueEnumeration_h_
+#define liblldb_OptionValueEnumeration_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+
+class OptionValueEnumeration : public OptionValue
+{
+public:
+ typedef int64_t enum_type;
+ struct EnumeratorInfo
+ {
+ enum_type value;
+ const char *description;
+ };
+ typedef UniqueCStringMap<EnumeratorInfo> EnumerationMap;
+ typedef typename EnumerationMap::Entry EnumerationMapEntry;
+
+ OptionValueEnumeration (const OptionEnumValueElement *enumerators, enum_type value);
+
+ virtual
+ ~OptionValueEnumeration();
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeEnum;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_current_value = m_default_value;
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ virtual size_t
+ AutoComplete (CommandInterpreter &interpreter,
+ const char *s,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ enum_type
+ operator = (enum_type value)
+ {
+ m_current_value = value;
+ return m_current_value;
+ }
+
+ enum_type
+ GetCurrentValue() const
+ {
+ return m_current_value;
+ }
+
+ enum_type
+ GetDefaultValue() const
+ {
+ return m_default_value;
+ }
+
+ void
+ SetCurrentValue (enum_type value)
+ {
+ m_current_value = value;
+ }
+
+ void
+ SetDefaultValue (enum_type value)
+ {
+ m_default_value = value;
+ }
+
+protected:
+ void
+ SetEnumerations (const OptionEnumValueElement *enumerators);
+
+ enum_type m_current_value;
+ enum_type m_default_value;
+ EnumerationMap m_enumerations;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueEnumeration_h_
diff --git a/include/lldb/Interpreter/OptionValueFileSpec.h b/include/lldb/Interpreter/OptionValueFileSpec.h
new file mode 100644
index 000000000000..7e74b605660c
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueFileSpec.h
@@ -0,0 +1,129 @@
+//===-- OptionValueFileSpec.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueFileSpec_h_
+#define liblldb_OptionValueFileSpec_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueFileSpec : public OptionValue
+{
+public:
+ OptionValueFileSpec ();
+
+ OptionValueFileSpec (const FileSpec &value);
+
+ OptionValueFileSpec (const FileSpec &current_value,
+ const FileSpec &default_value);
+
+ virtual
+ ~OptionValueFileSpec()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeFileSpec;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_current_value = m_default_value;
+ m_value_was_set = false;
+ m_data_sp.reset();
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ virtual size_t
+ AutoComplete (CommandInterpreter &interpreter,
+ const char *s,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ FileSpec &
+ GetCurrentValue()
+ {
+ return m_current_value;
+ }
+
+ const FileSpec &
+ GetCurrentValue() const
+ {
+ return m_current_value;
+ }
+
+ const FileSpec &
+ GetDefaultValue() const
+ {
+ return m_default_value;
+ }
+
+ void
+ SetCurrentValue (const FileSpec &value, bool set_value_was_set)
+ {
+ m_current_value = value;
+ if (set_value_was_set)
+ m_value_was_set = true;
+ m_data_sp.reset();
+ }
+
+ void
+ SetDefaultValue (const FileSpec &value)
+ {
+ m_default_value = value;
+ }
+
+ const lldb::DataBufferSP &
+ GetFileContents(bool null_terminate);
+
+ void
+ SetCompletionMask (uint32_t mask)
+ {
+ m_completion_mask = mask;
+ }
+
+protected:
+ FileSpec m_current_value;
+ FileSpec m_default_value;
+ lldb::DataBufferSP m_data_sp;
+ uint32_t m_completion_mask;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueFileSpec_h_
diff --git a/include/lldb/Interpreter/OptionValueFileSpecList.h b/include/lldb/Interpreter/OptionValueFileSpecList.h
new file mode 100644
index 000000000000..792de4e23af6
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueFileSpecList.h
@@ -0,0 +1,105 @@
+//===-- OptionValueFileSpecList.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueFileSpecList_h_
+#define liblldb_OptionValueFileSpecList_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueFileSpecList : public OptionValue
+{
+public:
+ OptionValueFileSpecList () :
+ OptionValue(),
+ m_current_value ()
+ {
+ }
+
+ OptionValueFileSpecList (const FileSpecList &current_value) :
+ OptionValue(),
+ m_current_value (current_value)
+ {
+ }
+
+
+ virtual
+ ~OptionValueFileSpecList()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeFileSpecList;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_current_value.Clear();
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ virtual bool
+ IsAggregateValue () const
+ {
+ return true;
+ }
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ FileSpecList &
+ GetCurrentValue()
+ {
+ return m_current_value;
+ }
+
+ const FileSpecList &
+ GetCurrentValue() const
+ {
+ return m_current_value;
+ }
+
+ void
+ SetCurrentValue (const FileSpecList &value)
+ {
+ m_current_value = value;
+ }
+
+protected:
+ FileSpecList m_current_value;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueFileSpecList_h_
diff --git a/include/lldb/Interpreter/OptionValueFormat.h b/include/lldb/Interpreter/OptionValueFormat.h
new file mode 100644
index 000000000000..245b2eeb5af1
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueFormat.h
@@ -0,0 +1,107 @@
+//===-- OptionValueFormat.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueFormat_h_
+#define liblldb_OptionValueFormat_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueFormat : public OptionValue
+{
+public:
+ OptionValueFormat (lldb::Format value) :
+ OptionValue(),
+ m_current_value (value),
+ m_default_value (value)
+ {
+ }
+
+ OptionValueFormat (lldb::Format current_value,
+ lldb::Format default_value) :
+ OptionValue(),
+ m_current_value (current_value),
+ m_default_value (default_value)
+ {
+ }
+
+ virtual
+ ~OptionValueFormat()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeFormat;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_current_value = m_default_value;
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ lldb::Format
+ GetCurrentValue() const
+ {
+ return m_current_value;
+ }
+
+ lldb::Format
+ GetDefaultValue() const
+ {
+ return m_default_value;
+ }
+
+ void
+ SetCurrentValue (lldb::Format value)
+ {
+ m_current_value = value;
+ }
+
+ void
+ SetDefaultValue (lldb::Format value)
+ {
+ m_default_value = value;
+ }
+
+protected:
+ lldb::Format m_current_value;
+ lldb::Format m_default_value;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueFormat_h_
diff --git a/include/lldb/Interpreter/OptionValuePathMappings.h b/include/lldb/Interpreter/OptionValuePathMappings.h
new file mode 100644
index 000000000000..7ebf4947c6af
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValuePathMappings.h
@@ -0,0 +1,94 @@
+//===-- OptionValuePathMappings.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValuePathMappings_h_
+#define liblldb_OptionValuePathMappings_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/PathMappingList.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValuePathMappings : public OptionValue
+{
+public:
+ OptionValuePathMappings (bool notify_changes) :
+ OptionValue(),
+ m_path_mappings (),
+ m_notify_changes (notify_changes)
+ {
+ }
+
+ virtual
+ ~OptionValuePathMappings()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypePathMap;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_path_mappings.Clear(m_notify_changes);
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ virtual bool
+ IsAggregateValue () const
+ {
+ return true;
+ }
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ PathMappingList &
+ GetCurrentValue()
+ {
+ return m_path_mappings;
+ }
+
+ const PathMappingList &
+ GetCurrentValue() const
+ {
+ return m_path_mappings;
+ }
+
+protected:
+ PathMappingList m_path_mappings;
+ bool m_notify_changes;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValuePathMappings_h_
diff --git a/include/lldb/Interpreter/OptionValueProperties.h b/include/lldb/Interpreter/OptionValueProperties.h
new file mode 100644
index 000000000000..0024f20e2ff6
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueProperties.h
@@ -0,0 +1,265 @@
+//===-- OptionValueProperties.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueProperties_h_
+#define liblldb_OptionValueProperties_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Interpreter/OptionValue.h"
+#include "lldb/Interpreter/Property.h"
+
+namespace lldb_private {
+
+class OptionValueProperties :
+ public OptionValue,
+ public std::enable_shared_from_this<OptionValueProperties>
+{
+public:
+
+ //---------------------------------------------------------------------
+ // OptionValueProperties
+ //---------------------------------------------------------------------
+ OptionValueProperties () :
+ OptionValue(),
+ m_name (),
+ m_properties (),
+ m_name_to_index ()
+ {
+ }
+
+ OptionValueProperties (const ConstString &name);
+
+ OptionValueProperties (const OptionValueProperties &global_properties);
+
+ virtual
+ ~OptionValueProperties()
+ {
+ }
+
+ virtual Type
+ GetType () const
+ {
+ return eTypeProperties;
+ }
+
+ virtual bool
+ Clear ();
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ virtual Error
+ SetValueFromCString (const char *value, VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx,
+ Stream &strm,
+ uint32_t dump_mask);
+
+ virtual ConstString
+ GetName () const
+ {
+ return m_name;
+ }
+
+ virtual Error
+ DumpPropertyValue (const ExecutionContext *exe_ctx,
+ Stream &strm,
+ const char *property_path,
+ uint32_t dump_mask);
+
+ virtual void
+ DumpAllDescriptions (CommandInterpreter &interpreter,
+ Stream &strm) const;
+
+ void
+ Apropos (const char *keyword,
+ std::vector<const Property *> &matching_properties) const;
+
+ void
+ Initialize (const PropertyDefinition *setting_definitions);
+
+// bool
+// GetQualifiedName (Stream &strm);
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ virtual size_t
+ GetNumProperties() const;
+
+ virtual ConstString
+ GetPropertyNameAtIndex (uint32_t idx) const;
+
+ virtual const char *
+ GetPropertyDescriptionAtIndex (uint32_t idx) const;
+
+ //---------------------------------------------------------------------
+ // Get the index of a property given its exact name in this property
+ // collection, "name" can't be a path to a property path that refers
+ // to a property within a property
+ //---------------------------------------------------------------------
+ virtual uint32_t
+ GetPropertyIndex (const ConstString &name) const;
+
+ //---------------------------------------------------------------------
+ // Get a property by exact name exists in this property collection, name
+ // can not be a path to a property path that refers to a property within
+ // a property
+ //---------------------------------------------------------------------
+ virtual const Property *
+ GetProperty (const ExecutionContext *exe_ctx,
+ bool will_modify,
+ const ConstString &name) const;
+
+ virtual const Property *
+ GetPropertyAtIndex (const ExecutionContext *exe_ctx,
+ bool will_modify,
+ uint32_t idx) const;
+
+ //---------------------------------------------------------------------
+ // Property can be be a property path like "target.process.extra-startup-command"
+ //---------------------------------------------------------------------
+ virtual const Property *
+ GetPropertyAtPath (const ExecutionContext *exe_ctx,
+ bool will_modify,
+ const char *property_path) const;
+
+ virtual lldb::OptionValueSP
+ GetPropertyValueAtIndex (const ExecutionContext *exe_ctx,
+ bool will_modify,
+ uint32_t idx) const;
+
+ virtual lldb::OptionValueSP
+ GetValueForKey (const ExecutionContext *exe_ctx,
+ const ConstString &key,
+ bool value_will_be_modified) const;
+
+ lldb::OptionValueSP
+ GetSubValue (const ExecutionContext *exe_ctx,
+ const char *name,
+ bool value_will_be_modified,
+ Error &error) const;
+
+ virtual Error
+ SetSubValue (const ExecutionContext *exe_ctx,
+ VarSetOperationType op,
+ const char *path,
+ const char *value);
+
+ virtual bool
+ PredicateMatches (const ExecutionContext *exe_ctx,
+ const char *predicate) const
+ {
+ return false;
+ }
+
+
+ OptionValueArch *
+ GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const;
+
+ bool
+ GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const;
+
+ bool
+ SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args);
+
+ bool
+ GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const;
+
+ bool
+ SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value);
+
+ OptionValueDictionary *
+ GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const;
+
+ int64_t
+ GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const;
+
+ bool
+ SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value);
+
+ const RegularExpression *
+ GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const;
+
+ OptionValueSInt64 *
+ GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const;
+
+ int64_t
+ GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const;
+
+ bool
+ SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value);
+
+ uint64_t
+ GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const;
+
+ bool
+ SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value);
+
+ const char *
+ GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const;
+
+ bool
+ SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value);
+
+ OptionValueString *
+ GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const;
+
+ OptionValueFileSpec *
+ GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const;
+
+ FileSpec
+ GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const;
+
+ bool
+ SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &file_spec);
+
+ OptionValuePathMappings *
+ GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const;
+
+ OptionValueFileSpecList *
+ GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const;
+
+ void
+ AppendProperty(const ConstString &name,
+ const ConstString &desc,
+ bool is_global,
+ const lldb::OptionValueSP &value_sp);
+
+ lldb::OptionValuePropertiesSP
+ GetSubProperty (const ExecutionContext *exe_ctx,
+ const ConstString &name);
+
+protected:
+
+ const Property *
+ ProtectedGetPropertyAtIndex (uint32_t idx) const
+ {
+ if (idx < m_properties.size())
+ return &m_properties[idx];
+ return NULL;
+ }
+
+ typedef UniqueCStringMap<size_t> NameToIndex;
+
+ ConstString m_name;
+ std::vector<Property> m_properties;
+ NameToIndex m_name_to_index;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueProperties_h_
diff --git a/include/lldb/Interpreter/OptionValueRegex.h b/include/lldb/Interpreter/OptionValueRegex.h
new file mode 100644
index 000000000000..bb8c4588e22a
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueRegex.h
@@ -0,0 +1,98 @@
+//===-- OptionValueRegex.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueRegex_h_
+#define liblldb_OptionValueRegex_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueRegex : public OptionValue
+{
+public:
+ OptionValueRegex (const char *value = NULL, uint32_t regex_flags = 0) :
+ OptionValue(),
+ m_regex (value, regex_flags)
+ {
+ }
+
+ virtual
+ ~OptionValueRegex()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeRegex;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_regex.Clear();
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+ const RegularExpression *
+ GetCurrentValue() const
+ {
+ if (m_regex.IsValid())
+ return &m_regex;
+ return NULL;
+ }
+
+ void
+ SetCurrentValue (const char *value, uint32_t regex_flags)
+ {
+ if (value && value[0])
+ m_regex.Compile (value, regex_flags);
+ else
+ m_regex.Clear();
+ }
+
+ bool
+ IsValid () const
+ {
+ return m_regex.IsValid();
+ }
+
+protected:
+ RegularExpression m_regex;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueRegex_h_
diff --git a/include/lldb/Interpreter/OptionValueSInt64.h b/include/lldb/Interpreter/OptionValueSInt64.h
new file mode 100644
index 000000000000..8bc8fb2da2d5
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueSInt64.h
@@ -0,0 +1,172 @@
+//===-- OptionValueSInt64.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueSInt64_h_
+#define liblldb_OptionValueSInt64_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueSInt64 : public OptionValue
+{
+public:
+ OptionValueSInt64 () :
+ OptionValue(),
+ m_current_value (0),
+ m_default_value (0),
+ m_min_value (INT64_MIN),
+ m_max_value (INT64_MAX)
+ {
+ }
+
+ OptionValueSInt64 (int64_t value) :
+ OptionValue(),
+ m_current_value (value),
+ m_default_value (value),
+ m_min_value (INT64_MIN),
+ m_max_value (INT64_MAX)
+ {
+ }
+
+ OptionValueSInt64 (int64_t current_value,
+ int64_t default_value) :
+ OptionValue(),
+ m_current_value (current_value),
+ m_default_value (default_value),
+ m_min_value (INT64_MIN),
+ m_max_value (INT64_MAX)
+ {
+ }
+
+ OptionValueSInt64 (const OptionValueSInt64 &rhs) :
+ OptionValue(rhs),
+ m_current_value (rhs.m_current_value),
+ m_default_value (rhs.m_default_value),
+ m_min_value (rhs.m_min_value),
+ m_max_value (rhs.m_max_value)
+ {
+ }
+
+ virtual
+ ~OptionValueSInt64()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeSInt64;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_current_value = m_default_value;
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ const int64_t &
+ operator = (int64_t value)
+ {
+ m_current_value = value;
+ return m_current_value;
+ }
+
+ int64_t
+ GetCurrentValue() const
+ {
+ return m_current_value;
+ }
+
+ int64_t
+ GetDefaultValue() const
+ {
+ return m_default_value;
+ }
+
+ bool
+ SetCurrentValue (int64_t value)
+ {
+ if (value >= m_min_value && value <= m_max_value)
+ {
+ m_current_value = value;
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ SetDefaultValue (int64_t value)
+ {
+ if (value >= m_min_value && value <= m_max_value)
+ {
+ m_default_value = value;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ SetMinimumValue (int64_t v)
+ {
+ m_min_value = v;
+ }
+
+ int64_t
+ GetMinimumValue () const
+ {
+ return m_min_value;
+ }
+
+ void
+ SetMaximumValue (int64_t v)
+ {
+ m_max_value = v;
+ }
+
+ int64_t
+ GetMaximumValue () const
+ {
+ return m_max_value;
+ }
+
+protected:
+ int64_t m_current_value;
+ int64_t m_default_value;
+ int64_t m_min_value;
+ int64_t m_max_value;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueSInt64_h_
diff --git a/include/lldb/Interpreter/OptionValueString.h b/include/lldb/Interpreter/OptionValueString.h
new file mode 100644
index 000000000000..a82e1403b74b
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueString.h
@@ -0,0 +1,227 @@
+//===-- OptionValueString.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueString_h_
+#define liblldb_OptionValueString_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Flags.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueString : public OptionValue
+{
+public:
+
+ typedef Error (*ValidatorCallback) (const char* string,
+ void* baton);
+
+ enum Options
+ {
+ eOptionEncodeCharacterEscapeSequences = (1u << 0)
+ };
+
+ OptionValueString () :
+ OptionValue(),
+ m_current_value (),
+ m_default_value (),
+ m_options(),
+ m_validator(),
+ m_validator_baton()
+ {
+ }
+
+ OptionValueString (ValidatorCallback validator,
+ void* baton = NULL) :
+ OptionValue(),
+ m_current_value (),
+ m_default_value (),
+ m_options(),
+ m_validator(validator),
+ m_validator_baton(baton)
+ {
+ }
+
+ OptionValueString (const char *value) :
+ OptionValue(),
+ m_current_value (),
+ m_default_value (),
+ m_options(),
+ m_validator(),
+ m_validator_baton()
+ {
+ if (value && value[0])
+ {
+ m_current_value.assign (value);
+ m_default_value.assign (value);
+ }
+ }
+
+ OptionValueString (const char *current_value,
+ const char *default_value) :
+ OptionValue(),
+ m_current_value (),
+ m_default_value (),
+ m_options(),
+ m_validator(),
+ m_validator_baton()
+ {
+ if (current_value && current_value[0])
+ m_current_value.assign (current_value);
+ if (default_value && default_value[0])
+ m_default_value.assign (default_value);
+ }
+
+ OptionValueString (const char *value,
+ ValidatorCallback validator,
+ void* baton = NULL) :
+ OptionValue(),
+ m_current_value (),
+ m_default_value (),
+ m_options(),
+ m_validator(validator),
+ m_validator_baton(baton)
+ {
+ if (value && value[0])
+ {
+ m_current_value.assign (value);
+ m_default_value.assign (value);
+ }
+ }
+
+ OptionValueString (const char *current_value,
+ const char *default_value,
+ ValidatorCallback validator,
+ void* baton = NULL) :
+ OptionValue(),
+ m_current_value (),
+ m_default_value (),
+ m_options(),
+ m_validator(validator),
+ m_validator_baton(baton)
+ {
+ if (current_value && current_value[0])
+ m_current_value.assign (current_value);
+ if (default_value && default_value[0])
+ m_default_value.assign (default_value);
+ }
+
+ virtual
+ ~OptionValueString()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeString;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_current_value = m_default_value;
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ Flags &
+ GetOptions ()
+ {
+ return m_options;
+ }
+
+ const Flags &
+ GetOptions () const
+ {
+ return m_options;
+ }
+
+ const char *
+ operator = (const char *value)
+ {
+ SetCurrentValue(value);
+ return m_current_value.c_str();
+ }
+
+ const char *
+ GetCurrentValue() const
+ {
+ return m_current_value.c_str();
+ }
+
+ const char *
+ GetDefaultValue() const
+ {
+ return m_default_value.c_str();
+ }
+
+ Error
+ SetCurrentValue (const char *value);
+
+ Error
+ AppendToCurrentValue (const char *value);
+
+ void
+ SetDefaultValue (const char *value)
+ {
+ if (value && value[0])
+ m_default_value.assign (value);
+ else
+ m_default_value.clear();
+ }
+
+ bool
+ IsCurrentValueEmpty () const
+ {
+ return m_current_value.empty();
+ }
+
+ bool
+ IsDefaultValueEmpty () const
+ {
+ return m_default_value.empty();
+ }
+
+
+protected:
+ std::string m_current_value;
+ std::string m_default_value;
+ Flags m_options;
+ ValidatorCallback m_validator;
+ void* m_validator_baton;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueString_h_
diff --git a/include/lldb/Interpreter/OptionValueUInt64.h b/include/lldb/Interpreter/OptionValueUInt64.h
new file mode 100644
index 000000000000..9b5496f9835c
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueUInt64.h
@@ -0,0 +1,134 @@
+//===-- OptionValueUInt64.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueUInt64_h_
+#define liblldb_OptionValueUInt64_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueUInt64 : public OptionValue
+{
+public:
+ OptionValueUInt64 () :
+ OptionValue(),
+ m_current_value (0),
+ m_default_value (0)
+ {
+ }
+
+ OptionValueUInt64 (uint64_t value) :
+ OptionValue(),
+ m_current_value (value),
+ m_default_value (value)
+ {
+ }
+
+ OptionValueUInt64 (uint64_t current_value,
+ uint64_t default_value) :
+ OptionValue(),
+ m_current_value (current_value),
+ m_default_value (default_value)
+ {
+ }
+
+ virtual
+ ~OptionValueUInt64()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Decode a uint64_t from "value_cstr" return a OptionValueUInt64 object
+ // inside of a lldb::OptionValueSP object if all goes well. If the
+ // string isn't a uint64_t value or any other error occurs, return an
+ // empty lldb::OptionValueSP and fill error in with the correct stuff.
+ //---------------------------------------------------------------------
+ static lldb::OptionValueSP
+ Create (const char *value_cstr, Error &error);
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeUInt64;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_current_value = m_default_value;
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ const uint64_t &
+ operator = (uint64_t value)
+ {
+ m_current_value = value;
+ return m_current_value;
+ }
+
+ operator uint64_t () const
+ {
+ return m_current_value;
+ }
+
+ uint64_t
+ GetCurrentValue() const
+ {
+ return m_current_value;
+ }
+
+ uint64_t
+ GetDefaultValue() const
+ {
+ return m_default_value;
+ }
+
+ void
+ SetCurrentValue (uint64_t value)
+ {
+ m_current_value = value;
+ }
+
+ void
+ SetDefaultValue (uint64_t value)
+ {
+ m_default_value = value;
+ }
+
+protected:
+ uint64_t m_current_value;
+ uint64_t m_default_value;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueUInt64_h_
diff --git a/include/lldb/Interpreter/OptionValueUUID.h b/include/lldb/Interpreter/OptionValueUUID.h
new file mode 100644
index 000000000000..caf436e576f5
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueUUID.h
@@ -0,0 +1,106 @@
+//===-- OptionValueUUID.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueUUID_h_
+#define liblldb_OptionValueUUID_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/UUID.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueUUID : public OptionValue
+{
+public:
+ OptionValueUUID () :
+ OptionValue(),
+ m_uuid ()
+ {
+ }
+
+ OptionValueUUID (const UUID &uuid) :
+ OptionValue(),
+ m_uuid (uuid)
+ {
+ }
+
+ virtual
+ ~OptionValueUUID()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ virtual OptionValue::Type
+ GetType () const
+ {
+ return eTypeUUID;
+ }
+
+ virtual void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask);
+
+ virtual Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign);
+
+ virtual bool
+ Clear ()
+ {
+ m_uuid.Clear();
+ m_value_was_set = false;
+ return true;
+ }
+
+ virtual lldb::OptionValueSP
+ DeepCopy () const;
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ UUID &
+ GetCurrentValue()
+ {
+ return m_uuid;
+ }
+
+ const UUID &
+ GetCurrentValue() const
+ {
+ return m_uuid;
+ }
+
+ void
+ SetCurrentValue (const UUID &value)
+ {
+ m_uuid = value;
+ }
+
+ virtual size_t
+ AutoComplete (CommandInterpreter &interpreter,
+ const char *s,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+protected:
+ UUID m_uuid;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueUUID_h_
diff --git a/include/lldb/Interpreter/OptionValues.h b/include/lldb/Interpreter/OptionValues.h
new file mode 100644
index 000000000000..41b9d2e351f4
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValues.h
@@ -0,0 +1,31 @@
+//===-- OptionValues.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValues_h_
+#define liblldb_OptionValues_h_
+
+#include "lldb/Interpreter/OptionValue.h"
+#include "lldb/Interpreter/OptionValueArch.h"
+#include "lldb/Interpreter/OptionValueArgs.h"
+#include "lldb/Interpreter/OptionValueArray.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueDictionary.h"
+#include "lldb/Interpreter/OptionValueEnumeration.h"
+#include "lldb/Interpreter/OptionValueFileSpec.h"
+#include "lldb/Interpreter/OptionValueFileSpecList.h"
+#include "lldb/Interpreter/OptionValueFormat.h"
+#include "lldb/Interpreter/OptionValuePathMappings.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/OptionValueRegex.h"
+#include "lldb/Interpreter/OptionValueSInt64.h"
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/OptionValueUInt64.h"
+#include "lldb/Interpreter/OptionValueUUID.h"
+
+#endif // liblldb_OptionValues_h_
diff --git a/include/lldb/Interpreter/Options.h b/include/lldb/Interpreter/Options.h
new file mode 100644
index 000000000000..ac4daa8f579a
--- /dev/null
+++ b/include/lldb/Interpreter/Options.h
@@ -0,0 +1,487 @@
+//===-- Options.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Options_h_
+#define liblldb_Options_h_
+
+// C Includes
+#include <getopt.h>
+
+// C++ Includes
+#include <set>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/Interpreter/Args.h"
+
+namespace lldb_private {
+
+ static inline bool
+ isprint8 (int ch)
+ {
+ if (ch & 0xffffff00u)
+ return false;
+ return isprint(ch);
+ }
+
+
+//----------------------------------------------------------------------
+/// @class Options Options.h "lldb/Interpreter/Options.h"
+/// @brief A command line option parsing protocol class.
+///
+/// Options is designed to be subclassed to contain all needed
+/// options for a given command. The options can be parsed by calling:
+/// \code
+/// Error Args::ParseOptions (Options &);
+/// \endcode
+///
+/// The options are specified using the format defined for the libc
+/// options parsing function getopt_long_only:
+/// \code
+/// #include <getopt.h>
+/// int getopt_long_only(int argc, char * const *argv, const char *optstring, const struct option *longopts, int *longindex);
+/// \endcode
+///
+/// Example code:
+/// \code
+/// #include <getopt.h>
+/// #include <string>
+///
+/// class CommandOptions : public Options
+/// {
+/// public:
+/// virtual struct option *
+/// GetLongOptions() {
+/// return g_options;
+/// }
+///
+/// virtual Error
+/// SetOptionValue (uint32_t option_idx, int option_val, const char *option_arg)
+/// {
+/// Error error;
+/// switch (option_val)
+/// {
+/// case 'g': debug = true; break;
+/// case 'v': verbose = true; break;
+/// case 'l': log_file = option_arg; break;
+/// case 'f': log_flags = strtoull(option_arg, NULL, 0); break;
+/// default:
+/// error.SetErrorStringWithFormat("unrecognized short option %c", option_val);
+/// break;
+/// }
+///
+/// return error;
+/// }
+///
+/// CommandOptions (CommandInterpreter &interpreter) : debug (true), verbose (false), log_file (), log_flags (0)
+/// {}
+///
+/// bool debug;
+/// bool verbose;
+/// std::string log_file;
+/// uint32_t log_flags;
+///
+/// static struct option g_options[];
+///
+/// };
+///
+/// struct option CommandOptions::g_options[] =
+/// {
+/// { "debug", no_argument, NULL, 'g' },
+/// { "log-file", required_argument, NULL, 'l' },
+/// { "log-flags", required_argument, NULL, 'f' },
+/// { "verbose", no_argument, NULL, 'v' },
+/// { NULL, 0, NULL, 0 }
+/// };
+///
+/// int main (int argc, const char **argv, const char **envp)
+/// {
+/// CommandOptions options;
+/// Args main_command;
+/// main_command.SetArguments(argc, argv, false);
+/// main_command.ParseOptions(options);
+///
+/// if (options.verbose)
+/// {
+/// std::cout << "verbose is on" << std::endl;
+/// }
+/// }
+/// \endcode
+//----------------------------------------------------------------------
+class Options
+{
+public:
+
+ Options (CommandInterpreter &interpreter);
+
+ virtual
+ ~Options ();
+
+ void
+ BuildGetoptTable ();
+
+ void
+ BuildValidOptionSets ();
+
+ uint32_t
+ NumCommandOptions ();
+
+ //------------------------------------------------------------------
+ /// Get the option definitions to use when parsing Args options.
+ ///
+ /// @see Args::ParseOptions (Options&)
+ /// @see man getopt_long_only
+ //------------------------------------------------------------------
+ struct option *
+ GetLongOptions ();
+
+ // This gets passed the short option as an integer...
+ void
+ OptionSeen (int short_option);
+
+ bool
+ VerifyOptions (CommandReturnObject &result);
+
+ // Verify that the options given are in the options table and can
+ // be used together, but there may be some required options that are
+ // missing (used to verify options that get folded into command aliases).
+
+ bool
+ VerifyPartialOptions (CommandReturnObject &result);
+
+ void
+ OutputFormattedUsageText (Stream &strm,
+ const char *text,
+ uint32_t output_max_columns);
+
+ void
+ GenerateOptionUsage (Stream &strm,
+ CommandObject *cmd);
+
+ bool
+ SupportsLongOption (const char *long_option);
+
+ // The following two pure virtual functions must be defined by every
+ // class that inherits from this class.
+
+ virtual const OptionDefinition*
+ GetDefinitions () { return NULL; }
+
+ // Call this prior to parsing any options. This call will call the
+ // subclass OptionParsingStarting() and will avoid the need for all
+ // OptionParsingStarting() function instances from having to call the
+ // Option::OptionParsingStarting() like they did before. This was error
+ // prone and subclasses shouldn't have to do it.
+ void
+ NotifyOptionParsingStarting ();
+
+ Error
+ NotifyOptionParsingFinished ();
+
+ //------------------------------------------------------------------
+ /// Set the value of an option.
+ ///
+ /// @param[in] option_idx
+ /// The index into the "struct option" array that was returned
+ /// by Options::GetLongOptions().
+ ///
+ /// @param[in] option_arg
+ /// The argument value for the option that the user entered, or
+ /// NULL if there is no argument for the current option.
+ ///
+ ///
+ /// @see Args::ParseOptions (Options&)
+ /// @see man getopt_long_only
+ //------------------------------------------------------------------
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg) = 0;
+
+ //------------------------------------------------------------------
+ /// Handles the generic bits of figuring out whether we are in an
+ /// option, and if so completing it.
+ ///
+ /// @param[in] input
+ /// The command line parsed into words
+ ///
+ /// @param[in] cursor_index
+ /// The index in \ainput of the word in which the cursor lies.
+ ///
+ /// @param[in] char_pos
+ /// The character position of the cursor in its argument word.
+ ///
+ /// @param[in] match_start_point
+ /// @param[in] match_return_elements
+ /// See CommandObject::HandleCompletions for a description of
+ /// how these work.
+ ///
+ /// @param[in] interpreter
+ /// The interpreter that's doing the completing.
+ ///
+ /// @param[out] word_complete
+ /// \btrue if this is a complete option value (a space will be
+ /// inserted after the completion.) \b false otherwise.
+ ///
+ /// @param[out] matches
+ /// The array of matches returned.
+ ///
+ /// FIXME: This is the wrong return value, since we also need to
+ /// make a distinction between total number of matches, and the
+ /// window the user wants returned.
+ ///
+ /// @return
+ /// \btrue if we were in an option, \bfalse otherwise.
+ //------------------------------------------------------------------
+ bool
+ HandleOptionCompletion (Args &input,
+ OptionElementVector &option_map,
+ int cursor_index,
+ int char_pos,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ lldb_private::StringList &matches);
+
+ //------------------------------------------------------------------
+ /// Handles the generic bits of figuring out whether we are in an
+ /// option, and if so completing it.
+ ///
+ /// @param[in] interpreter
+ /// The command interpreter doing the completion.
+ ///
+ /// @param[in] input
+ /// The command line parsed into words
+ ///
+ /// @param[in] cursor_index
+ /// The index in \ainput of the word in which the cursor lies.
+ ///
+ /// @param[in] char_pos
+ /// The character position of the cursor in its argument word.
+ ///
+ /// @param[in] opt_element_vector
+ /// The results of the options parse of \a input.
+ ///
+ /// @param[in] opt_element_index
+ /// The position in \a opt_element_vector of the word in \a
+ /// input containing the cursor.
+ ///
+ /// @param[in] match_start_point
+ /// @param[in] match_return_elements
+ /// See CommandObject::HandleCompletions for a description of
+ /// how these work.
+ ///
+ /// @param[out] word_complete
+ /// \btrue if this is a complete option value (a space will
+ /// be inserted after the completion.) \bfalse otherwise.
+ ///
+ /// @param[out] matches
+ /// The array of matches returned.
+ ///
+ /// FIXME: This is the wrong return value, since we also need to
+ /// make a distinction between total number of matches, and the
+ /// window the user wants returned.
+ ///
+ /// @return
+ /// \btrue if we were in an option, \bfalse otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ HandleOptionArgumentCompletion (Args &input,
+ int cursor_index,
+ int char_pos,
+ OptionElementVector &opt_element_vector,
+ int opt_element_index,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+protected:
+ // This is a set of options expressed as indexes into the options table for this Option.
+ typedef std::set<int> OptionSet;
+ typedef std::vector<OptionSet> OptionSetVector;
+
+ CommandInterpreter &m_interpreter;
+ std::vector<struct option> m_getopt_table;
+ OptionSet m_seen_options;
+ OptionSetVector m_required_options;
+ OptionSetVector m_optional_options;
+
+ OptionSetVector &GetRequiredOptions ()
+ {
+ BuildValidOptionSets();
+ return m_required_options;
+ }
+
+ OptionSetVector &GetOptionalOptions ()
+ {
+ BuildValidOptionSets();
+ return m_optional_options;
+ }
+
+ bool
+ IsASubset (const OptionSet& set_a, const OptionSet& set_b);
+
+ size_t
+ OptionsSetDiff (const OptionSet &set_a, const OptionSet &set_b, OptionSet &diffs);
+
+ void
+ OptionsSetUnion (const OptionSet &set_a, const OptionSet &set_b, OptionSet &union_set);
+
+ // Subclasses must reset their option values prior to starting a new
+ // option parse. Each subclass must override this function and revert
+ // all option settings to default values.
+ virtual void
+ OptionParsingStarting () = 0;
+
+ virtual Error
+ OptionParsingFinished ()
+ {
+ // If subclasses need to know when the options are done being parsed
+ // they can implement this function to do extra checking
+ Error error;
+ return error;
+ }
+};
+
+ class OptionGroup
+ {
+ public:
+ OptionGroup ()
+ {
+ }
+
+ virtual
+ ~OptionGroup ()
+ {
+ }
+
+ virtual uint32_t
+ GetNumDefinitions () = 0;
+
+ virtual const OptionDefinition*
+ GetDefinitions () = 0;
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value) = 0;
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter) = 0;
+
+ virtual Error
+ OptionParsingFinished (CommandInterpreter &interpreter)
+ {
+ // If subclasses need to know when the options are done being parsed
+ // they can implement this function to do extra checking
+ Error error;
+ return error;
+ }
+ };
+
+ class OptionGroupOptions : public Options
+ {
+ public:
+
+ OptionGroupOptions (CommandInterpreter &interpreter) :
+ Options (interpreter),
+ m_option_defs (),
+ m_option_infos (),
+ m_did_finalize (false)
+ {
+ }
+
+ virtual
+ ~OptionGroupOptions ()
+ {
+ }
+
+
+ //----------------------------------------------------------------------
+ /// Append options from a OptionGroup class.
+ ///
+ /// Append all options from \a group using the exact same option groups
+ /// that each option is defined with.
+ ///
+ /// @param[in] group
+ /// A group of options to take option values from and copy their
+ /// definitions into this class.
+ //----------------------------------------------------------------------
+ void
+ Append (OptionGroup* group);
+
+ //----------------------------------------------------------------------
+ /// Append options from a OptionGroup class.
+ ///
+ /// Append options from \a group that have a usage mask that has any bits
+ /// in "src_mask" set. After the option definition is copied into the
+ /// options definitions in this class, set the usage_mask to "dst_mask".
+ ///
+ /// @param[in] group
+ /// A group of options to take option values from and copy their
+ /// definitions into this class.
+ ///
+ /// @param[in] src_mask
+ /// When copying options from \a group, you might only want some of
+ /// the options to be appended to this group. This mask allows you
+ /// to control which options from \a group get added. It also allows
+ /// you to specify the same options from \a group multiple times
+ /// for different option sets.
+ ///
+ /// @param[in] dst_mask
+ /// Set the usage mask for any copied options to \a dst_mask after
+ /// copying the option definition.
+ //----------------------------------------------------------------------
+ void
+ Append (OptionGroup* group,
+ uint32_t src_mask,
+ uint32_t dst_mask);
+
+ void
+ Finalize ();
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx,
+ const char *option_arg);
+
+ virtual void
+ OptionParsingStarting ();
+
+ virtual Error
+ OptionParsingFinished ();
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ assert (m_did_finalize);
+ return &m_option_defs[0];
+ }
+ struct OptionInfo
+ {
+ OptionInfo (OptionGroup* g, uint32_t i) :
+ option_group (g),
+ option_index (i)
+ {
+ }
+ OptionGroup* option_group; // The group that this option came from
+ uint32_t option_index; // The original option index from the OptionGroup
+ };
+ typedef std::vector<OptionInfo> OptionInfos;
+
+ std::vector<OptionDefinition> m_option_defs;
+ OptionInfos m_option_infos;
+ bool m_did_finalize;
+ };
+
+
+} // namespace lldb_private
+
+#endif // liblldb_Options_h_
diff --git a/include/lldb/Interpreter/Property.h b/include/lldb/Interpreter/Property.h
new file mode 100644
index 000000000000..b192758cbc41
--- /dev/null
+++ b/include/lldb/Interpreter/Property.h
@@ -0,0 +1,109 @@
+//===-- Property.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Property_h_
+#define liblldb_Property_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-defines.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+ // A structure that can be used to create a global table for all properties.
+ // Property class instances can be constructed using one of these.
+ struct PropertyDefinition
+ {
+ const char *name;
+ OptionValue::Type type;
+ bool global;
+ uintptr_t default_uint_value;
+ const char *default_cstr_value;
+ OptionEnumValueElement *enum_values;
+ const char *description;
+ };
+
+ class Property
+ {
+ public:
+ Property (const PropertyDefinition &definition);
+
+ Property (const ConstString &name,
+ const ConstString &desc,
+ bool is_global,
+ const lldb::OptionValueSP &value_sp);
+
+ const ConstString &
+ GetName() const
+ {
+ return m_name;
+ }
+
+ const char *
+ GetDescription () const
+ {
+ return m_description.GetCString();
+ }
+
+ const lldb::OptionValueSP &
+ GetValue() const
+ {
+ return m_value_sp;
+ }
+
+ void
+ SetOptionValue (const lldb::OptionValueSP &value_sp)
+ {
+ m_value_sp = value_sp;
+ }
+
+
+ bool
+ IsValid() const
+ {
+ return (bool)m_value_sp;
+ }
+
+ bool
+ IsGlobal () const
+ {
+ return m_is_global;
+ }
+
+ void
+ Dump (const ExecutionContext *exe_ctx,
+ Stream &strm,
+ uint32_t dump_mask) const;
+
+ bool
+ DumpQualifiedName(Stream &strm) const;
+
+ void
+ DumpDescription (CommandInterpreter &interpreter,
+ Stream &strm,
+ uint32_t output_width,
+ bool display_qualified_name) const;
+
+ protected:
+ ConstString m_name;
+ ConstString m_description;
+ lldb::OptionValueSP m_value_sp;
+ bool m_is_global;
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_Property_h_
diff --git a/include/lldb/Interpreter/PythonDataObjects.h b/include/lldb/Interpreter/PythonDataObjects.h
new file mode 100644
index 000000000000..b2c9240db09f
--- /dev/null
+++ b/include/lldb/Interpreter/PythonDataObjects.h
@@ -0,0 +1,233 @@
+//===-- PythonDataObjects.h----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_PythonDataObjects_h_
+#define liblldb_PythonDataObjects_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-defines.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Interpreter/OptionValue.h"
+#if defined (__APPLE__)
+#include <Python/Python.h>
+#else
+#include <Python.h>
+#endif
+
+namespace lldb_private {
+
+ class PythonObject
+ {
+ public:
+ PythonObject () :
+ m_py_obj(NULL)
+ {
+ }
+
+ PythonObject (PyObject* py_obj) :
+ m_py_obj(NULL)
+ {
+ Reset (py_obj);
+ }
+
+ PythonObject (const PythonObject &rhs) :
+ m_py_obj(NULL)
+ {
+ Reset (rhs.m_py_obj);
+ }
+
+ PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp);
+
+ virtual
+ ~PythonObject ()
+ {
+ Reset (NULL);
+ }
+
+ const PythonObject &
+ operator = (const PythonObject &rhs)
+ {
+ if (this != &rhs)
+ Reset (rhs.m_py_obj);
+ return *this;
+ }
+
+ bool
+ Reset (const PythonObject &object)
+ {
+ return Reset(object.GetPythonObject());
+ }
+
+ virtual bool
+ Reset (PyObject* py_obj = NULL)
+ {
+ if (py_obj != m_py_obj)
+ {
+ Py_XDECREF(m_py_obj);
+ m_py_obj = py_obj;
+ Py_XINCREF(m_py_obj);
+ }
+ return true;
+ }
+
+ void
+ Dump () const
+ {
+ if (m_py_obj)
+ _PyObject_Dump (m_py_obj);
+ else
+ puts ("NULL");
+ }
+
+ void
+ Dump (Stream &strm) const;
+
+ PyObject*
+ GetPythonObject () const
+ {
+ return m_py_obj;
+ }
+
+ PythonString
+ Repr ();
+
+ PythonString
+ Str ();
+
+ operator bool () const
+ {
+ return m_py_obj != NULL;
+ }
+
+ protected:
+ PyObject* m_py_obj;
+ };
+
+ class PythonString: public PythonObject
+ {
+ public:
+
+ PythonString ();
+ PythonString (PyObject *o);
+ PythonString (const PythonObject &object);
+ PythonString (const lldb::ScriptInterpreterObjectSP &script_object_sp);
+ PythonString (const char* string);
+ virtual ~PythonString ();
+
+ virtual bool
+ Reset (PyObject* py_obj = NULL);
+
+ const char*
+ GetString() const;
+
+ size_t
+ GetSize() const;
+
+ void
+ SetString (const char* string);
+ };
+
+ class PythonInteger: public PythonObject
+ {
+ public:
+
+ PythonInteger ();
+ PythonInteger (PyObject* py_obj);
+ PythonInteger (const PythonObject &object);
+ PythonInteger (const lldb::ScriptInterpreterObjectSP &script_object_sp);
+ PythonInteger (int64_t value);
+ virtual ~PythonInteger ();
+
+ virtual bool
+ Reset (PyObject* py_obj = NULL);
+
+ int64_t
+ GetInteger();
+
+ void
+ SetInteger (int64_t value);
+ };
+
+ class PythonList: public PythonObject
+ {
+ public:
+
+ PythonList ();
+ PythonList (PyObject* py_obj);
+ PythonList (const PythonObject &object);
+ PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp);
+ PythonList (uint32_t count);
+ virtual ~PythonList ();
+
+ virtual bool
+ Reset (PyObject* py_obj = NULL);
+
+ uint32_t
+ GetSize();
+
+ PythonObject
+ GetItemAtIndex (uint32_t index);
+
+ void
+ SetItemAtIndex (uint32_t index, const PythonObject &object);
+
+ void
+ AppendItem (const PythonObject &object);
+ };
+
+ class PythonDictionary: public PythonObject
+ {
+ public:
+
+ PythonDictionary ();
+ PythonDictionary (PyObject* object);
+ PythonDictionary (const PythonObject &object);
+ PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp);
+ virtual ~PythonDictionary ();
+
+ virtual bool
+ Reset (PyObject* object = NULL);
+
+ uint32_t GetSize();
+
+ PythonObject
+ GetItemForKey (const PythonString &key) const;
+
+ const char *
+ GetItemForKeyAsString (const PythonString &key, const char *fail_value = NULL) const;
+
+ int64_t
+ GetItemForKeyAsInteger (const PythonString &key, int64_t fail_value = 0) const;
+
+ PythonObject
+ GetItemForKey (const char *key) const;
+
+ typedef bool (*DictionaryIteratorCallback)(PythonString* key, PythonDictionary* dict);
+
+ PythonList
+ GetKeys () const;
+
+ PythonString
+ GetKeyAtPosition (uint32_t pos) const;
+
+ PythonObject
+ GetValueAtPosition (uint32_t pos) const;
+
+ void
+ SetItemForKey (const PythonString &key, const PythonObject& value);
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_PythonDataObjects_h_
diff --git a/include/lldb/Interpreter/ScriptInterpreter.h b/include/lldb/Interpreter/ScriptInterpreter.h
new file mode 100644
index 000000000000..9a66c775d47a
--- /dev/null
+++ b/include/lldb/Interpreter/ScriptInterpreter.h
@@ -0,0 +1,519 @@
+//===-- ScriptInterpreter.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ScriptInterpreter_h_
+#define liblldb_ScriptInterpreter_h_
+
+#include "lldb/lldb-private.h"
+
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Error.h"
+
+#include "lldb/Utility/PseudoTerminal.h"
+
+
+namespace lldb_private {
+
+class ScriptInterpreterObject
+{
+public:
+ ScriptInterpreterObject() :
+ m_object(NULL)
+ {}
+
+ ScriptInterpreterObject(void* obj) :
+ m_object(obj)
+ {}
+
+ ScriptInterpreterObject(const ScriptInterpreterObject& rhs)
+ : m_object(rhs.m_object)
+ {}
+
+ virtual void*
+ GetObject()
+ {
+ return m_object;
+ }
+
+ operator bool ()
+ {
+ return m_object != NULL;
+ }
+
+ ScriptInterpreterObject&
+ operator = (const ScriptInterpreterObject& rhs)
+ {
+ if (this != &rhs)
+ m_object = rhs.m_object;
+ return *this;
+ }
+
+ virtual
+ ~ScriptInterpreterObject()
+ {}
+
+protected:
+ void* m_object;
+};
+
+class ScriptInterpreterLocker
+{
+public:
+
+ ScriptInterpreterLocker ()
+ {
+ }
+
+ virtual ~ScriptInterpreterLocker ()
+ {
+ }
+private:
+ DISALLOW_COPY_AND_ASSIGN (ScriptInterpreterLocker);
+};
+
+
+class ScriptInterpreter
+{
+public:
+
+ typedef void (*SWIGInitCallback) (void);
+
+ typedef bool (*SWIGBreakpointCallbackFunction) (const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::StackFrameSP& frame_sp,
+ const lldb::BreakpointLocationSP &bp_loc_sp);
+
+ typedef bool (*SWIGWatchpointCallbackFunction) (const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::StackFrameSP& frame_sp,
+ const lldb::WatchpointSP &wp_sp);
+
+ typedef bool (*SWIGPythonTypeScriptCallbackFunction) (const char *python_function_name,
+ void *session_dictionary,
+ const lldb::ValueObjectSP& valobj_sp,
+ void** pyfunct_wrapper,
+ std::string& retval);
+
+ typedef void* (*SWIGPythonCreateSyntheticProvider) (const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP& valobj_sp);
+
+ typedef void* (*SWIGPythonCreateOSPlugin) (const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP& process_sp);
+
+ typedef uint32_t (*SWIGPythonCalculateNumChildren) (void *implementor);
+ typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx);
+ typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name);
+ typedef void* (*SWIGPythonCastPyObjectToSBValue) (void* data);
+ typedef bool (*SWIGPythonUpdateSynthProviderInstance) (void* data);
+ typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance) (void* data);
+
+
+ typedef bool (*SWIGPythonCallCommand) (const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger,
+ const char* args,
+ lldb_private::CommandReturnObject& cmd_retobj);
+
+ typedef bool (*SWIGPythonCallModuleInit) (const char *python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger);
+
+ typedef bool (*SWIGPythonScriptKeyword_Process) (const char* python_function_name,
+ const char* session_dictionary_name,
+ lldb::ProcessSP& process,
+ std::string& output);
+ typedef bool (*SWIGPythonScriptKeyword_Thread) (const char* python_function_name,
+ const char* session_dictionary_name,
+ lldb::ThreadSP& thread,
+ std::string& output);
+
+ typedef bool (*SWIGPythonScriptKeyword_Target) (const char* python_function_name,
+ const char* session_dictionary_name,
+ lldb::TargetSP& target,
+ std::string& output);
+
+ typedef bool (*SWIGPythonScriptKeyword_Frame) (const char* python_function_name,
+ const char* session_dictionary_name,
+ lldb::StackFrameSP& frame,
+ std::string& output);
+
+
+
+ typedef enum
+ {
+ eScriptReturnTypeCharPtr,
+ eScriptReturnTypeBool,
+ eScriptReturnTypeShortInt,
+ eScriptReturnTypeShortIntUnsigned,
+ eScriptReturnTypeInt,
+ eScriptReturnTypeIntUnsigned,
+ eScriptReturnTypeLongInt,
+ eScriptReturnTypeLongIntUnsigned,
+ eScriptReturnTypeLongLong,
+ eScriptReturnTypeLongLongUnsigned,
+ eScriptReturnTypeFloat,
+ eScriptReturnTypeDouble,
+ eScriptReturnTypeChar,
+ eScriptReturnTypeCharStrOrNone
+ } ScriptReturnType;
+
+ ScriptInterpreter (CommandInterpreter &interpreter, lldb::ScriptLanguage script_lang);
+
+ virtual ~ScriptInterpreter ();
+
+ struct ExecuteScriptOptions
+ {
+ public:
+ ExecuteScriptOptions () :
+ m_enable_io(true),
+ m_set_lldb_globals(true),
+ m_maskout_errors(true)
+ {
+ }
+
+ bool
+ GetEnableIO () const
+ {
+ return m_enable_io;
+ }
+
+ bool
+ GetSetLLDBGlobals () const
+ {
+ return m_set_lldb_globals;
+ }
+
+ bool
+ GetMaskoutErrors () const
+ {
+ return m_maskout_errors;
+ }
+
+ ExecuteScriptOptions&
+ SetEnableIO (bool enable)
+ {
+ m_enable_io = enable;
+ return *this;
+ }
+
+ ExecuteScriptOptions&
+ SetSetLLDBGlobals (bool set)
+ {
+ m_set_lldb_globals = set;
+ return *this;
+ }
+
+ ExecuteScriptOptions&
+ SetMaskoutErrors (bool maskout)
+ {
+ m_maskout_errors = maskout;
+ return *this;
+ }
+
+ private:
+ bool m_enable_io;
+ bool m_set_lldb_globals;
+ bool m_maskout_errors;
+ };
+
+ virtual bool
+ ExecuteOneLine (const char *command,
+ CommandReturnObject *result,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) = 0;
+
+ virtual void
+ ExecuteInterpreterLoop () = 0;
+
+ virtual bool
+ ExecuteOneLineWithReturn (const char *in_string,
+ ScriptReturnType return_type,
+ void *ret_value,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions())
+ {
+ return true;
+ }
+
+ virtual bool
+ ExecuteMultipleLines (const char *in_string,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions())
+ {
+ return true;
+ }
+
+ virtual bool
+ ExportFunctionDefinitionToInterpreter (StringList &function_def)
+ {
+ return false;
+ }
+
+ virtual bool
+ GenerateBreakpointCommandCallbackData (StringList &input, std::string& output)
+ {
+ return false;
+ }
+
+ virtual bool
+ GenerateWatchpointCommandCallbackData (StringList &input, std::string& output)
+ {
+ return false;
+ }
+
+ virtual bool
+ GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token = NULL)
+ {
+ return false;
+ }
+
+ virtual bool
+ GenerateTypeScriptFunction (StringList &input, std::string& output, void* name_token = NULL)
+ {
+ return false;
+ }
+
+ virtual bool
+ GenerateScriptAliasFunction (StringList &input, std::string& output)
+ {
+ return false;
+ }
+
+ virtual bool
+ GenerateTypeSynthClass (StringList &input, std::string& output, void* name_token = NULL)
+ {
+ return false;
+ }
+
+ virtual bool
+ GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token = NULL)
+ {
+ return false;
+ }
+
+ virtual lldb::ScriptInterpreterObjectSP
+ CreateSyntheticScriptedProvider (const char *class_name,
+ lldb::ValueObjectSP valobj)
+ {
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_CreatePluginObject (const char *class_name,
+ lldb::ProcessSP process_sp)
+ {
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
+ {
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
+ {
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t thread_id)
+ {
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t tid,
+ lldb::addr_t context)
+ {
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
+ virtual bool
+ GenerateFunction(const char *signature, const StringList &input)
+ {
+ return false;
+ }
+
+ virtual void
+ CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
+ CommandReturnObject &result);
+
+ virtual void
+ CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
+ CommandReturnObject &result);
+
+ /// Set a one-liner as the callback for the breakpoint.
+ virtual void
+ SetBreakpointCommandCallback (BreakpointOptions *bp_options,
+ const char *oneliner)
+ {
+ return;
+ }
+
+ /// Set a one-liner as the callback for the watchpoint.
+ virtual void
+ SetWatchpointCommandCallback (WatchpointOptions *wp_options,
+ const char *oneliner)
+ {
+ return;
+ }
+
+ virtual bool
+ GetScriptedSummary (const char *function_name,
+ lldb::ValueObjectSP valobj,
+ lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
+ std::string& retval)
+ {
+ return false;
+ }
+
+ virtual size_t
+ CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor)
+ {
+ return 0;
+ }
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor, uint32_t idx)
+ {
+ return lldb::ValueObjectSP();
+ }
+
+ virtual int
+ GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name)
+ {
+ return UINT32_MAX;
+ }
+
+ virtual bool
+ UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor)
+ {
+ return false;
+ }
+
+ virtual bool
+ MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor)
+ {
+ return true;
+ }
+
+ virtual bool
+ RunScriptBasedCommand (const char* impl_function,
+ const char* args,
+ ScriptedCommandSynchronicity synchronicity,
+ lldb_private::CommandReturnObject& cmd_retobj,
+ Error& error)
+ {
+ return false;
+ }
+
+ virtual bool
+ RunScriptFormatKeyword (const char* impl_function,
+ Process* process,
+ std::string& output,
+ Error& error)
+ {
+ error.SetErrorString("unimplemented");
+ return false;
+ }
+
+ virtual bool
+ RunScriptFormatKeyword (const char* impl_function,
+ Thread* thread,
+ std::string& output,
+ Error& error)
+ {
+ error.SetErrorString("unimplemented");
+ return false;
+ }
+
+ virtual bool
+ RunScriptFormatKeyword (const char* impl_function,
+ Target* target,
+ std::string& output,
+ Error& error)
+ {
+ error.SetErrorString("unimplemented");
+ return false;
+ }
+
+ virtual bool
+ RunScriptFormatKeyword (const char* impl_function,
+ StackFrame* frame,
+ std::string& output,
+ Error& error)
+ {
+ error.SetErrorString("unimplemented");
+ return false;
+ }
+
+ virtual bool
+ GetDocumentationForItem (const char* item, std::string& dest)
+ {
+ dest.clear();
+ return false;
+ }
+
+ virtual bool
+ CheckObjectExists (const char* name)
+ {
+ return false;
+ }
+
+ virtual bool
+ LoadScriptingModule (const char* filename,
+ bool can_reload,
+ bool init_session,
+ lldb_private::Error& error)
+ {
+ error.SetErrorString("loading unimplemented");
+ return false;
+ }
+
+ virtual lldb::ScriptInterpreterObjectSP
+ MakeScriptObject (void* object)
+ {
+ return lldb::ScriptInterpreterObjectSP(new ScriptInterpreterObject(object));
+ }
+
+ virtual std::unique_ptr<ScriptInterpreterLocker>
+ AcquireInterpreterLock ();
+
+ const char *
+ GetScriptInterpreterPtyName ();
+
+ int
+ GetMasterFileDescriptor ();
+
+ CommandInterpreter &
+ GetCommandInterpreter ();
+
+ static std::string
+ LanguageToString (lldb::ScriptLanguage language);
+
+ static void
+ InitializeInterpreter (SWIGInitCallback python_swig_init_callback);
+
+ static void
+ TerminateInterpreter ();
+
+ virtual void
+ ResetOutputFileHandle (FILE *new_fh) { } //By default, do nothing.
+
+protected:
+ CommandInterpreter &m_interpreter;
+ lldb::ScriptLanguage m_script_lang;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_ScriptInterpreter_h_
diff --git a/include/lldb/Interpreter/ScriptInterpreterNone.h b/include/lldb/Interpreter/ScriptInterpreterNone.h
new file mode 100644
index 000000000000..6c82b60b0bcd
--- /dev/null
+++ b/include/lldb/Interpreter/ScriptInterpreterNone.h
@@ -0,0 +1,35 @@
+//===-- ScriptInterpreterNone.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ScriptInterpreterNone_h_
+#define liblldb_ScriptInterpreterNone_h_
+
+#include "lldb/Interpreter/ScriptInterpreter.h"
+
+namespace lldb_private {
+
+class ScriptInterpreterNone : public ScriptInterpreter
+{
+public:
+
+ ScriptInterpreterNone (CommandInterpreter &interpreter);
+
+ ~ScriptInterpreterNone ();
+
+ bool
+ ExecuteOneLine (const char *command, CommandReturnObject *result, const ExecuteScriptOptions &options = ExecuteScriptOptions());
+
+ void
+ ExecuteInterpreterLoop ();
+
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_ScriptInterpreterNone_h_
diff --git a/include/lldb/Interpreter/ScriptInterpreterPython.h b/include/lldb/Interpreter/ScriptInterpreterPython.h
new file mode 100644
index 000000000000..2616f575d20e
--- /dev/null
+++ b/include/lldb/Interpreter/ScriptInterpreterPython.h
@@ -0,0 +1,407 @@
+//===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef liblldb_ScriptInterpreterPython_h_
+#define liblldb_ScriptInterpreterPython_h_
+
+#ifdef LLDB_DISABLE_PYTHON
+
+// Python is disabled in this build
+
+#else
+
+#if defined (__APPLE__)
+#include <Python/Python.h>
+#else
+#include <Python.h>
+#endif
+
+#include "lldb/lldb-private.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Core/InputReader.h"
+#include "lldb/Host/Terminal.h"
+
+namespace lldb_private {
+
+class ScriptInterpreterPython : public ScriptInterpreter
+{
+public:
+
+ ScriptInterpreterPython (CommandInterpreter &interpreter);
+
+ ~ScriptInterpreterPython ();
+
+ bool
+ ExecuteOneLine (const char *command,
+ CommandReturnObject *result,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions());
+
+ void
+ ExecuteInterpreterLoop ();
+
+ bool
+ ExecuteOneLineWithReturn (const char *in_string,
+ ScriptInterpreter::ScriptReturnType return_type,
+ void *ret_value,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions());
+
+ bool
+ ExecuteMultipleLines (const char *in_string,
+ const ExecuteScriptOptions &options = ExecuteScriptOptions());
+
+ bool
+ ExportFunctionDefinitionToInterpreter (StringList &function_def);
+
+ bool
+ GenerateTypeScriptFunction (StringList &input, std::string& output, void* name_token = NULL);
+
+ bool
+ GenerateTypeSynthClass (StringList &input, std::string& output, void* name_token = NULL);
+
+ bool
+ GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token = NULL);
+
+ // use this if the function code is just a one-liner script
+ bool
+ GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token = NULL);
+
+ virtual bool
+ GenerateScriptAliasFunction (StringList &input, std::string& output);
+
+ lldb::ScriptInterpreterObjectSP
+ CreateSyntheticScriptedProvider (const char *class_name,
+ lldb::ValueObjectSP valobj);
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_CreatePluginObject (const char *class_name,
+ lldb::ProcessSP process_sp);
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp);
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp);
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t thread_id);
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t tid,
+ lldb::addr_t context);
+
+ virtual size_t
+ CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor);
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor, uint32_t idx);
+
+ virtual int
+ GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name);
+
+ virtual bool
+ UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor);
+
+ virtual bool
+ MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor);
+
+ virtual bool
+ RunScriptBasedCommand(const char* impl_function,
+ const char* args,
+ ScriptedCommandSynchronicity synchronicity,
+ lldb_private::CommandReturnObject& cmd_retobj,
+ Error& error);
+
+ bool
+ GenerateFunction(const char *signature, const StringList &input);
+
+ bool
+ GenerateBreakpointCommandCallbackData (StringList &input, std::string& output);
+
+ bool
+ GenerateWatchpointCommandCallbackData (StringList &input, std::string& output);
+
+ static size_t
+ GenerateBreakpointOptionsCommandCallback (void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+ static size_t
+ GenerateWatchpointOptionsCommandCallback (void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+ static bool
+ BreakpointCallbackFunction (void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ static bool
+ WatchpointCallbackFunction (void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t watch_id);
+
+ virtual bool
+ GetScriptedSummary (const char *function_name,
+ lldb::ValueObjectSP valobj,
+ lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
+ std::string& retval);
+
+ virtual bool
+ GetDocumentationForItem (const char* item, std::string& dest);
+
+ virtual bool
+ CheckObjectExists (const char* name)
+ {
+ if (!name || !name[0])
+ return false;
+ std::string temp;
+ return GetDocumentationForItem (name,temp);
+ }
+
+ virtual bool
+ RunScriptFormatKeyword (const char* impl_function,
+ Process* process,
+ std::string& output,
+ Error& error);
+
+ virtual bool
+ RunScriptFormatKeyword (const char* impl_function,
+ Thread* thread,
+ std::string& output,
+ Error& error);
+
+ virtual bool
+ RunScriptFormatKeyword (const char* impl_function,
+ Target* target,
+ std::string& output,
+ Error& error);
+
+ virtual bool
+ RunScriptFormatKeyword (const char* impl_function,
+ StackFrame* frame,
+ std::string& output,
+ Error& error);
+
+ virtual bool
+ LoadScriptingModule (const char* filename,
+ bool can_reload,
+ bool init_session,
+ lldb_private::Error& error);
+
+ virtual lldb::ScriptInterpreterObjectSP
+ MakeScriptObject (void* object);
+
+ virtual std::unique_ptr<ScriptInterpreterLocker>
+ AcquireInterpreterLock ();
+
+ void
+ CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
+ CommandReturnObject &result);
+
+ void
+ CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
+ CommandReturnObject &result);
+
+ /// Set a Python one-liner as the callback for the breakpoint.
+ void
+ SetBreakpointCommandCallback (BreakpointOptions *bp_options,
+ const char *oneliner);
+
+ /// Set a one-liner as the callback for the watchpoint.
+ void
+ SetWatchpointCommandCallback (WatchpointOptions *wp_options,
+ const char *oneliner);
+
+ StringList
+ ReadCommandInputFromUser (FILE *in_file);
+
+ virtual void
+ ResetOutputFileHandle (FILE *new_fh);
+
+ static lldb::thread_result_t
+ RunEmbeddedPythonInterpreter (lldb::thread_arg_t baton);
+
+ static void
+ InitializePrivate ();
+
+ static void
+ InitializeInterpreter (SWIGInitCallback python_swig_init_callback);
+
+protected:
+
+ bool
+ EnterSession (bool init_lldb_globals);
+
+ void
+ LeaveSession ();
+
+ void
+ SaveTerminalState (int fd);
+
+ void
+ RestoreTerminalState ();
+
+private:
+
+ class SynchronicityHandler
+ {
+ private:
+ lldb::DebuggerSP m_debugger_sp;
+ ScriptedCommandSynchronicity m_synch_wanted;
+ bool m_old_asynch;
+ public:
+ SynchronicityHandler(lldb::DebuggerSP,
+ ScriptedCommandSynchronicity);
+ ~SynchronicityHandler();
+ };
+
+ class ScriptInterpreterPythonObject : public ScriptInterpreterObject
+ {
+ public:
+ ScriptInterpreterPythonObject() :
+ ScriptInterpreterObject()
+ {}
+
+ ScriptInterpreterPythonObject(void* obj) :
+ ScriptInterpreterObject(obj)
+ {
+ Py_XINCREF(m_object);
+ }
+
+ operator bool ()
+ {
+ return m_object && m_object != Py_None;
+ }
+
+
+ virtual
+ ~ScriptInterpreterPythonObject()
+ {
+ Py_XDECREF(m_object);
+ m_object = NULL;
+ }
+ private:
+ DISALLOW_COPY_AND_ASSIGN (ScriptInterpreterPythonObject);
+ };
+
+ class Locker : public ScriptInterpreterLocker
+ {
+ public:
+
+ enum OnEntry
+ {
+ AcquireLock = 0x0001,
+ InitSession = 0x0002,
+ InitGlobals = 0x0004
+ };
+
+ enum OnLeave
+ {
+ FreeLock = 0x0001,
+ FreeAcquiredLock = 0x0002, // do not free the lock if we already held it when calling constructor
+ TearDownSession = 0x0004
+ };
+
+ Locker (ScriptInterpreterPython *py_interpreter = NULL,
+ uint16_t on_entry = AcquireLock | InitSession,
+ uint16_t on_leave = FreeLock | TearDownSession,
+ FILE* wait_msg_handle = NULL);
+
+ ~Locker ();
+
+ private:
+
+ bool
+ DoAcquireLock ();
+
+ bool
+ DoInitSession (bool init_lldb_globals);
+
+ bool
+ DoFreeLock ();
+
+ bool
+ DoTearDownSession ();
+
+ static void
+ ReleasePythonLock ();
+
+ bool m_teardown_session;
+ ScriptInterpreterPython *m_python_interpreter;
+ FILE* m_tmp_fh;
+ PyGILState_STATE m_GILState;
+ };
+
+ class PythonInputReaderManager
+ {
+ public:
+ PythonInputReaderManager (ScriptInterpreterPython *interpreter);
+
+ operator bool()
+ {
+ return m_error;
+ }
+
+ ~PythonInputReaderManager();
+
+ private:
+
+ static size_t
+ InputReaderCallback (void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+ static lldb::thread_result_t
+ RunPythonInputReader (lldb::thread_arg_t baton);
+
+ ScriptInterpreterPython *m_interpreter;
+ lldb::DebuggerSP m_debugger_sp;
+ lldb::InputReaderSP m_reader_sp;
+ bool m_error;
+ };
+
+ static size_t
+ InputReaderCallback (void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+
+ lldb_utility::PseudoTerminal m_embedded_thread_pty;
+ lldb_utility::PseudoTerminal m_embedded_python_pty;
+ lldb::InputReaderSP m_embedded_thread_input_reader_sp;
+ lldb::InputReaderSP m_embedded_python_input_reader_sp;
+ FILE *m_dbg_stdout;
+ PyObject *m_new_sysout;
+ PyObject *m_old_sysout;
+ PyObject *m_old_syserr;
+ PyObject *m_run_one_line;
+ std::string m_dictionary_name;
+ TerminalState m_terminal_state;
+ bool m_session_is_active;
+ bool m_pty_slave_is_open;
+ bool m_valid_session;
+ PyThreadState *m_command_thread_state;
+};
+} // namespace lldb_private
+
+#endif // #ifdef LLDB_DISABLE_PYTHON
+
+#endif // #ifndef liblldb_ScriptInterpreterPython_h_
diff --git a/include/lldb/Symbol/Block.h b/include/lldb/Symbol/Block.h
new file mode 100644
index 000000000000..a2d703b9069c
--- /dev/null
+++ b/include/lldb/Symbol/Block.h
@@ -0,0 +1,496 @@
+//===-- Block.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Block_h_
+#define liblldb_Block_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Symbol/LineEntry.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Block Block.h "lldb/Symbol/Block.h"
+/// @brief A class that describes a single lexical block.
+///
+/// A Function object owns a BlockList object which owns one or more
+/// Block objects. The BlockList object contains a section offset
+/// address range, and Block objects contain one or more ranges
+/// which are offsets into that range. Blocks are can have discontiguous
+/// ranges within the BlockList adress range, and each block can
+/// contain child blocks each with their own sets of ranges.
+///
+/// Each block has a variable list that represents local, argument, and
+/// static variables that are scoped to the block.
+///
+/// Inlined functions are representated by attaching a
+/// InlineFunctionInfo shared pointer object to a block. Inlined
+/// functions are represented as named blocks.
+//----------------------------------------------------------------------
+class Block :
+ public UserID,
+ public SymbolContextScope
+{
+public:
+ typedef RangeArray<uint32_t, uint32_t, 1> RangeList;
+ typedef RangeList::Entry Range;
+
+ //------------------------------------------------------------------
+ /// Construct with a User ID \a uid, \a depth.
+ ///
+ /// Initialize this block with the specified UID \a uid. The
+ /// \a depth in the \a block_list is used to represent the parent,
+ /// sibling, and child block information and also allows for partial
+ /// parsing at the block level.
+ ///
+ /// @param[in] uid
+ /// The UID for a given block. This value is given by the
+ /// SymbolFile plug-in and can be any value that helps the
+ /// SymbolFile plug-in to match this block back to the debug
+ /// information data that it parses for further or more in
+ /// depth parsing. Common values would be the index into a
+ /// table, or an offset into the debug information.
+ ///
+ /// @param[in] depth
+ /// The integer depth of this block in the block list hierarchy.
+ ///
+ /// @param[in] block_list
+ /// The block list that this object belongs to.
+ ///
+ /// @see BlockList
+ //------------------------------------------------------------------
+ Block (lldb::user_id_t uid);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ virtual ~Block ();
+
+ //------------------------------------------------------------------
+ /// Add a child to this object.
+ ///
+ /// @param[in] child_block_sp
+ /// A shared pointer to a child block that will get added to
+ /// this block.
+ //------------------------------------------------------------------
+ void
+ AddChild (const lldb::BlockSP &child_block_sp);
+
+ //------------------------------------------------------------------
+ /// Add a new offset range to this block.
+ ///
+ /// @param[in] start_offset
+ /// An offset into this Function's address range that
+ /// describes the start address of a range for this block.
+ ///
+ /// @param[in] end_offset
+ /// An offset into this Function's address range that
+ /// describes the end address of a range for this block.
+ //------------------------------------------------------------------
+ void
+ AddRange (const Range& range);
+
+ void
+ FinalizeRanges ();
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext(SymbolContext* sc);
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ();
+
+ virtual CompileUnit *
+ CalculateSymbolContextCompileUnit ();
+
+ virtual Function *
+ CalculateSymbolContextFunction ();
+
+ virtual Block *
+ CalculateSymbolContextBlock ();
+
+ //------------------------------------------------------------------
+ /// Check if an offset is in one of the block offset ranges.
+ ///
+ /// @param[in] range_offset
+ /// An offset into the Function's address range.
+ ///
+ /// @return
+ /// Returns \b true if \a range_offset falls in one of this
+ /// block's ranges, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Contains (lldb::addr_t range_offset) const;
+
+ //------------------------------------------------------------------
+ /// Check if a offset range is in one of the block offset ranges.
+ ///
+ /// @param[in] range
+ /// An offset range into the Function's address range.
+ ///
+ /// @return
+ /// Returns \b true if \a range falls in one of this
+ /// block's ranges, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Contains (const Range& range) const;
+
+ //------------------------------------------------------------------
+ /// Check if this object contains "block" as a child block at any
+ /// depth.
+ ///
+ /// @param[in] block
+ /// A potential child block.
+ ///
+ /// @return
+ /// Returns \b true if \a block is a child of this block, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Contains (const Block *block) const;
+
+ //------------------------------------------------------------------
+ /// Dump the block contents.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] base_addr
+ /// The resolved start address of the Function's address
+ /// range. This should be resolved as the file or load address
+ /// prior to passing the value into this function for dumping.
+ ///
+ /// @param[in] depth
+ /// Limit the number of levels deep that this function should
+ /// print as this block can contain child blocks. Specify
+ /// INT_MAX to dump all child blocks.
+ ///
+ /// @param[in] show_context
+ /// If \b true, variables will dump their context information.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, lldb::addr_t base_addr, int32_t depth, bool show_context) const;
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext(Stream *s);
+
+ void
+ DumpAddressRanges (Stream *s,
+ lldb::addr_t base_addr);
+
+ void
+ GetDescription (Stream *s,
+ Function *function,
+ lldb::DescriptionLevel level,
+ Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Get the parent block.
+ ///
+ /// @return
+ /// The parent block pointer, or NULL if this block has no
+ /// parent.
+ //------------------------------------------------------------------
+ Block *
+ GetParent () const;
+
+
+ //------------------------------------------------------------------
+ /// Get the inlined block that contains this block.
+ ///
+ /// @return
+ /// If this block contains inlined function info, it will return
+ /// this block, else parent blocks will be searched to see if
+ /// any contain this block. NULL will be returned if this block
+ /// nor any parent blocks are inlined function blocks.
+ //------------------------------------------------------------------
+ Block *
+ GetContainingInlinedBlock ();
+
+ //------------------------------------------------------------------
+ /// Get the inlined parent block for this block.
+ ///
+ /// @return
+ /// The parent block pointer, or NULL if this block has no
+ /// parent.
+ //------------------------------------------------------------------
+ Block *
+ GetInlinedParent ();
+
+ //------------------------------------------------------------------
+ /// Get the sibling block for this block.
+ ///
+ /// @return
+ /// The sibling block pointer, or NULL if this block has no
+ /// sibling.
+ //------------------------------------------------------------------
+ Block *
+ GetSibling () const;
+
+ //------------------------------------------------------------------
+ /// Get the first child block.
+ ///
+ /// @return
+ /// The first child block pointer, or NULL if this block has no
+ /// children.
+ //------------------------------------------------------------------
+ Block *
+ GetFirstChild () const
+ {
+ if (m_children.empty())
+ return NULL;
+ return m_children.front().get();
+ }
+
+ //------------------------------------------------------------------
+ /// Get the variable list for this block only.
+ ///
+ /// @param[in] can_create
+ /// If \b true, the variables can be parsed if they already
+ /// haven't been, else the current state of the block will be
+ /// returned.
+ ///
+ /// @return
+ /// A variable list shared pointer that contains all variables
+ /// for this block.
+ //------------------------------------------------------------------
+ lldb::VariableListSP
+ GetBlockVariableList (bool can_create);
+
+
+ //------------------------------------------------------------------
+ /// Get the variable list for this block and optionally all child
+ /// blocks if \a get_child_variables is \b true.
+ ///
+ /// @param[in] get_child_variables
+ /// If \b true, all variables from all child blocks will be
+ /// added to the variable list.
+ ///
+ /// @param[in] can_create
+ /// If \b true, the variables can be parsed if they already
+ /// haven't been, else the current state of the block will be
+ /// returned. Passing \b true for this parameter can be used
+ /// to see the current state of what has been parsed up to this
+ /// point.
+ ///
+ /// @param[in] add_inline_child_block_variables
+ /// If this is \b false, no child variables of child blocks
+ /// that are inlined functions will be gotten. If \b true then
+ /// all child variables will be added regardless of whether they
+ /// come from inlined functions or not.
+ ///
+ /// @return
+ /// A variable list shared pointer that contains all variables
+ /// for this block.
+ //------------------------------------------------------------------
+ uint32_t
+ AppendBlockVariables (bool can_create,
+ bool get_child_block_variables,
+ bool stop_if_child_block_is_inlined_function,
+ VariableList *variable_list);
+
+ //------------------------------------------------------------------
+ /// Appends the variables from this block, and optionally from all
+ /// parent blocks, to \a variable_list.
+ ///
+ /// @param[in] can_create
+ /// If \b true, the variables can be parsed if they already
+ /// haven't been, else the current state of the block will be
+ /// returned. Passing \b true for this parameter can be used
+ /// to see the current state of what has been parsed up to this
+ /// point.
+ ///
+ /// @param[in] get_parent_variables
+ /// If \b true, all variables from all parent blocks will be
+ /// added to the variable list.
+ ///
+ /// @param[in] stop_if_block_is_inlined_function
+ /// If \b true, all variables from all parent blocks will be
+ /// added to the variable list until there are no parent blocks
+ /// or the parent block has inlined function info.
+ ///
+ /// @param[in/out] variable_list
+ /// All variables in this block, and optionally all parent
+ /// blocks will be added to this list.
+ ///
+ /// @return
+ /// The number of variable that were appended to \a
+ /// variable_list.
+ //------------------------------------------------------------------
+ uint32_t
+ AppendVariables (bool can_create,
+ bool get_parent_variables,
+ bool stop_if_block_is_inlined_function,
+ VariableList *variable_list);
+
+ //------------------------------------------------------------------
+ /// Get const accessor for any inlined function information.
+ ///
+ /// @return
+ /// A comst pointer to any inlined function information, or NULL
+ /// if this is a regular block.
+ //------------------------------------------------------------------
+ const InlineFunctionInfo*
+ GetInlinedFunctionInfo () const
+ {
+ return m_inlineInfoSP.get();
+ }
+
+ clang::DeclContext *
+ GetClangDeclContext();
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// Returns the cost of this object plus any owned objects from the
+ /// ranges, variables, and inline function information.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ //------------------------------------------------------------------
+ size_t
+ MemorySize() const;
+
+ //------------------------------------------------------------------
+ /// Set accessor for any inlined function information.
+ ///
+ /// @param[in] name
+ /// The method name for the inlined function. This value should
+ /// not be NULL.
+ ///
+ /// @param[in] mangled
+ /// The mangled method name for the inlined function. This can
+ /// be NULL if there is no mangled name for an inlined function
+ /// or if the name is the same as \a name.
+ ///
+ /// @param[in] decl_ptr
+ /// A optional pointer to declaration information for the
+ /// inlined function information. This value can be NULL to
+ /// indicate that no declaration information is available.
+ ///
+ /// @param[in] call_decl_ptr
+ /// Optional calling location declaration information that
+ /// describes from where this inlined function was called.
+ //------------------------------------------------------------------
+ void
+ SetInlinedFunctionInfo (const char *name,
+ const char *mangled,
+ const Declaration *decl_ptr,
+ const Declaration *call_decl_ptr);
+
+
+ void
+ SetParentScope (SymbolContextScope *parent_scope)
+ {
+ m_parent_scope = parent_scope;
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the variable list.
+ ///
+ /// Called by the SymbolFile plug-ins after they have parsed the
+ /// variable lists and are ready to hand ownership of the list over
+ /// to this object.
+ ///
+ /// @param[in] variable_list_sp
+ /// A shared pointer to a VariableList.
+ //------------------------------------------------------------------
+ void
+ SetVariableList (lldb::VariableListSP& variable_list_sp)
+ {
+ m_variable_list_sp = variable_list_sp;
+ }
+
+
+
+ bool
+ BlockInfoHasBeenParsed() const
+ {
+ return m_parsed_block_info;
+ }
+
+ void
+ SetBlockInfoHasBeenParsed (bool b, bool set_children);
+
+ Block *
+ FindBlockByID (lldb::user_id_t block_id);
+
+ size_t
+ GetNumRanges () const
+ {
+ return m_ranges.GetSize();
+ }
+
+ bool
+ GetRangeContainingOffset (const lldb::addr_t offset, Range &range);
+
+ bool
+ GetRangeContainingAddress (const Address& addr, AddressRange &range);
+
+ bool
+ GetRangeContainingLoadAddress (lldb::addr_t load_addr, Target &target, AddressRange &range);
+
+ uint32_t
+ GetRangeIndexContainingAddress (const Address& addr);
+
+ //------------------------------------------------------------------
+ // Since blocks might have multiple discontiguous addresss ranges,
+ // we need to be able to get at any of the address ranges in a block.
+ //------------------------------------------------------------------
+ bool
+ GetRangeAtIndex (uint32_t range_idx,
+ AddressRange &range);
+
+ bool
+ GetStartAddress (Address &addr);
+
+ void
+ SetDidParseVariables (bool b, bool set_children);
+
+protected:
+ typedef std::vector<lldb::BlockSP> collection;
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ SymbolContextScope *m_parent_scope;
+ collection m_children;
+ RangeList m_ranges;
+ lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information.
+ lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, static and paramter variables scoped to this block.
+ bool m_parsed_block_info:1, ///< Set to true if this block and it's children have all been parsed
+ m_parsed_block_variables:1,
+ m_parsed_child_blocks:1;
+
+ // A parent of child blocks can be asked to find a sibling block given
+ // one of its child blocks
+ Block *
+ GetSiblingForChild (const Block *child_block) const;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (Block);
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_Block_h_
diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h
new file mode 100644
index 000000000000..75fc07b480e1
--- /dev/null
+++ b/include/lldb/Symbol/ClangASTContext.h
@@ -0,0 +1,441 @@
+//===-- ClangASTContext.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangASTContext_h_
+#define liblldb_ClangASTContext_h_
+
+// C Includes
+#include <stdint.h>
+
+// C++ Includes
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/TemplateBase.h"
+
+
+// Project includes
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Symbol/ClangASTType.h"
+
+namespace lldb_private {
+
+class Declaration;
+
+class ClangASTContext
+{
+public:
+ typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *);
+ typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ClangASTContext (const char *triple = NULL);
+
+ ~ClangASTContext();
+
+ clang::ASTContext *
+ getASTContext();
+
+ clang::Builtin::Context *
+ getBuiltinContext();
+
+ clang::IdentifierTable *
+ getIdentifierTable();
+
+ clang::LangOptions *
+ getLanguageOptions();
+
+ clang::SelectorTable *
+ getSelectorTable();
+
+ clang::FileManager *
+ getFileManager();
+
+ clang::SourceManager *
+ getSourceManager();
+
+ clang::DiagnosticsEngine *
+ getDiagnosticsEngine();
+
+ clang::DiagnosticConsumer *
+ getDiagnosticConsumer();
+
+ clang::TargetOptions *
+ getTargetOptions();
+
+ clang::TargetInfo *
+ getTargetInfo();
+
+ void
+ Clear();
+
+ const char *
+ GetTargetTriple ();
+
+ void
+ SetTargetTriple (const char *target_triple);
+
+ void
+ SetArchitecture (const ArchSpec &arch);
+
+ bool
+ HasExternalSource ();
+
+ void
+ SetExternalSource (llvm::OwningPtr<clang::ExternalASTSource> &ast_source_ap);
+
+ void
+ RemoveExternalSource ();
+
+ bool
+ GetCompleteDecl (clang::Decl *decl)
+ {
+ return ClangASTContext::GetCompleteDecl(getASTContext(), decl);
+ }
+
+ static bool
+ GetCompleteDecl (clang::ASTContext *ast,
+ clang::Decl *decl);
+
+ void SetMetadataAsUserID (const void *object,
+ lldb::user_id_t user_id);
+
+ void SetMetadata (const void *object,
+ ClangASTMetadata &meta_data)
+ {
+ SetMetadata(getASTContext(), object, meta_data);
+ }
+
+ static void
+ SetMetadata (clang::ASTContext *ast,
+ const void *object,
+ ClangASTMetadata &meta_data);
+
+ ClangASTMetadata *
+ GetMetadata (const void *object)
+ {
+ return GetMetadata(getASTContext(), object);
+ }
+
+ static ClangASTMetadata *
+ GetMetadata (clang::ASTContext *ast,
+ const void *object);
+
+ //------------------------------------------------------------------
+ // Basic Types
+ //------------------------------------------------------------------
+ ClangASTType
+ GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding,
+ uint32_t bit_size);
+
+ static ClangASTType
+ GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast,
+ lldb::Encoding encoding,
+ uint32_t bit_size);
+
+ ClangASTType
+ GetBasicType (lldb::BasicType type);
+
+ static ClangASTType
+ GetBasicType (clang::ASTContext *ast, lldb::BasicType type);
+
+ static ClangASTType
+ GetBasicType (clang::ASTContext *ast, const ConstString &name);
+
+ static lldb::BasicType
+ GetBasicTypeEnumeration (const ConstString &name);
+
+ ClangASTType
+ GetBuiltinTypeForDWARFEncodingAndBitSize (
+ const char *type_name,
+ uint32_t dw_ate,
+ uint32_t bit_size);
+
+ ClangASTType
+ GetCStringType(bool is_const);
+
+ static ClangASTType
+ GetUnknownAnyType(clang::ASTContext *ast);
+
+ ClangASTType
+ GetUnknownAnyType()
+ {
+ return ClangASTContext::GetUnknownAnyType(getASTContext());
+ }
+
+ uint32_t
+ GetPointerByteSize ();
+
+ static clang::DeclContext *
+ GetTranslationUnitDecl (clang::ASTContext *ast);
+
+ clang::DeclContext *
+ GetTranslationUnitDecl ()
+ {
+ return GetTranslationUnitDecl (getASTContext());
+ }
+
+ static bool
+ GetClassMethodInfoForDeclContext (clang::DeclContext *decl_ctx,
+ lldb::LanguageType &language,
+ bool &is_instance_method,
+ ConstString &language_object_name);
+
+ static ClangASTType
+ CopyType(clang::ASTContext *dest_context,
+ ClangASTType source_type);
+
+ static clang::Decl *
+ CopyDecl (clang::ASTContext *dest_context,
+ clang::ASTContext *source_context,
+ clang::Decl *source_decl);
+
+ static bool
+ AreTypesSame(ClangASTType type1,
+ ClangASTType type2,
+ bool ignore_qualifiers = false);
+
+ ClangASTType
+ GetTypeForDecl (clang::TagDecl *decl);
+
+ ClangASTType
+ GetTypeForDecl (clang::ObjCInterfaceDecl *objc_decl);
+
+ //------------------------------------------------------------------
+ // Structure, Unions, Classes
+ //------------------------------------------------------------------
+
+ static clang::AccessSpecifier
+ ConvertAccessTypeToAccessSpecifier (lldb::AccessType access);
+
+ static clang::AccessSpecifier
+ UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs);
+
+ static uint32_t
+ GetNumBaseClasses (const clang::CXXRecordDecl *cxx_record_decl,
+ bool omit_empty_base_classes);
+
+ static uint32_t
+ GetIndexForRecordBase (const clang::RecordDecl *record_decl,
+ const clang::CXXBaseSpecifier *base_spec,
+ bool omit_empty_base_classes);
+
+ ClangASTType
+ CreateRecordType (clang::DeclContext *decl_ctx,
+ lldb::AccessType access_type,
+ const char *name,
+ int kind,
+ lldb::LanguageType language,
+ ClangASTMetadata *metadata = NULL);
+
+ class TemplateParameterInfos
+ {
+ public:
+ bool
+ IsValid() const
+ {
+ if (args.empty())
+ return false;
+ return args.size() == names.size();
+ }
+
+ size_t
+ GetSize () const
+ {
+ if (IsValid())
+ return args.size();
+ return 0;
+ }
+
+ llvm::SmallVector<const char *, 8> names;
+ llvm::SmallVector<clang::TemplateArgument, 8> args;
+ };
+
+ clang::FunctionTemplateDecl *
+ CreateFunctionTemplateDecl (clang::DeclContext *decl_ctx,
+ clang::FunctionDecl *func_decl,
+ const char *name,
+ const TemplateParameterInfos &infos);
+
+ void
+ CreateFunctionTemplateSpecializationInfo (clang::FunctionDecl *func_decl,
+ clang::FunctionTemplateDecl *Template,
+ const TemplateParameterInfos &infos);
+
+ clang::ClassTemplateDecl *
+ CreateClassTemplateDecl (clang::DeclContext *decl_ctx,
+ lldb::AccessType access_type,
+ const char *class_name,
+ int kind,
+ const TemplateParameterInfos &infos);
+
+ clang::ClassTemplateSpecializationDecl *
+ CreateClassTemplateSpecializationDecl (clang::DeclContext *decl_ctx,
+ clang::ClassTemplateDecl *class_template_decl,
+ int kind,
+ const TemplateParameterInfos &infos);
+
+ ClangASTType
+ CreateClassTemplateSpecializationType (clang::ClassTemplateSpecializationDecl *class_template_specialization_decl);
+
+ static clang::DeclContext *
+ GetAsDeclContext (clang::CXXMethodDecl *cxx_method_decl);
+
+ static clang::DeclContext *
+ GetAsDeclContext (clang::ObjCMethodDecl *objc_method_decl);
+
+
+ static bool
+ CheckOverloadedOperatorKindParameterCount (uint32_t op_kind,
+ uint32_t num_params);
+
+ bool
+ FieldIsBitfield (clang::FieldDecl* field,
+ uint32_t& bitfield_bit_size);
+
+ static bool
+ FieldIsBitfield (clang::ASTContext *ast,
+ clang::FieldDecl* field,
+ uint32_t& bitfield_bit_size);
+
+ static bool
+ RecordHasFields (const clang::RecordDecl *record_decl);
+
+
+ ClangASTType
+ CreateObjCClass (const char *name,
+ clang::DeclContext *decl_ctx,
+ bool isForwardDecl,
+ bool isInternal,
+ ClangASTMetadata *metadata = NULL);
+
+ // Returns a mask containing bits from the ClangASTContext::eTypeXXX enumerations
+
+
+ //------------------------------------------------------------------
+ // Namespace Declarations
+ //------------------------------------------------------------------
+
+ clang::NamespaceDecl *
+ GetUniqueNamespaceDeclaration (const char *name,
+ clang::DeclContext *decl_ctx);
+
+ //------------------------------------------------------------------
+ // Function Types
+ //------------------------------------------------------------------
+
+ clang::FunctionDecl *
+ CreateFunctionDeclaration (clang::DeclContext *decl_ctx,
+ const char *name,
+ const ClangASTType &function_Type,
+ int storage,
+ bool is_inline);
+
+ static ClangASTType
+ CreateFunctionType (clang::ASTContext *ast,
+ const ClangASTType &result_type,
+ const ClangASTType *args,
+ unsigned num_args,
+ bool is_variadic,
+ unsigned type_quals);
+
+ ClangASTType
+ CreateFunctionType (const ClangASTType &result_type,
+ const ClangASTType *args,
+ unsigned num_args,
+ bool is_variadic,
+ unsigned type_quals)
+ {
+ return ClangASTContext::CreateFunctionType(getASTContext(),
+ result_type,
+ args,
+ num_args,
+ is_variadic,
+ type_quals);
+ }
+
+ clang::ParmVarDecl *
+ CreateParameterDeclaration (const char *name,
+ const ClangASTType &param_type,
+ int storage);
+
+ void
+ SetFunctionParameters (clang::FunctionDecl *function_decl,
+ clang::ParmVarDecl **params,
+ unsigned num_params);
+
+ //------------------------------------------------------------------
+ // Array Types
+ //------------------------------------------------------------------
+
+ ClangASTType
+ CreateArrayType (const ClangASTType &element_type,
+ size_t element_count,
+ bool is_vector);
+
+ //------------------------------------------------------------------
+ // Enumeration Types
+ //------------------------------------------------------------------
+ ClangASTType
+ CreateEnumerationType (const char *name,
+ clang::DeclContext *decl_ctx,
+ const Declaration &decl,
+ const ClangASTType &integer_qual_type);
+
+ //------------------------------------------------------------------
+ // Floating point functions
+ //------------------------------------------------------------------
+
+ ClangASTType
+ GetFloatTypeFromBitSize (size_t bit_size)
+ {
+ return GetFloatTypeFromBitSize (getASTContext(), bit_size);
+ }
+
+ static ClangASTType
+ GetFloatTypeFromBitSize (clang::ASTContext *ast,
+ size_t bit_size);
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from ClangASTContext can see and modify these
+ //------------------------------------------------------------------
+ std::string m_target_triple;
+ std::unique_ptr<clang::ASTContext> m_ast_ap;
+ std::unique_ptr<clang::LangOptions> m_language_options_ap;
+ std::unique_ptr<clang::FileManager> m_file_manager_ap;
+ std::unique_ptr<clang::FileSystemOptions> m_file_system_options_ap;
+ std::unique_ptr<clang::SourceManager> m_source_manager_ap;
+ std::unique_ptr<clang::DiagnosticsEngine> m_diagnostics_engine_ap;
+ std::unique_ptr<clang::DiagnosticConsumer> m_diagnostic_consumer_ap;
+ llvm::IntrusiveRefCntPtr<clang::TargetOptions> m_target_options_rp;
+ std::unique_ptr<clang::TargetInfo> m_target_info_ap;
+ std::unique_ptr<clang::IdentifierTable> m_identifier_table_ap;
+ std::unique_ptr<clang::SelectorTable> m_selector_table_ap;
+ std::unique_ptr<clang::Builtin::Context> m_builtins_ap;
+ CompleteTagDeclCallback m_callback_tag_decl;
+ CompleteObjCInterfaceDeclCallback m_callback_objc_decl;
+ void * m_callback_baton;
+ uint32_t m_pointer_byte_size;
+private:
+ //------------------------------------------------------------------
+ // For ClangASTContext only
+ //------------------------------------------------------------------
+ ClangASTContext(const ClangASTContext&);
+ const ClangASTContext& operator=(const ClangASTContext&);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangASTContext_h_
diff --git a/include/lldb/Symbol/ClangASTImporter.h b/include/lldb/Symbol/ClangASTImporter.h
new file mode 100644
index 000000000000..10df7da893a8
--- /dev/null
+++ b/include/lldb/Symbol/ClangASTImporter.h
@@ -0,0 +1,371 @@
+//===-- ClangASTImporter.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangASTImporter_h_
+#define liblldb_ClangASTImporter_h_
+
+#include <map>
+#include <set>
+
+#include "lldb/lldb-types.h"
+#include "clang/AST/ASTImporter.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "lldb/Symbol/ClangNamespaceDecl.h"
+
+namespace lldb_private {
+
+class ClangASTMetrics
+{
+public:
+ static void DumpCounters (Log *log);
+ static void ClearLocalCounters ()
+ {
+ local_counters = { 0, 0, 0, 0, 0, 0 };
+ }
+
+ static void RegisterVisibleQuery ()
+ {
+ ++global_counters.m_visible_query_count;
+ ++local_counters.m_visible_query_count;
+ }
+
+ static void RegisterLexicalQuery ()
+ {
+ ++global_counters.m_lexical_query_count;
+ ++local_counters.m_lexical_query_count;
+ }
+
+ static void RegisterLLDBImport ()
+ {
+ ++global_counters.m_lldb_import_count;
+ ++local_counters.m_lldb_import_count;
+ }
+
+ static void RegisterClangImport ()
+ {
+ ++global_counters.m_clang_import_count;
+ ++local_counters.m_clang_import_count;
+ }
+
+ static void RegisterDeclCompletion ()
+ {
+ ++global_counters.m_decls_completed_count;
+ ++local_counters.m_decls_completed_count;
+ }
+
+ static void RegisterRecordLayout ()
+ {
+ ++global_counters.m_record_layout_count;
+ ++local_counters.m_record_layout_count;
+ }
+
+private:
+ struct Counters
+ {
+ uint64_t m_visible_query_count;
+ uint64_t m_lexical_query_count;
+ uint64_t m_lldb_import_count;
+ uint64_t m_clang_import_count;
+ uint64_t m_decls_completed_count;
+ uint64_t m_record_layout_count;
+ };
+
+ static Counters global_counters;
+ static Counters local_counters;
+
+ static void DumpCounters (Log *log, Counters &counters);
+};
+
+class ClangASTImporter
+{
+public:
+ ClangASTImporter () :
+ m_file_manager(clang::FileSystemOptions())
+ {
+ }
+
+ clang::QualType
+ CopyType (clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ clang::QualType type);
+
+ lldb::clang_type_t
+ CopyType (clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ lldb::clang_type_t type);
+
+ clang::Decl *
+ CopyDecl (clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ clang::Decl *decl);
+
+ lldb::clang_type_t
+ DeportType (clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ lldb::clang_type_t type);
+
+ clang::Decl *
+ DeportDecl (clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ clang::Decl *decl);
+
+ void
+ CompleteDecl (clang::Decl *decl);
+
+ bool
+ CompleteTagDecl (clang::TagDecl *decl);
+
+ bool
+ CompleteTagDeclWithOrigin (clang::TagDecl *decl, clang::TagDecl *origin);
+
+ bool
+ CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl);
+
+ bool
+ RequireCompleteType (clang::QualType type);
+
+ bool
+ ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx)
+ {
+ DeclOrigin origin = GetDeclOrigin(decl);
+
+ if (original_decl)
+ *original_decl = origin.decl;
+
+ if (original_ctx)
+ *original_ctx = origin.ctx;
+
+ return origin.Valid();
+ }
+
+ void
+ SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl);
+
+ ClangASTMetadata *
+ GetDeclMetadata (const clang::Decl *decl);
+
+ //
+ // Namespace maps
+ //
+
+ typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap;
+ typedef std::shared_ptr<NamespaceMap> NamespaceMapSP;
+
+ void RegisterNamespaceMap (const clang::NamespaceDecl *decl,
+ NamespaceMapSP &namespace_map);
+
+ NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl);
+
+ void BuildNamespaceMap (const clang::NamespaceDecl *decl);
+
+ //
+ // Comleters for maps
+ //
+
+ class MapCompleter
+ {
+ public:
+ virtual ~MapCompleter ();
+
+ virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map,
+ const ConstString &name,
+ NamespaceMapSP &parent_map) const = 0;
+ };
+
+ void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer)
+ {
+ ASTContextMetadataSP context_md;
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter == m_metadata_map.end())
+ {
+ context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
+ m_metadata_map[dst_ctx] = context_md;
+ }
+ else
+ {
+ context_md = context_md_iter->second;
+ }
+
+ context_md->m_map_completer = &completer;
+ }
+
+ void ForgetDestination (clang::ASTContext *dst_ctx);
+ void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
+private:
+ struct DeclOrigin
+ {
+ DeclOrigin () :
+ ctx(NULL),
+ decl(NULL)
+ {
+ }
+
+ DeclOrigin (clang::ASTContext *_ctx,
+ clang::Decl *_decl) :
+ ctx(_ctx),
+ decl(_decl)
+ {
+ }
+
+ DeclOrigin (const DeclOrigin &rhs)
+ {
+ ctx = rhs.ctx;
+ decl = rhs.decl;
+ }
+
+ void operator= (const DeclOrigin &rhs)
+ {
+ ctx = rhs.ctx;
+ decl = rhs.decl;
+ }
+
+ bool
+ Valid ()
+ {
+ return (ctx != NULL || decl != NULL);
+ }
+
+ clang::ASTContext *ctx;
+ clang::Decl *decl;
+ };
+
+ typedef std::map<const clang::Decl *, DeclOrigin> OriginMap;
+
+ class Minion : public clang::ASTImporter
+ {
+ public:
+ Minion (ClangASTImporter &master,
+ clang::ASTContext *target_ctx,
+ clang::ASTContext *source_ctx) :
+ clang::ASTImporter(*target_ctx,
+ master.m_file_manager,
+ *source_ctx,
+ master.m_file_manager,
+ true /*minimal*/),
+ m_decls_to_deport(NULL),
+ m_decls_already_deported(NULL),
+ m_master(master),
+ m_source_ctx(source_ctx)
+ {
+ }
+
+ // A call to "InitDeportWorkQueues" puts the minion into deport mode.
+ // In deport mode, every copied Decl that could require completion is
+ // recorded and placed into the decls_to_deport set.
+ //
+ // A call to "ExecuteDeportWorkQueues" completes all the Decls that
+ // are in decls_to_deport, adding any Decls it sees along the way that
+ // it hasn't already deported. It proceeds until decls_to_deport is
+ // empty.
+ //
+ // These calls must be paired. Leaving a minion in deport mode or
+ // trying to start deport minion with a new pair of queues will result
+ // in an assertion failure.
+
+ void InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport,
+ std::set<clang::NamedDecl *> *decls_already_deported);
+ void ExecuteDeportWorkQueues ();
+
+ void ImportDefinitionTo (clang::Decl *to, clang::Decl *from);
+
+ clang::Decl *Imported (clang::Decl *from, clang::Decl *to);
+
+ std::set<clang::NamedDecl *> *m_decls_to_deport;
+ std::set<clang::NamedDecl *> *m_decls_already_deported;
+ ClangASTImporter &m_master;
+ clang::ASTContext *m_source_ctx;
+ };
+
+ typedef std::shared_ptr<Minion> MinionSP;
+ typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
+ typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
+
+ struct ASTContextMetadata
+ {
+ ASTContextMetadata(clang::ASTContext *dst_ctx) :
+ m_dst_ctx (dst_ctx),
+ m_minions (),
+ m_origins (),
+ m_namespace_maps (),
+ m_map_completer (NULL)
+ {
+ }
+
+ clang::ASTContext *m_dst_ctx;
+ MinionMap m_minions;
+ OriginMap m_origins;
+
+ NamespaceMetaMap m_namespace_maps;
+ MapCompleter *m_map_completer;
+ };
+
+ typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP;
+ typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap;
+
+ ContextMetadataMap m_metadata_map;
+
+ ASTContextMetadataSP
+ GetContextMetadata (clang::ASTContext *dst_ctx)
+ {
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter == m_metadata_map.end())
+ {
+ ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
+ m_metadata_map[dst_ctx] = context_md;
+ return context_md;
+ }
+ else
+ {
+ return context_md_iter->second;
+ }
+ }
+
+ ASTContextMetadataSP
+ MaybeGetContextMetadata (clang::ASTContext *dst_ctx)
+ {
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter != m_metadata_map.end())
+ return context_md_iter->second;
+ else
+ return ASTContextMetadataSP();
+ }
+
+ MinionSP
+ GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx)
+ {
+ ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
+
+ MinionMap &minions = context_md->m_minions;
+ MinionMap::iterator minion_iter = minions.find(src_ctx);
+
+ if (minion_iter == minions.end())
+ {
+ MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
+ minions[src_ctx] = minion;
+ return minion;
+ }
+ else
+ {
+ return minion_iter->second;
+ }
+ }
+
+ DeclOrigin
+ GetDeclOrigin (const clang::Decl *decl);
+
+ clang::FileManager m_file_manager;
+};
+
+}
+
+#endif
diff --git a/include/lldb/Symbol/ClangASTType.h b/include/lldb/Symbol/ClangASTType.h
new file mode 100644
index 000000000000..d9e754e8ceb9
--- /dev/null
+++ b/include/lldb/Symbol/ClangASTType.h
@@ -0,0 +1,679 @@
+//===-- ClangASTType.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangASTType_h_
+#define liblldb_ClangASTType_h_
+
+#include <string>
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "clang/AST/Type.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A class that can carry around a clang ASTContext and a opaque clang
+// QualType. A clang::QualType can be easily reconstructed from an
+// opaque clang type and often the ASTContext is needed when doing
+// various type related tasks, so this class allows both items to travel
+// in a single very lightweight class that can be used. There are many
+// static equivalents of the member functions that allow the ASTContext
+// and the opaque clang QualType to be specified for ease of use and
+// to avoid code duplication.
+//----------------------------------------------------------------------
+class ClangASTType
+{
+public:
+ enum {
+ eTypeHasChildren = (1u << 0),
+ eTypeHasValue = (1u << 1),
+ eTypeIsArray = (1u << 2),
+ eTypeIsBlock = (1u << 3),
+ eTypeIsBuiltIn = (1u << 4),
+ eTypeIsClass = (1u << 5),
+ eTypeIsCPlusPlus = (1u << 6),
+ eTypeIsEnumeration = (1u << 7),
+ eTypeIsFuncPrototype = (1u << 8),
+ eTypeIsMember = (1u << 9),
+ eTypeIsObjC = (1u << 10),
+ eTypeIsPointer = (1u << 11),
+ eTypeIsReference = (1u << 12),
+ eTypeIsStructUnion = (1u << 13),
+ eTypeIsTemplate = (1u << 14),
+ eTypeIsTypedef = (1u << 15),
+ eTypeIsVector = (1u << 16),
+ eTypeIsScalar = (1u << 17),
+ eTypeIsInteger = (1u << 18),
+ eTypeIsFloat = (1u << 19),
+ eTypeIsComplex = (1u << 20),
+ eTypeIsSigned = (1u << 21)
+ };
+
+
+ //----------------------------------------------------------------------
+ // Constructors and Destructors
+ //----------------------------------------------------------------------
+ ClangASTType (clang::ASTContext *ast_context, lldb::clang_type_t type) :
+ m_type (type),
+ m_ast (ast_context)
+ {
+ }
+
+ ClangASTType (clang::ASTContext *ast_context, clang::QualType qual_type);
+
+ ClangASTType (const ClangASTType &rhs) :
+ m_type (rhs.m_type),
+ m_ast (rhs.m_ast)
+ {
+ }
+
+ ClangASTType () :
+ m_type (0),
+ m_ast (0)
+ {
+ }
+
+ ~ClangASTType();
+
+ //----------------------------------------------------------------------
+ // Operators
+ //----------------------------------------------------------------------
+
+ const ClangASTType &
+ operator= (const ClangASTType &rhs)
+ {
+ m_type = rhs.m_type;
+ m_ast = rhs.m_ast;
+ return *this;
+ }
+
+
+ //----------------------------------------------------------------------
+ // Tests
+ //----------------------------------------------------------------------
+
+ operator bool () const
+ {
+ return m_type != NULL && m_ast != NULL;
+ }
+
+ bool
+ operator < (const ClangASTType &rhs) const
+ {
+ if (m_ast == rhs.m_ast)
+ return m_type < rhs.m_type;
+ return m_ast < rhs.m_ast;
+ }
+
+ bool
+ IsValid () const
+ {
+ return m_type != NULL && m_ast != NULL;
+ }
+
+ bool
+ IsArrayType (ClangASTType *element_type,
+ uint64_t *size,
+ bool *is_incomplete) const;
+
+ bool
+ IsArrayOfScalarType () const;
+
+ bool
+ IsAggregateType () const;
+
+ bool
+ IsBeingDefined () const;
+
+ bool
+ IsCharType () const;
+
+ bool
+ IsCompleteType () const;
+
+ bool
+ IsConst() const;
+
+ bool
+ IsCStringType (uint32_t &length) const;
+
+ bool
+ IsCXXClassType () const;
+
+ bool
+ IsDefined() const;
+
+ bool
+ IsFloatingPointType (uint32_t &count, bool &is_complex) const;
+
+ bool
+ IsFunctionType (bool *is_variadic_ptr = NULL) const;
+
+ bool
+ IsVariadicFunctionType () const;
+
+ bool
+ IsFunctionPointerType () const;
+
+ bool
+ IsIntegerType (bool &is_signed) const;
+
+ bool
+ IsObjCClassType () const;
+
+ bool
+ IsObjCClassTypeAndHasIVars (bool check_superclass) const;
+
+ bool
+ IsObjCObjectOrInterfaceType () const;
+
+ bool
+ IsObjCObjectPointerType (ClangASTType *target_type = NULL);
+
+ bool
+ IsPolymorphicClass () const;
+
+ bool
+ IsPossibleCPlusPlusDynamicType (ClangASTType *target_type = NULL) const
+ {
+ return IsPossibleDynamicType (target_type, true, false);
+ }
+
+ bool
+ IsPossibleDynamicType (ClangASTType *target_type, // Can pass NULL
+ bool check_cplusplus,
+ bool check_objc) const;
+
+
+ bool
+ IsPointerToScalarType () const;
+
+ bool
+ IsPointerType (ClangASTType *pointee_type = NULL) const;
+
+ bool
+ IsPointerOrReferenceType (ClangASTType *pointee_type = NULL) const;
+
+ bool
+ IsReferenceType (ClangASTType *pointee_type = NULL) const;
+
+ bool
+ IsScalarType () const;
+
+ bool
+ IsTypedefType () const;
+
+ bool
+ IsVoidType () const;
+
+ bool
+ GetCXXClassName (std::string &class_name) const;
+
+ bool
+ GetObjCClassName (std::string &class_name);
+
+
+ //----------------------------------------------------------------------
+ // Type Completion
+ //----------------------------------------------------------------------
+
+ bool
+ GetCompleteType () const;
+
+ //----------------------------------------------------------------------
+ // AST related queries
+ //----------------------------------------------------------------------
+
+ size_t
+ GetPointerByteSize () const;
+
+ //----------------------------------------------------------------------
+ // Accessors
+ //----------------------------------------------------------------------
+
+ clang::ASTContext *
+ GetASTContext() const
+ {
+ return m_ast;
+ }
+
+ ConstString
+ GetConstQualifiedTypeName () const;
+
+ ConstString
+ GetConstTypeName () const;
+
+ std::string
+ GetTypeName () const;
+
+ uint32_t
+ GetTypeInfo (ClangASTType *pointee_or_element_clang_type = NULL) const;
+
+ lldb::LanguageType
+ GetMinimumLanguage ();
+
+ lldb::clang_type_t
+ GetOpaqueQualType() const
+ {
+ return m_type;
+ }
+
+ lldb::TypeClass
+ GetTypeClass () const;
+
+ void
+ SetClangType (clang::ASTContext *ast, lldb::clang_type_t type)
+ {
+ m_ast = ast;
+ m_type = type;
+ }
+
+ void
+ SetClangType (clang::ASTContext *ast, clang::QualType qual_type);
+
+ unsigned
+ GetTypeQualifiers() const;
+
+ //----------------------------------------------------------------------
+ // Creating related types
+ //----------------------------------------------------------------------
+
+ ClangASTType
+ AddConstModifier () const;
+
+ ClangASTType
+ AddRestrictModifier () const;
+
+ ClangASTType
+ AddVolatileModifier () const;
+
+ // Using the current type, create a new typedef to that type using "typedef_name"
+ // as the name and "decl_ctx" as the decl context.
+ ClangASTType
+ CreateTypedefType (const char *typedef_name,
+ clang::DeclContext *decl_ctx) const;
+
+ ClangASTType
+ GetArrayElementType (uint64_t& stride) const;
+
+ ClangASTType
+ GetCanonicalType () const;
+
+ ClangASTType
+ GetFullyUnqualifiedType () const;
+
+ // Returns -1 if this isn't a function of if the fucntion doesn't have a prototype
+ // Returns a value >= 0 if there is a prototype.
+ int
+ GetFunctionArgumentCount () const;
+
+ ClangASTType
+ GetFunctionArgumentTypeAtIndex (size_t idx);
+
+ ClangASTType
+ GetFunctionReturnType () const;
+
+ ClangASTType
+ GetLValueReferenceType () const;
+
+ ClangASTType
+ GetNonReferenceType () const;
+
+ ClangASTType
+ GetPointeeType () const;
+
+ ClangASTType
+ GetPointerType () const;
+
+ ClangASTType
+ GetRValueReferenceType () const;
+
+ // If the current object represents a typedef type, get the underlying type
+ ClangASTType
+ GetTypedefedType () const;
+
+ ClangASTType
+ RemoveFastQualifiers () const;
+
+ //----------------------------------------------------------------------
+ // Create related types using the current type's AST
+ //----------------------------------------------------------------------
+ ClangASTType
+ GetBasicTypeFromAST (lldb::BasicType basic_type) const;
+
+ //----------------------------------------------------------------------
+ // Exploring the type
+ //----------------------------------------------------------------------
+
+ uint64_t
+ GetByteSize () const;
+
+ uint64_t
+ GetBitSize () const;
+
+ lldb::Encoding
+ GetEncoding (uint64_t &count) const;
+
+ lldb::Format
+ GetFormat () const;
+
+ size_t
+ GetTypeBitAlign () const;
+
+ uint32_t
+ GetNumChildren (bool omit_empty_base_classes) const;
+
+ lldb::BasicType
+ GetBasicTypeEnumeration () const;
+
+ static lldb::BasicType
+ GetBasicTypeEnumeration (const ConstString &name);
+
+ uint32_t
+ GetNumDirectBaseClasses () const;
+
+ uint32_t
+ GetNumVirtualBaseClasses () const;
+
+ uint32_t
+ GetNumFields () const;
+
+ ClangASTType
+ GetDirectBaseClassAtIndex (size_t idx,
+ uint32_t *bit_offset_ptr) const;
+
+ ClangASTType
+ GetVirtualBaseClassAtIndex (size_t idx,
+ uint32_t *bit_offset_ptr) const;
+
+ ClangASTType
+ GetFieldAtIndex (size_t idx,
+ std::string& name,
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr) const;
+
+ uint32_t
+ GetIndexOfFieldWithName (const char* name,
+ ClangASTType* field_clang_type = NULL,
+ uint64_t *bit_offset_ptr = NULL,
+ uint32_t *bitfield_bit_size_ptr = NULL,
+ bool *is_bitfield_ptr = NULL) const;
+
+ uint32_t
+ GetNumPointeeChildren () const;
+
+ ClangASTType
+ GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
+ const char *parent_name,
+ size_t idx,
+ bool transparent_pointers,
+ bool omit_empty_base_classes,
+ bool ignore_array_bounds,
+ std::string& child_name,
+ uint32_t &child_byte_size,
+ int32_t &child_byte_offset,
+ uint32_t &child_bitfield_bit_size,
+ uint32_t &child_bitfield_bit_offset,
+ bool &child_is_base_class,
+ bool &child_is_deref_of_parent) const;
+
+ // Lookup a child given a name. This function will match base class names
+ // and member member names in "clang_type" only, not descendants.
+ uint32_t
+ GetIndexOfChildWithName (const char *name,
+ bool omit_empty_base_classes) const;
+
+ // Lookup a child member given a name. This function will match member names
+ // only and will descend into "clang_type" children in search for the first
+ // member in this class, or any base class that matches "name".
+ // TODO: Return all matches for a given name by returning a vector<vector<uint32_t>>
+ // so we catch all names that match a given child name, not just the first.
+ size_t
+ GetIndexOfChildMemberWithName (const char *name,
+ bool omit_empty_base_classes,
+ std::vector<uint32_t>& child_indexes) const;
+
+ size_t
+ GetNumTemplateArguments () const;
+
+ ClangASTType
+ GetTemplateArgument (size_t idx,
+ lldb::TemplateArgumentKind &kind) const;
+
+
+ //----------------------------------------------------------------------
+ // Modifying RecordType
+ //----------------------------------------------------------------------
+ clang::FieldDecl *
+ AddFieldToRecordType (const char *name,
+ const ClangASTType &field_type,
+ lldb::AccessType access,
+ uint32_t bitfield_bit_size);
+
+ void
+ BuildIndirectFields ();
+
+ clang::VarDecl *
+ AddVariableToRecordType (const char *name,
+ const ClangASTType &var_type,
+ lldb::AccessType access);
+
+ clang::CXXMethodDecl *
+ AddMethodToCXXRecordType (const char *name,
+ const ClangASTType &method_type,
+ lldb::AccessType access,
+ bool is_virtual,
+ bool is_static,
+ bool is_inline,
+ bool is_explicit,
+ bool is_attr_used,
+ bool is_artificial);
+
+ // C++ Base Classes
+ clang::CXXBaseSpecifier *
+ CreateBaseClassSpecifier (lldb::AccessType access,
+ bool is_virtual,
+ bool base_of_class);
+
+ static void
+ DeleteBaseClassSpecifiers (clang::CXXBaseSpecifier **base_classes,
+ unsigned num_base_classes);
+
+ bool
+ SetBaseClassesForClassType (clang::CXXBaseSpecifier const * const *base_classes,
+ unsigned num_base_classes);
+
+
+ bool
+ SetObjCSuperClass (const ClangASTType &superclass_clang_type);
+
+ bool
+ AddObjCClassProperty (const char *property_name,
+ const ClangASTType &property_clang_type,
+ clang::ObjCIvarDecl *ivar_decl,
+ const char *property_setter_name,
+ const char *property_getter_name,
+ uint32_t property_attributes,
+ ClangASTMetadata *metadata);
+
+ clang::ObjCMethodDecl *
+ AddMethodToObjCObjectType (const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
+ const ClangASTType &method_clang_type,
+ lldb::AccessType access,
+ bool is_artificial);
+
+ clang::DeclContext *
+ GetDeclContextForType () const;
+
+
+ bool
+ SetDefaultAccessForRecordFields (int default_accessibility,
+ int *assigned_accessibilities,
+ size_t num_assigned_accessibilities);
+
+ bool
+ SetHasExternalStorage (bool has_extern);
+
+
+ //------------------------------------------------------------------
+ // clang::TagType
+ //------------------------------------------------------------------
+
+ bool
+ SetTagTypeKind (int kind) const;
+
+ //------------------------------------------------------------------
+ // Tag Declarations
+ //------------------------------------------------------------------
+ bool
+ StartTagDeclarationDefinition ();
+
+ bool
+ CompleteTagDeclarationDefinition ();
+
+ //----------------------------------------------------------------------
+ // Modifying Enumeration types
+ //----------------------------------------------------------------------
+ bool
+ AddEnumerationValueToEnumerationType (const ClangASTType &enumerator_qual_type,
+ const Declaration &decl,
+ const char *name,
+ int64_t enum_value,
+ uint32_t enum_value_bit_size);
+
+
+
+ ClangASTType
+ GetEnumerationIntegerType () const;
+
+
+ //------------------------------------------------------------------
+ // Pointers & References
+ //------------------------------------------------------------------
+
+ // Call this function using the class type when you want to make a
+ // member pointer type to pointee_type.
+ ClangASTType
+ CreateMemberPointerType (const ClangASTType &pointee_type) const;
+
+
+ // Converts "s" to a floating point value and place resulting floating
+ // point bytes in the "dst" buffer.
+ size_t
+ ConvertStringToFloatValue (const char *s,
+ uint8_t *dst,
+ size_t dst_size) const;
+ //----------------------------------------------------------------------
+ // Dumping types
+ //----------------------------------------------------------------------
+ void
+ DumpValue (ExecutionContext *exe_ctx,
+ Stream *s,
+ lldb::Format format,
+ const DataExtractor &data,
+ lldb::offset_t data_offset,
+ size_t data_byte_size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset,
+ bool show_types,
+ bool show_summary,
+ bool verbose,
+ uint32_t depth);
+
+ bool
+ DumpTypeValue (Stream *s,
+ lldb::Format format,
+ const DataExtractor &data,
+ lldb::offset_t data_offset,
+ size_t data_byte_size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset,
+ ExecutionContextScope *exe_scope);
+
+ void
+ DumpSummary (ExecutionContext *exe_ctx,
+ Stream *s,
+ const DataExtractor &data,
+ lldb::offset_t data_offset,
+ size_t data_byte_size);
+
+ void
+ DumpTypeDescription () const; // Dump to stdout
+
+ void
+ DumpTypeDescription (Stream *s) const;
+
+ bool
+ GetValueAsScalar (const DataExtractor &data,
+ lldb::offset_t data_offset,
+ size_t data_byte_size,
+ Scalar &value) const;
+
+ bool
+ SetValueFromScalar (const Scalar &value,
+ Stream &strm);
+
+ bool
+ ReadFromMemory (ExecutionContext *exe_ctx,
+ lldb::addr_t addr,
+ AddressType address_type,
+ DataExtractor &data);
+
+ bool
+ WriteToMemory (ExecutionContext *exe_ctx,
+ lldb::addr_t addr,
+ AddressType address_type,
+ StreamString &new_value);
+
+
+ clang::RecordDecl *
+ GetAsRecordDecl () const;
+
+ clang::CXXRecordDecl *
+ GetAsCXXRecordDecl () const;
+
+ clang::ObjCInterfaceDecl *
+ GetAsObjCInterfaceDecl () const;
+
+ void
+ Clear()
+ {
+ m_type = NULL;
+ m_ast = NULL;
+ }
+
+ clang::QualType
+ GetQualType () const
+ {
+ if (m_type)
+ return clang::QualType::getFromOpaquePtr(m_type);
+ return clang::QualType();
+ }
+ clang::QualType
+ GetCanonicalQualType () const
+ {
+ if (m_type)
+ return clang::QualType::getFromOpaquePtr(m_type).getCanonicalType();
+ return clang::QualType();
+ }
+
+private:
+ lldb::clang_type_t m_type;
+ clang::ASTContext *m_ast;
+
+};
+
+bool operator == (const ClangASTType &lhs, const ClangASTType &rhs);
+bool operator != (const ClangASTType &lhs, const ClangASTType &rhs);
+
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_ClangASTType_h_
diff --git a/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h b/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h
new file mode 100644
index 000000000000..0c8121135ef0
--- /dev/null
+++ b/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h
@@ -0,0 +1,171 @@
+//===-- ClangExternalASTSourceCallbacks.h -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangExternalASTSourceCallbacks_h_
+#define liblldb_ClangExternalASTSourceCallbacks_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <vector>
+#include <stdint.h>
+
+// Other libraries and framework includes
+#include "clang/AST/CharUnits.h"
+
+// Project includes
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+
+namespace lldb_private {
+
+class ClangExternalASTSourceCallbacks : public ClangExternalASTSourceCommon
+{
+public:
+
+ typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *);
+ typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *);
+ typedef void (*FindExternalVisibleDeclsByNameCallback)(void *baton, const clang::DeclContext *DC, clang::DeclarationName Name, llvm::SmallVectorImpl <clang::NamedDecl *> *results);
+ typedef bool (*LayoutRecordTypeCallback)(void *baton,
+ const clang::RecordDecl *Record,
+ uint64_t &Size,
+ uint64_t &Alignment,
+ llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets);
+
+ ClangExternalASTSourceCallbacks (CompleteTagDeclCallback tag_decl_callback,
+ CompleteObjCInterfaceDeclCallback objc_decl_callback,
+ FindExternalVisibleDeclsByNameCallback find_by_name_callback,
+ LayoutRecordTypeCallback layout_record_type_callback,
+ void *callback_baton) :
+ m_callback_tag_decl (tag_decl_callback),
+ m_callback_objc_decl (objc_decl_callback),
+ m_callback_find_by_name (find_by_name_callback),
+ m_callback_layout_record_type (layout_record_type_callback),
+ m_callback_baton (callback_baton)
+ {
+ }
+
+ //------------------------------------------------------------------
+ // clang::ExternalASTSource
+ //------------------------------------------------------------------
+
+ virtual clang::Decl *
+ GetExternalDecl (uint32_t ID)
+ {
+ // This method only needs to be implemented if the AST source ever
+ // passes back decl sets as VisibleDeclaration objects.
+ return 0;
+ }
+
+ virtual clang::Stmt *
+ GetExternalDeclStmt (uint64_t Offset)
+ {
+ // This operation is meant to be used via a LazyOffsetPtr. It only
+ // needs to be implemented if the AST source uses methods like
+ // FunctionDecl::setLazyBody when building decls.
+ return 0;
+ }
+
+ virtual clang::Selector
+ GetExternalSelector (uint32_t ID)
+ {
+ // This operation only needs to be implemented if the AST source
+ // returns non-zero for GetNumKnownSelectors().
+ return clang::Selector();
+ }
+
+ virtual uint32_t
+ GetNumExternalSelectors()
+ {
+ return 0;
+ }
+
+ virtual clang::CXXBaseSpecifier *
+ GetExternalCXXBaseSpecifiers(uint64_t Offset)
+ {
+ return NULL;
+ }
+
+ virtual void
+ MaterializeVisibleDecls (const clang::DeclContext *decl_ctx)
+ {
+ return;
+ }
+
+ virtual clang::ExternalLoadResult
+ FindExternalLexicalDecls (const clang::DeclContext *decl_ctx,
+ bool (*isKindWeWant)(clang::Decl::Kind),
+ llvm::SmallVectorImpl<clang::Decl*> &decls)
+ {
+ // This is used to support iterating through an entire lexical context,
+ // which isn't something the debugger should ever need to do.
+ return clang::ELR_Failure;
+ }
+
+ virtual bool
+ FindExternalVisibleDeclsByName (const clang::DeclContext *decl_ctx,
+ clang::DeclarationName decl_name);
+
+ virtual void
+ CompleteType (clang::TagDecl *tag_decl);
+
+ virtual void
+ CompleteType (clang::ObjCInterfaceDecl *objc_decl);
+
+ bool
+ layoutRecordType(const clang::RecordDecl *Record,
+ uint64_t &Size,
+ uint64_t &Alignment,
+ llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets);
+ void
+ SetExternalSourceCallbacks (CompleteTagDeclCallback tag_decl_callback,
+ CompleteObjCInterfaceDeclCallback objc_decl_callback,
+ FindExternalVisibleDeclsByNameCallback find_by_name_callback,
+ LayoutRecordTypeCallback layout_record_type_callback,
+ void *callback_baton)
+ {
+ m_callback_tag_decl = tag_decl_callback;
+ m_callback_objc_decl = objc_decl_callback;
+ m_callback_find_by_name = find_by_name_callback;
+ m_callback_layout_record_type = layout_record_type_callback;
+ m_callback_baton = callback_baton;
+ }
+
+ void
+ RemoveExternalSourceCallbacks (void *callback_baton)
+ {
+ if (callback_baton == m_callback_baton)
+ {
+ m_callback_tag_decl = NULL;
+ m_callback_objc_decl = NULL;
+ m_callback_find_by_name = NULL;
+ m_callback_layout_record_type = NULL;
+ }
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from ClangExternalASTSourceCallbacks can see and modify these
+ //------------------------------------------------------------------
+ CompleteTagDeclCallback m_callback_tag_decl;
+ CompleteObjCInterfaceDeclCallback m_callback_objc_decl;
+ FindExternalVisibleDeclsByNameCallback m_callback_find_by_name;
+ LayoutRecordTypeCallback m_callback_layout_record_type;
+ void * m_callback_baton;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangExternalASTSourceCallbacks_h_
diff --git a/include/lldb/Symbol/ClangExternalASTSourceCommon.h b/include/lldb/Symbol/ClangExternalASTSourceCommon.h
new file mode 100644
index 000000000000..72d77e74ca90
--- /dev/null
+++ b/include/lldb/Symbol/ClangExternalASTSourceCommon.h
@@ -0,0 +1,188 @@
+//===-- ClangExternalASTSourceCommon.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangExternalASTSourceCommon_h
+#define liblldb_ClangExternalASTSourceCommon_h
+
+// Clang headers like to use NDEBUG inside of them to enable/disable debug
+// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing
+// or another. This is bad because it means that if clang was built in release
+// mode, it assumes that you are building in release mode which is not always
+// the case. You can end up with functions that are defined as empty in header
+// files when NDEBUG is not defined, and this can cause link errors with the
+// clang .a files that you have since you might be missing functions in the .a
+// file. So we have to define NDEBUG when including clang headers to avoid any
+// mismatches. This is covered by rdar://problem/8691220
+
+#if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF)
+#define LLDB_DEFINED_NDEBUG_FOR_CLANG
+#define NDEBUG
+// Need to include assert.h so it is as clang would expect it to be (disabled)
+#include <assert.h>
+#endif
+
+#include "clang/AST/ExternalASTSource.h"
+
+#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
+#undef NDEBUG
+#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
+// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
+#include <assert.h>
+#endif
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/dwarf.h"
+
+namespace lldb_private {
+
+class ClangASTMetadata
+{
+public:
+ ClangASTMetadata () :
+ m_user_id(0),
+ m_union_is_user_id(false),
+ m_union_is_isa_ptr(false),
+ m_has_object_ptr(false),
+ m_is_self (false),
+ m_is_dynamic_cxx (true)
+ {
+ }
+
+ bool
+ GetIsDynamicCXXType () const
+ {
+ return m_is_dynamic_cxx;
+ }
+
+ void
+ SetIsDynamicCXXType (bool b)
+ {
+ m_is_dynamic_cxx = b;
+ }
+
+ void
+ SetUserID (lldb::user_id_t user_id)
+ {
+ m_user_id = user_id;
+ m_union_is_user_id = true;
+ m_union_is_isa_ptr = false;
+ }
+
+ lldb::user_id_t
+ GetUserID () const
+ {
+ if (m_union_is_user_id)
+ return m_user_id;
+ else
+ return LLDB_INVALID_UID;
+ }
+
+ void
+ SetISAPtr (uint64_t isa_ptr)
+ {
+ m_isa_ptr = isa_ptr;
+ m_union_is_user_id = false;
+ m_union_is_isa_ptr = true;
+ }
+
+ uint64_t
+ GetISAPtr () const
+ {
+ if (m_union_is_isa_ptr)
+ return m_isa_ptr;
+ else
+ return 0;
+ }
+
+ void
+ SetObjectPtrName(const char *name)
+ {
+ m_has_object_ptr = true;
+ if (strcmp (name, "self") == 0)
+ m_is_self = true;
+ else if (strcmp (name, "this") == 0)
+ m_is_self = false;
+ else
+ m_has_object_ptr = false;
+ }
+
+ lldb::LanguageType
+ GetObjectPtrLanguage () const
+ {
+ if (m_has_object_ptr)
+ {
+ if (m_is_self)
+ return lldb::eLanguageTypeObjC;
+ else
+ return lldb::eLanguageTypeC_plus_plus;
+ }
+ return lldb::eLanguageTypeUnknown;
+
+ }
+ const char *
+ GetObjectPtrName() const
+ {
+ if (m_has_object_ptr)
+ {
+ if (m_is_self)
+ return "self";
+ else
+ return "this";
+ }
+ else
+ return NULL;
+ }
+
+ bool
+ HasObjectPtr() const
+ {
+ return m_has_object_ptr;
+ }
+
+ void
+ Dump (Stream *s);
+
+private:
+ union
+ {
+ lldb::user_id_t m_user_id;
+ uint64_t m_isa_ptr;
+ };
+ bool m_union_is_user_id : 1,
+ m_union_is_isa_ptr : 1,
+ m_has_object_ptr : 1,
+ m_is_self : 1,
+ m_is_dynamic_cxx : 1;
+
+};
+
+class ClangExternalASTSourceCommon : public clang::ExternalASTSource
+{
+public:
+ ClangExternalASTSourceCommon();
+ ~ClangExternalASTSourceCommon();
+
+ virtual ClangASTMetadata *GetMetadata(const void *object);
+ virtual void SetMetadata(const void *object, ClangASTMetadata &metadata);
+ virtual bool HasMetadata(const void *object);
+private:
+ typedef llvm::DenseMap<const void *, ClangASTMetadata> MetadataMap;
+
+ MetadataMap m_metadata;
+ uint64_t m_magic; ///< Because we don't have RTTI, we must take it
+ ///< on faith that any valid ExternalASTSource that
+ ///< we try to use the *Metadata APIs on inherits
+ ///< from ClangExternalASTSourceCommon. This magic
+ ///< number exists to enforce that.
+};
+
+}
+
+#endif
diff --git a/include/lldb/Symbol/ClangNamespaceDecl.h b/include/lldb/Symbol/ClangNamespaceDecl.h
new file mode 100644
index 000000000000..d10ab2a29665
--- /dev/null
+++ b/include/lldb/Symbol/ClangNamespaceDecl.h
@@ -0,0 +1,103 @@
+//===-- ClangNamespaceDecl.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangNamespaceDecl_h_
+#define liblldb_ClangNamespaceDecl_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ClangForward.h"
+
+namespace lldb_private {
+
+class ClangNamespaceDecl
+{
+public:
+ ClangNamespaceDecl () :
+ m_ast (NULL),
+ m_namespace_decl (NULL)
+ {
+ }
+
+ ClangNamespaceDecl (clang::ASTContext *ast, clang::NamespaceDecl *namespace_decl) :
+ m_ast (ast),
+ m_namespace_decl (namespace_decl)
+ {
+ }
+
+ ClangNamespaceDecl (const ClangNamespaceDecl &rhs) :
+ m_ast (rhs.m_ast),
+ m_namespace_decl (rhs.m_namespace_decl)
+ {
+ }
+
+ const ClangNamespaceDecl &
+ operator = (const ClangNamespaceDecl &rhs)
+ {
+ m_ast = rhs.m_ast;
+ m_namespace_decl = rhs.m_namespace_decl;
+ return *this;
+ }
+
+ //------------------------------------------------------------------
+ /// Convert to bool operator.
+ ///
+ /// This allows code to check a ClangNamespaceDecl object to see if
+ /// it contains a valid namespace decl using code such as:
+ ///
+ /// @code
+ /// ClangNamespaceDecl ns_decl(...);
+ /// if (ns_decl)
+ /// { ...
+ /// @endcode
+ ///
+ /// @return
+ /// /b True this object contains a valid namespace decl, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ operator bool() const
+ {
+ return m_ast != NULL && m_namespace_decl != NULL;
+ }
+
+ clang::ASTContext *
+ GetASTContext() const
+ {
+ return m_ast;
+ }
+
+ void
+ SetASTContext (clang::ASTContext *ast)
+ {
+ m_ast = ast;
+ }
+
+ clang::NamespaceDecl *
+ GetNamespaceDecl () const
+ {
+ return m_namespace_decl;
+ }
+
+ void
+ SetNamespaceDecl (clang::NamespaceDecl *namespace_decl)
+ {
+ m_namespace_decl = namespace_decl;
+ }
+
+ std::string
+ GetQualifiedName () const;
+
+protected:
+ clang::ASTContext *m_ast;
+ clang::NamespaceDecl *m_namespace_decl;
+};
+
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_ClangNamespaceDecl_h_
diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h
new file mode 100644
index 000000000000..5de93670c5a7
--- /dev/null
+++ b/include/lldb/Symbol/CompileUnit.h
@@ -0,0 +1,422 @@
+//===-- CompileUnit.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CompUnit_h_
+#define liblldb_CompUnit_h_
+
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/UserID.h"
+
+namespace lldb_private {
+//----------------------------------------------------------------------
+/// @class CompileUnit CompileUnit.h "lldb/Symbol/CompileUnit.h"
+/// @brief A class that describes a compilation unit.
+///
+/// A representation of a compilation unit, or compiled source file.
+/// The UserID of the compile unit is specified by the SymbolFile
+/// plug-in and can have any value as long as the value is unique
+/// within the Module that owns this compile units.
+///
+/// Each compile unit has a list of functions, global and static
+/// variables, support file list (include files and inlined source
+/// files), and a line table.
+//----------------------------------------------------------------------
+class CompileUnit :
+ public std::enable_shared_from_this<CompileUnit>,
+ public ModuleChild,
+ public FileSpec,
+ public UserID,
+ public SymbolContextScope
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with a module, path, UID and language.
+ ///
+ /// Initialize the compile unit given the owning \a module, a path
+ /// to convert into a FileSpec, the SymbolFile plug-in supplied
+ /// \a uid, and the source language type.
+ ///
+ /// @param[in] module
+ /// The parent module that owns this compile unit. This value
+ /// must be a valid pointer value.
+ ///
+ /// @param[in] user_data
+ /// User data where the SymbolFile parser can store data.
+ ///
+ /// @param[in] pathname
+ /// The path to the source file for this compile unit.
+ ///
+ /// @param[in] uid
+ /// The user ID of the compile unit. This value is supplied by
+ /// the SymbolFile plug-in and should be a value that allows
+ /// the SymbolFile plug-in to easily locate and parse additional
+ /// information for the compile unit.
+ ///
+ /// @param[in] language
+ /// A language enumeration type that describes the main language
+ /// of this compile unit.
+ ///
+ /// @see lldb::LanguageType
+ //------------------------------------------------------------------
+ CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, lldb::user_id_t uid, lldb::LanguageType language);
+
+ //------------------------------------------------------------------
+ /// Construct with a module, file spec, UID and language.
+ ///
+ /// Initialize the compile unit given the owning \a module, a path
+ /// to convert into a FileSpec, the SymbolFile plug-in supplied
+ /// \a uid, and the source language type.
+ ///
+ /// @param[in] module
+ /// The parent module that owns this compile unit. This value
+ /// must be a valid pointer value.
+ ///
+ /// @param[in] user_data
+ /// User data where the SymbolFile parser can store data.
+ ///
+ /// @param[in] file_spec
+ /// The file specification for the source file of this compile
+ /// unit.
+ ///
+ /// @param[in] uid
+ /// The user ID of the compile unit. This value is supplied by
+ /// the SymbolFile plug-in and should be a value that allows
+ /// the plug-in to easily locate and parse
+ /// additional information for the compile unit.
+ ///
+ /// @param[in] language
+ /// A language enumeration type that describes the main language
+ /// of this compile unit.
+ ///
+ /// @see lldb::LanguageType
+ //------------------------------------------------------------------
+ CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, lldb::LanguageType language);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual
+ ~CompileUnit();
+
+ //------------------------------------------------------------------
+ /// Add a function to this compile unit.
+ ///
+ /// Typically called by the SymbolFile plug-ins as they partially
+ /// parse the debug information.
+ ///
+ /// @param[in] function_sp
+ /// A shared pointer to the a Function object.
+ //------------------------------------------------------------------
+ void
+ AddFunction(lldb::FunctionSP& function_sp);
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext(SymbolContext* sc);
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ();
+
+ virtual CompileUnit *
+ CalculateSymbolContextCompileUnit ();
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext(Stream *s);
+
+ lldb::LanguageType
+ GetLanguage();
+
+ void
+ SetLanguage(lldb::LanguageType language)
+ {
+ m_flags.Set(flagsParsedLanguage);
+ m_language = language;
+ }
+
+ void
+ GetDescription(Stream *s, lldb::DescriptionLevel level) const;
+
+ //------------------------------------------------------------------
+ /// Get a shared pointer to a function in this compile unit by
+ /// index.
+ ///
+ /// Typically called when iterating though all functions in a
+ /// compile unit after all functions have been parsed. This provides
+ /// raw access to the function shared pointer list and will not
+ /// cause the SymbolFile plug-in to parse any unparsed functions.
+ ///
+ /// @param[in] idx
+ /// An index into the function list.
+ ///
+ /// @return
+ /// A shared pointer to a function that might contain a NULL
+ /// Function class pointer.
+ //------------------------------------------------------------------
+ lldb::FunctionSP
+ GetFunctionAtIndex (size_t idx);
+
+ //------------------------------------------------------------------
+ /// Dump the compile unit contents to the stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] show_context
+ /// If \b true, variables will dump their symbol context
+ /// information.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, bool show_context) const;
+
+ //------------------------------------------------------------------
+ /// Find the line entry by line and optional inlined file spec.
+ ///
+ /// Finds the first line entry that has an index greater than
+ /// \a start_idx that matches \a line. If \a file_spec_ptr
+ /// is NULL, then the search matches line entries whose file matches
+ /// the file for the compile unit. If \a file_spec_ptr is
+ /// not NULL, line entries must match the specified file spec (for
+ /// inlined line table entries).
+ ///
+ /// Multiple calls to this function can find all entries that match
+ /// a given file and line by starting with \a start_idx equal to zero,
+ /// and calling this function back with the return valeu + 1.
+ ///
+ /// @param[in] start_idx
+ /// The zero based index at which to start looking for matches.
+ ///
+ /// @param[in] line
+ /// The line number to search for.
+ ///
+ /// @param[in] file_spec_ptr
+ /// If non-NULL search for entries that match this file spec,
+ /// else if NULL, search for line entries that match the compile
+ /// unit file.
+ ///
+ /// @param[in] exact
+ /// If \btrue match only if there is a line table entry for this line number.
+ /// If \bfalse, find the line table entry equal to or after this line number.
+ ///
+ /// @param[out] line_entry
+ /// If non-NULL, a copy of the line entry that was found.
+ ///
+ /// @return
+ /// The zero based index of a matching line entry, or UINT32_MAX
+ /// if no matching line entry is found.
+ //------------------------------------------------------------------
+ uint32_t
+ FindLineEntry (uint32_t start_idx,
+ uint32_t line,
+ const FileSpec* file_spec_ptr,
+ bool exact,
+ LineEntry *line_entry);
+
+ //------------------------------------------------------------------
+ /// Get the line table for the compile unit.
+ ///
+ /// Called by clients and the SymbolFile plug-in. The SymbolFile
+ /// plug-ins use this function to determine if the line table has
+ /// be parsed yet. Clients use this function to get the line table
+ /// from a compile unit.
+ ///
+ /// @return
+ /// The line table object pointer, or NULL if this line table
+ /// hasn't been parsed yet.
+ //------------------------------------------------------------------
+ LineTable*
+ GetLineTable ();
+
+ //------------------------------------------------------------------
+ /// Get the compile unit's support file list.
+ ///
+ /// The support file list is used by the line table, and any objects
+ /// that have valid Declaration objects.
+ ///
+ /// @return
+ /// A support file list object.
+ //------------------------------------------------------------------
+ FileSpecList&
+ GetSupportFiles ();
+
+ //------------------------------------------------------------------
+ /// Get the SymbolFile plug-in user data.
+ ///
+ /// SymbolFile plug-ins can store user data to internal state or
+ /// objects to quickly allow them to parse more information for a
+ /// given object.
+ ///
+ /// @return
+ /// The user data stored with the CompileUnit when it was
+ /// constructed.
+ //------------------------------------------------------------------
+ void *
+ GetUserData () const;
+
+ //------------------------------------------------------------------
+ /// Get the variable list for a compile unit.
+ ///
+ /// Called by clients to get the variable list for a compile unit.
+ /// The variable list will contain all global and static variables
+ /// that were defined at the compile unit level.
+ ///
+ /// @param[in] can_create
+ /// If \b true, the variable list will be parsed on demand. If
+ /// \b false, the current variable list will be returned even
+ /// if it contains a NULL VariableList object (typically
+ /// called by dumping routines that want to display only what
+ /// has currently been parsed).
+ ///
+ /// @return
+ /// A shared pointer to a variable list, that can contain NULL
+ /// VariableList pointer if there are no global or static
+ /// variables.
+ //------------------------------------------------------------------
+ lldb::VariableListSP
+ GetVariableList (bool can_create);
+
+ //------------------------------------------------------------------
+ /// Finds a function by user ID.
+ ///
+ /// Typically used by SymbolFile plug-ins when partially parsing
+ /// the debug information to see if the function has been parsed
+ /// yet.
+ ///
+ /// @param[in] uid
+ /// The user ID of the function to find. This value is supplied
+ /// by the SymbolFile plug-in and should be a value that
+ /// allows the plug-in to easily locate and parse additional
+ /// information in the function.
+ ///
+ /// @return
+ /// A shared pointer to the function object that might contain
+ /// a NULL Function pointer.
+ //------------------------------------------------------------------
+ lldb::FunctionSP
+ FindFunctionByUID (lldb::user_id_t uid);
+
+ //------------------------------------------------------------------
+ /// Set the line table for the compile unit.
+ ///
+ /// Called by the SymbolFile plug-in when if first parses the line
+ /// table and hands ownership of the line table to this object. The
+ /// compile unit owns the line table object and will delete the
+ /// object when it is deleted.
+ ///
+ /// @param[in] line_table
+ /// A line table object pointer that this object now owns.
+ //------------------------------------------------------------------
+ void
+ SetLineTable(LineTable* line_table);
+
+ //------------------------------------------------------------------
+ /// Set accessor for the variable list.
+ ///
+ /// Called by the SymbolFile plug-ins after they have parsed the
+ /// variable lists and are ready to hand ownership of the list over
+ /// to this object.
+ ///
+ /// @param[in] variable_list_sp
+ /// A shared pointer to a VariableList.
+ //------------------------------------------------------------------
+ void
+ SetVariableList (lldb::VariableListSP& variable_list_sp);
+
+ //------------------------------------------------------------------
+ /// Resolve symbol contexts by file and line.
+ ///
+ /// Given a file in \a file_spec, and a line number, find all
+ /// instances and append them to the supplied symbol context list
+ /// \a sc_list.
+ ///
+ /// @param[in] file_spec
+ /// A file specification. If \a file_spec contains no directory
+ /// information, only the basename will be used when matching
+ /// contexts. If the directory in \a file_spec is valid, a
+ /// complete file specification match will be performed.
+ ///
+ /// @param[in] line
+ /// The line number to match against the compile unit's line
+ /// tables.
+ ///
+ /// @param[in] check_inlines
+ /// If \b true this function will also match any inline
+ /// file and line matches. If \b false, the compile unit's
+ /// file specification must match \a file_spec for any matches
+ /// to be returned.
+ ///
+ /// @param[in] exact
+ /// If true, only resolve the context if \a line exists in the line table.
+ /// If false, resolve the context to the closest line greater than \a line
+ /// in the line table.
+ ///
+ /// @param[in] resolve_scope
+ /// For each matching line entry, this bitfield indicates what
+ /// values within each SymbolContext that gets added to \a
+ /// sc_list will be resolved. See the SymbolContext::Scope
+ /// enumeration for a list of all available bits that can be
+ /// resolved. Only SymbolContext entries that can be resolved
+ /// using a LineEntry base address will be able to be resolved.
+ ///
+ /// @param[out] sc_list
+ /// A SymbolContext list class that willl get any matching
+ /// entries appended to.
+ ///
+ /// @return
+ /// The number of new matches that were added to \a sc_list.
+ ///
+ /// @see enum SymbolContext::Scope
+ //------------------------------------------------------------------
+ uint32_t
+ ResolveSymbolContext (const FileSpec& file_spec,
+ uint32_t line,
+ bool check_inlines,
+ bool exact,
+ uint32_t resolve_scope,
+ SymbolContextList &sc_list);
+
+
+protected:
+ void *m_user_data; ///< User data for the SymbolFile parser to store information into.
+ lldb::LanguageType m_language; ///< The programming language enumeration value.
+ Flags m_flags; ///< Compile unit flags that help with partial parsing.
+ std::vector<lldb::FunctionSP> m_functions; ///< The sparsely populated list of shared pointers to functions
+ ///< that gets populated as functions get partially parsed.
+ FileSpecList m_support_files; ///< Files associated with this compile unit's line table and declarations.
+ std::unique_ptr<LineTable> m_line_table_ap; ///< Line table that will get parsed on demand.
+ lldb::VariableListSP m_variables; ///< Global and static variable list that will get parsed on demand.
+
+private:
+ enum
+ {
+ flagsParsedAllFunctions = (1u << 0), ///< Have we already parsed all our functions
+ flagsParsedVariables = (1u << 1), ///< Have we already parsed globals and statics?
+ flagsParsedSupportFiles = (1u << 2), ///< Have we already parsed the support files for this compile unit?
+ flagsParsedLineTable = (1u << 3), ///< Have we parsed the line table already?
+ flagsParsedLanguage = (1u << 4) ///< Have we parsed the line table already?
+ };
+
+ DISALLOW_COPY_AND_ASSIGN (CompileUnit);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CompUnit_h_
diff --git a/include/lldb/Symbol/DWARFCallFrameInfo.h b/include/lldb/Symbol/DWARFCallFrameInfo.h
new file mode 100644
index 000000000000..13a14f8c4041
--- /dev/null
+++ b/include/lldb/Symbol/DWARFCallFrameInfo.h
@@ -0,0 +1,150 @@
+//===-- DWARFCallFrameInfo.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFCallFrameInfo_h_
+#define liblldb_DWARFCallFrameInfo_h_
+
+#include <map>
+
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Core/VMRange.h"
+#include "lldb/Core/dwarf.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// DWARFCallFrameInfo is a class which can read eh_frame and DWARF
+// Call Frame Information FDEs. It stores little information internally.
+// Only two APIs are exported - one to find the high/low pc values
+// of a function given a text address via the information in the
+// eh_frame / debug_frame, and one to generate an UnwindPlan based
+// on the FDE in the eh_frame / debug_frame section.
+
+class DWARFCallFrameInfo
+{
+public:
+
+ DWARFCallFrameInfo (ObjectFile& objfile,
+ lldb::SectionSP& section,
+ lldb::RegisterKind reg_kind,
+ bool is_eh_frame);
+
+ ~DWARFCallFrameInfo();
+
+ // Locate an AddressRange that includes the provided Address in this
+ // object's eh_frame/debug_info
+ // Returns true if a range is found to cover that address.
+ bool
+ GetAddressRange (Address addr, AddressRange &range);
+
+ // Return an UnwindPlan based on the call frame information encoded
+ // in the FDE of this DWARFCallFrameInfo section.
+ bool
+ GetUnwindPlan (Address addr, UnwindPlan& unwind_plan);
+
+ typedef RangeVector<lldb::addr_t, uint32_t> FunctionAddressAndSizeVector;
+
+ //------------------------------------------------------------------
+ // Build a vector of file address and size for all functions in this Module
+ // based on the eh_frame FDE entries.
+ //
+ // The eh_frame information can be a useful source of file address and size of
+ // the functions in a Module. Often a binary's non-exported symbols are stripped
+ // before shipping so lldb won't know the start addr / size of many functions
+ // in the Module. But the eh_frame can help to give the addresses of these
+ // stripped symbols, at least.
+ //
+ // @param[out] function_info
+ // A vector provided by the caller is filled out. May be empty if no FDEs/no eh_frame
+ // is present in this Module.
+
+ void
+ GetFunctionAddressAndSizeVector (FunctionAddressAndSizeVector &function_info);
+
+private:
+ enum
+ {
+ CFI_AUG_MAX_SIZE = 8,
+ CFI_HEADER_SIZE = 8
+ };
+
+ struct CIE
+ {
+ dw_offset_t cie_offset;
+ uint8_t version;
+ char augmentation[CFI_AUG_MAX_SIZE]; // This is typically empty or very short.
+ uint32_t code_align;
+ int32_t data_align;
+ uint32_t return_addr_reg_num;
+ dw_offset_t inst_offset; // offset of CIE instructions in mCFIData
+ uint32_t inst_length; // length of CIE instructions in mCFIData
+ uint8_t ptr_encoding;
+ lldb_private::UnwindPlan::Row initial_row;
+
+ CIE(dw_offset_t offset) : cie_offset(offset), version (-1), code_align (0),
+ data_align (0), return_addr_reg_num (LLDB_INVALID_REGNUM), inst_offset (0),
+ inst_length (0), ptr_encoding (0), initial_row() {}
+ };
+
+ typedef std::shared_ptr<CIE> CIESP;
+
+ typedef std::map<off_t, CIESP> cie_map_t;
+
+ // Start address (file address), size, offset of FDE location
+ // used for finding an FDE for a given File address; the start address field is
+ // an offset into an individual Module.
+ typedef RangeDataVector<lldb::addr_t, uint32_t, dw_offset_t> FDEEntryMap;
+
+ bool
+ IsEHFrame() const;
+
+ bool
+ GetFDEEntryByFileAddress (lldb::addr_t file_offset, FDEEntryMap::Entry& fde_entry);
+
+ void
+ GetFDEIndex ();
+
+ bool
+ FDEToUnwindPlan (uint32_t offset, Address startaddr, UnwindPlan& unwind_plan);
+
+ const CIE*
+ GetCIE(dw_offset_t cie_offset);
+
+ void
+ GetCFIData();
+
+ ObjectFile& m_objfile;
+ lldb::SectionSP m_section_sp;
+ lldb::RegisterKind m_reg_kind;
+ Flags m_flags;
+ cie_map_t m_cie_map;
+
+ DataExtractor m_cfi_data;
+ bool m_cfi_data_initialized; // only copy the section into the DE once
+
+ FDEEntryMap m_fde_index;
+ bool m_fde_index_initialized; // only scan the section for FDEs once
+ Mutex m_fde_index_mutex; // and isolate the thread that does it
+
+ bool m_is_eh_frame;
+
+ CIESP
+ ParseCIE (const uint32_t cie_offset);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_DWARFCallFrameInfo_h_
diff --git a/include/lldb/Symbol/Declaration.h b/include/lldb/Symbol/Declaration.h
new file mode 100644
index 000000000000..f014571595f0
--- /dev/null
+++ b/include/lldb/Symbol/Declaration.h
@@ -0,0 +1,278 @@
+//===-- Declaration.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Declaration_h_
+#define liblldb_Declaration_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Host/FileSpec.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Declaration Declaration.h "lldb/Symbol/Declaration.h"
+/// @brief A class that describes the declaration location of a
+/// lldb object.
+///
+/// The declarations include the file specification, line number, and
+/// the column info and can help track where functions, blocks, inlined
+/// functions, types, variables, any many other debug core objects were
+/// declared.
+//----------------------------------------------------------------------
+class Declaration
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor.
+ //------------------------------------------------------------------
+ Declaration () :
+ m_file (),
+ m_line (0)
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ ,m_column (0)
+#endif
+ {
+ }
+
+
+ //------------------------------------------------------------------
+ /// Construct with file specification, and optional line and column.
+ ///
+ /// @param[in] file_spec
+ /// The file specification that describes where this was
+ /// declared.
+ ///
+ /// @param[in] line
+ /// The line number that describes where this was declared. Set
+ /// to zero if there is no line number information.
+ ///
+ /// @param[in] column
+ /// The column number that describes where this was declared.
+ /// Set to zero if there is no column number information.
+ //------------------------------------------------------------------
+ Declaration (const FileSpec& file_spec, uint32_t line = 0, uint32_t column = 0) :
+ m_file (file_spec),
+ m_line (line)
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ ,m_column (column)
+#endif
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Construct with a reference to another Declaration object.
+ //------------------------------------------------------------------
+ Declaration (const Declaration& rhs) :
+ m_file (rhs.m_file),
+ m_line (rhs.m_line)
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ ,m_column (rhs.m_column)
+#endif
+ {
+
+ }
+
+ //------------------------------------------------------------------
+ /// Construct with a pointer to another Declaration object.
+ //------------------------------------------------------------------
+ Declaration(const Declaration* decl_ptr) :
+ m_file(),
+ m_line(0)
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ ,m_column(0)
+#endif
+ {
+ if (decl_ptr)
+ *this = *decl_ptr;
+ }
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Sets the file specification to be empty, and the line and column
+ /// to zero.
+ //------------------------------------------------------------------
+ void
+ Clear ()
+ {
+ m_file.Clear();
+ m_line= 0;
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ m_column = 0;
+#endif
+ }
+
+ //------------------------------------------------------------------
+ /// Compare two declaration objects.
+ ///
+ /// Compares the two file specifications from \a lhs and \a rhs. If
+ /// the file specifications are equal, then continue to compare the
+ /// line number and column numbers respectively.
+ ///
+ /// @param[in] lhs
+ /// The Left Hand Side const Declaration object reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const Declaration object reference.
+ ///
+ /// @return
+ /// @li -1 if lhs < rhs
+ /// @li 0 if lhs == rhs
+ /// @li 1 if lhs > rhs
+ //------------------------------------------------------------------
+ static int
+ Compare (const Declaration& lhs, const Declaration& rhs);
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, bool show_fullpaths) const;
+
+ bool
+ DumpStopContext (Stream *s, bool show_fullpaths) const;
+ //------------------------------------------------------------------
+ /// Get accessor for the declaration column number.
+ ///
+ /// @return
+ /// Non-zero indicates a valid column number, zero indicates no
+ /// column information is available.
+ //------------------------------------------------------------------
+ uint32_t
+ GetColumn () const
+ {
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ return m_column;
+#else
+ return 0;
+#endif
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor for file specification.
+ ///
+ /// @return
+ /// A reference to the file specification object.
+ //------------------------------------------------------------------
+ FileSpec&
+ GetFile ()
+ {
+ return m_file;
+ }
+
+ //------------------------------------------------------------------
+ /// Get const accessor for file specification.
+ ///
+ /// @return
+ /// A const reference to the file specification object.
+ //------------------------------------------------------------------
+ const FileSpec&
+ GetFile () const
+ {
+ return m_file;
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor for the declaration line number.
+ ///
+ /// @return
+ /// Non-zero indicates a valid line number, zero indicates no
+ /// line information is available.
+ //------------------------------------------------------------------
+ uint32_t
+ GetLine () const
+ {
+ return m_line;
+ }
+
+
+ bool
+ IsValid() const
+ {
+ return m_file && m_line != 0;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ /// The returned value does not include the bytes for any
+ /// shared string values.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ size_t
+ MemorySize () const;
+
+ //------------------------------------------------------------------
+ /// Set accessor for the declaration column number.
+ ///
+ /// @param[in] column
+ /// Non-zero indicates a valid column number, zero indicates no
+ /// column information is available.
+ //------------------------------------------------------------------
+ void
+ SetColumn (uint32_t column)
+ {
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ m_column = col;
+#endif
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the declaration file specification.
+ ///
+ /// @param[in] file_spec
+ /// The new declaration file specifciation.
+ //------------------------------------------------------------------
+ void
+ SetFile (const FileSpec& file_spec)
+ {
+ m_file = file_spec;
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the declaration line number.
+ ///
+ /// @param[in] line
+ /// Non-zero indicates a valid line number, zero indicates no
+ /// line information is available.
+ //------------------------------------------------------------------
+ void
+ SetLine (uint32_t line)
+ {
+ m_line = line;
+ }
+protected:
+ //------------------------------------------------------------------
+ /// Member variables.
+ //------------------------------------------------------------------
+ FileSpec m_file; ///< The file specification that points to the
+ ///< source file where the declaration occurred.
+ uint32_t m_line; ///< Non-zero values indicates a valid line number,
+ ///< zero indicates no line number information is available.
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ uint32_t m_column; ///< Non-zero values indicates a valid column number,
+ ///< zero indicates no column information is available.
+#endif
+};
+
+bool
+operator == (const Declaration &lhs, const Declaration &rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_Declaration_h_
diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h
new file mode 100644
index 000000000000..fa48dc27e123
--- /dev/null
+++ b/include/lldb/Symbol/FuncUnwinders.h
@@ -0,0 +1,106 @@
+#ifndef liblldb_FuncUnwinders_h
+#define liblldb_FuncUnwinders_h
+
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+class UnwindTable;
+
+class FuncUnwinders
+{
+public:
+ // FuncUnwinders objects are used to track UnwindPlans for a function
+ // (named or not - really just an address range)
+
+ // We'll record three different UnwindPlans for each address range:
+ // 1. Unwinding from a call site (a valid exception throw location)
+ // This is often sourced from the eh_frame exception handling info
+ // 2. Unwinding from a non-call site (any location in the function)
+ // This is often done by analyzing the function prologue assembly
+ // langauge instructions
+ // 3. A fast unwind method for this function which only retrieves a
+ // limited set of registers necessary to walk the stack
+ // 4. An architectural default unwind plan when none of the above are
+ // available for some reason.
+
+ // Additionally, FuncUnwinds object can be asked where the prologue
+ // instructions are finished for migrating breakpoints past the
+ // stack frame setup instructions when we don't have line table information.
+
+ FuncUnwinders (lldb_private::UnwindTable& unwind_table, lldb_private::UnwindAssembly *assembly_profiler, AddressRange range);
+
+ ~FuncUnwinders ();
+
+ // current_offset is the byte offset into the function.
+ // 0 means no instructions have executed yet. -1 means the offset is unknown.
+ // On architectures where the pc points to the next instruction that will execute, this
+ // offset value will have already been decremented by 1 to stay within the bounds of the
+ // correct function body.
+ lldb::UnwindPlanSP
+ GetUnwindPlanAtCallSite (int current_offset);
+
+ lldb::UnwindPlanSP
+ GetUnwindPlanAtNonCallSite (lldb_private::Thread& thread);
+
+ lldb::UnwindPlanSP
+ GetUnwindPlanFastUnwind (lldb_private::Thread& Thread);
+
+ lldb::UnwindPlanSP
+ GetUnwindPlanArchitectureDefault (lldb_private::Thread& thread);
+
+ lldb::UnwindPlanSP
+ GetUnwindPlanArchitectureDefaultAtFunctionEntry (lldb_private::Thread& thread);
+
+ Address&
+ GetFirstNonPrologueInsn (Target& target);
+
+ const Address&
+ GetFunctionStartAddress () const;
+
+ bool
+ ContainsAddress (const Address& addr) const
+ {
+ return m_range.ContainsFileAddress (addr);
+ }
+
+ // When we're doing an unwind using the UnwindPlanAtNonCallSite and we find an
+ // impossible unwind condition, we know that the UnwindPlan is invalid. Calling
+ // this method on the FuncUnwinder will tell it to replace that UnwindPlan with
+ // the architectural default UnwindPlan so hopefully our stack walk will get past
+ // this frame.
+ void
+ InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& Thread);
+
+private:
+ UnwindTable& m_unwind_table;
+ UnwindAssembly *m_assembly_profiler;
+ AddressRange m_range;
+
+ Mutex m_mutex;
+ lldb::UnwindPlanSP m_unwind_plan_call_site_sp;
+ lldb::UnwindPlanSP m_unwind_plan_non_call_site_sp;
+ lldb::UnwindPlanSP m_unwind_plan_fast_sp;
+ lldb::UnwindPlanSP m_unwind_plan_arch_default_sp;
+ lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp;
+
+ bool m_tried_unwind_at_call_site:1,
+ m_tried_unwind_at_non_call_site:1,
+ m_tried_unwind_fast:1,
+ m_tried_unwind_arch_default:1,
+ m_tried_unwind_arch_default_at_func_entry:1;
+
+
+ Address m_first_non_prologue_insn;
+
+ DISALLOW_COPY_AND_ASSIGN (FuncUnwinders);
+
+}; // class FuncUnwinders
+
+} // namespace lldb_private
+
+
+#endif //liblldb_FuncUnwinders_h
diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h
new file mode 100644
index 000000000000..787f81c5ad27
--- /dev/null
+++ b/include/lldb/Symbol/Function.h
@@ -0,0 +1,638 @@
+//===-- Function.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Function_h_
+#define liblldb_Function_h_
+
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/Declaration.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Core/Mangled.h"
+#include "lldb/Core/UserID.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class FunctionInfo Function.h "lldb/Symbol/Function.h"
+/// @brief A class that contains generic function information.
+///
+/// This provides generic function information that gets resused between
+/// inline functions and function types.
+//----------------------------------------------------------------------
+class FunctionInfo
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with the function method name and optional declaration
+ /// information.
+ ///
+ /// @param[in] name
+ /// A C string name for the method name for this function. This
+ /// value should not be the mangled named, but the simple method
+ /// name.
+ ///
+ /// @param[in] decl_ptr
+ /// Optional declaration information that describes where the
+ /// function was declared. This can be NULL.
+ //------------------------------------------------------------------
+ FunctionInfo (const char *name, const Declaration *decl_ptr);
+
+ //------------------------------------------------------------------
+ /// Construct with the function method name and optional declaration
+ /// information.
+ ///
+ /// @param[in] name
+ /// A name for the method name for this function. This value
+ /// should not be the mangled named, but the simple method name.
+ ///
+ /// @param[in] decl_ptr
+ /// Optional declaration information that describes where the
+ /// function was declared. This can be NULL.
+ //------------------------------------------------------------------
+ FunctionInfo (const ConstString& name, const Declaration *decl_ptr);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since classes inherit from this class.
+ //------------------------------------------------------------------
+ virtual
+ ~FunctionInfo ();
+
+ //------------------------------------------------------------------
+ /// Compare two function information objects.
+ ///
+ /// First compares the method names, and if equal, then compares
+ /// the declaration information.
+ ///
+ /// @param[in] lhs
+ /// The Left Hand Side const FunctionInfo object reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const FunctionInfo object reference.
+ ///
+ /// @return
+ /// @li -1 if lhs < rhs
+ /// @li 0 if lhs == rhs
+ /// @li 1 if lhs > rhs
+ //------------------------------------------------------------------
+ static int
+ Compare (const FunctionInfo& lhs, const FunctionInfo& rhs);
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, bool show_fullpaths) const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the declaration information.
+ ///
+ /// @return
+ /// A reference to the declaration object.
+ //------------------------------------------------------------------
+ Declaration&
+ GetDeclaration ();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the declaration information.
+ ///
+ /// @return
+ /// A const reference to the declaration object.
+ //------------------------------------------------------------------
+ const Declaration&
+ GetDeclaration () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the method name.
+ ///
+ /// @return
+ /// A const reference to the method name object.
+ //------------------------------------------------------------------
+ const ConstString&
+ GetName () const;
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ /// The returned value does not include the bytes for any
+ /// shared string values.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ virtual size_t
+ MemorySize () const;
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ ConstString m_name; ///< Function method name (not a mangled name).
+ Declaration m_declaration; ///< Information describing where this function information was defined.
+};
+
+
+//----------------------------------------------------------------------
+/// @class InlineFunctionInfo Function.h "lldb/Symbol/Function.h"
+/// @brief A class that describes information for an inlined function.
+//----------------------------------------------------------------------
+class InlineFunctionInfo : public FunctionInfo
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with the function method name, mangled name, and
+ /// optional declaration information.
+ ///
+ /// @param[in] name
+ /// A C string name for the method name for this function. This
+ /// value should not be the mangled named, but the simple method
+ /// name.
+ ///
+ /// @param[in] mangled
+ /// A C string name for the mangled name for this function. This
+ /// value can be NULL if there is no mangled information.
+ ///
+ /// @param[in] decl_ptr
+ /// Optional declaration information that describes where the
+ /// function was declared. This can be NULL.
+ ///
+ /// @param[in] call_decl_ptr
+ /// Optional calling location declaration information that
+ /// describes from where this inlined function was called.
+ //------------------------------------------------------------------
+ InlineFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr);
+
+ //------------------------------------------------------------------
+ /// Construct with the function method name, mangled name, and
+ /// optional declaration information.
+ ///
+ /// @param[in] name
+ /// A name for the method name for this function. This value
+ /// should not be the mangled named, but the simple method name.
+ ///
+ /// @param[in] mangled
+ /// A name for the mangled name for this function. This value
+ /// can be empty if there is no mangled information.
+ ///
+ /// @param[in] decl_ptr
+ /// Optional declaration information that describes where the
+ /// function was declared. This can be NULL.
+ ///
+ /// @param[in] call_decl_ptr
+ /// Optional calling location declaration information that
+ /// describes from where this inlined function was called.
+ //------------------------------------------------------------------
+ InlineFunctionInfo(const ConstString& name, const Mangled &mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~InlineFunctionInfo();
+
+ //------------------------------------------------------------------
+ /// Compare two inlined function information objects.
+ ///
+ /// First compares the FunctionInfo objects, and if equal,
+ /// compares the mangled names.
+ ///
+ /// @param[in] lhs
+ /// The Left Hand Side const InlineFunctionInfo object
+ /// reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const InlineFunctionInfo object
+ /// reference.
+ ///
+ /// @return
+ /// @li -1 if lhs < rhs
+ /// @li 0 if lhs == rhs
+ /// @li 1 if lhs > rhs
+ //------------------------------------------------------------------
+ int
+ Compare(const InlineFunctionInfo& lhs, const InlineFunctionInfo& rhs);
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump(Stream *s, bool show_fullpaths) const;
+
+ void
+ DumpStopContext (Stream *s) const;
+
+ const ConstString &
+ GetName () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the call site declaration information.
+ ///
+ /// @return
+ /// A reference to the declaration object.
+ //------------------------------------------------------------------
+ Declaration&
+ GetCallSite ();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the call site declaration information.
+ ///
+ /// @return
+ /// A const reference to the declaration object.
+ //------------------------------------------------------------------
+ const Declaration&
+ GetCallSite () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the mangled name object.
+ ///
+ /// @return
+ /// A reference to the mangled name object.
+ //------------------------------------------------------------------
+ Mangled&
+ GetMangled();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the mangled name object.
+ ///
+ /// @return
+ /// A const reference to the mangled name object.
+ //------------------------------------------------------------------
+ const Mangled&
+ GetMangled() const;
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ /// The returned value does not include the bytes for any
+ /// shared string values.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ virtual size_t
+ MemorySize() const;
+
+private:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ Mangled m_mangled; ///< Mangled inlined function name (can be empty if there is no mangled information).
+ Declaration m_call_decl;
+};
+
+//----------------------------------------------------------------------
+/// @class Function Function.h "lldb/Symbol/Function.h"
+/// @brief A class that describes a function.
+///
+/// Functions belong to CompileUnit objects (Function::m_comp_unit),
+/// have unique user IDs (Function::UserID), know how to reconstruct
+/// their symbol context (Function::SymbolContextScope), have a
+/// specific function type (Function::m_type_uid), have a simple
+/// method name (FunctionInfo::m_name), be declared at a specific
+/// location (FunctionInfo::m_declaration), possibly have mangled
+/// names (Function::m_mangled), an optional return type
+/// (Function::m_type), and contains lexical blocks
+/// (Function::m_blocks).
+///
+/// The function inforation is split into a few pieces:
+/// @li The concrete instance information
+/// @li The abstract information
+///
+/// The abstract information is found in the function type (Type) that
+/// describes a function information, return type and parameter types.
+///
+/// The concreate information is the address range information and
+/// specific locations for an instance of this function.
+//----------------------------------------------------------------------
+class Function :
+ public UserID,
+ public SymbolContextScope
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with a compile unit, function UID, function type UID,
+ /// optional mangled name, function type, and a section offset
+ /// based address range.
+ ///
+ /// @param[in] comp_unit
+ /// The compile unit to which this function belongs.
+ ///
+ /// @param[in] func_uid
+ /// The UID for this function. This value is provided by the
+ /// SymbolFile plug-in and can be any value that allows
+ /// the plug-in to quickly find and parse more detailed
+ /// information when and if more information is needed.
+ ///
+ /// @param[in] func_type_uid
+ /// The type UID for the function Type to allow for lazy type
+ /// parsing from the debug information.
+ ///
+ /// @param[in] mangled
+ /// The optional mangled name for this function. If empty, there
+ /// is no mangled information.
+ ///
+ /// @param[in] func_type
+ /// The optional function type. If NULL, the function type will
+ /// be parsed on demand when accessed using the
+ /// Function::GetType() function by asking the SymbolFile
+ /// plug-in to get the type for \a func_type_uid.
+ ///
+ /// @param[in] range
+ /// The section offset based address for this function.
+ //------------------------------------------------------------------
+ Function (
+ CompileUnit *comp_unit,
+ lldb::user_id_t func_uid,
+ lldb::user_id_t func_type_uid,
+ const Mangled &mangled,
+ Type * func_type,
+ const AddressRange& range);
+
+ //------------------------------------------------------------------
+ /// Construct with a compile unit, function UID, function type UID,
+ /// optional mangled name, function type, and a section offset
+ /// based address range.
+ ///
+ /// @param[in] comp_unit
+ /// The compile unit to which this function belongs.
+ ///
+ /// @param[in] func_uid
+ /// The UID for this function. This value is provided by the
+ /// SymbolFile plug-in and can be any value that allows
+ /// the plug-in to quickly find and parse more detailed
+ /// information when and if more information is needed.
+ ///
+ /// @param[in] func_type_uid
+ /// The type UID for the function Type to allow for lazy type
+ /// parsing from the debug information.
+ ///
+ /// @param[in] mangled
+ /// The optional mangled name for this function. If empty, there
+ /// is no mangled information.
+ ///
+ /// @param[in] func_type
+ /// The optional function type. If NULL, the function type will
+ /// be parsed on demand when accessed using the
+ /// Function::GetType() function by asking the SymbolFile
+ /// plug-in to get the type for \a func_type_uid.
+ ///
+ /// @param[in] range
+ /// The section offset based address for this function.
+ //------------------------------------------------------------------
+ Function (
+ CompileUnit *comp_unit,
+ lldb::user_id_t func_uid,
+ lldb::user_id_t func_type_uid,
+ const char *mangled,
+ Type * func_type,
+ const AddressRange& range);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~Function ();
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext(SymbolContext* sc);
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ();
+
+ virtual CompileUnit *
+ CalculateSymbolContextCompileUnit ();
+
+ virtual Function *
+ CalculateSymbolContextFunction ();
+
+ const AddressRange &
+ GetAddressRange()
+ {
+ return m_range;
+ }
+
+ //------------------------------------------------------------------
+ /// Find the file and line number of the source location of the start
+ /// of the function. This will use the declaration if present and fall
+ /// back on the line table if that fails. So there may NOT be a line
+ /// table entry for this source file/line combo.
+ ///
+ /// @param[out] source_file
+ /// The source file.
+ ///
+ /// @param[out] line_no
+ /// The line number.
+ //------------------------------------------------------------------
+ void
+ GetStartLineSourceInfo (FileSpec &source_file, uint32_t &line_no);
+
+ //------------------------------------------------------------------
+ /// Find the file and line number of the source location of the end
+ /// of the function.
+ ///
+ ///
+ /// @param[out] source_file
+ /// The source file.
+ ///
+ /// @param[out] line_no
+ /// The line number.
+ //------------------------------------------------------------------
+ void
+ GetEndLineSourceInfo (FileSpec &source_file, uint32_t &line_no);
+
+ //------------------------------------------------------------------
+ /// Get accessor for the block list.
+ ///
+ /// @return
+ /// The block list object that describes all lexical blocks
+ /// in the function.
+ ///
+ /// @see BlockList
+ //------------------------------------------------------------------
+ Block&
+ GetBlock (bool can_create);
+
+ //------------------------------------------------------------------
+ /// Get accessor for the compile unit that owns this function.
+ ///
+ /// @return
+ /// A compile unit object pointer.
+ //------------------------------------------------------------------
+ CompileUnit*
+ GetCompileUnit();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the compile unit that owns this function.
+ ///
+ /// @return
+ /// A const compile unit object pointer.
+ //------------------------------------------------------------------
+ const CompileUnit*
+ GetCompileUnit() const;
+
+ void
+ GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target);
+
+ //------------------------------------------------------------------
+ /// Get accessor for the frame base location.
+ ///
+ /// @return
+ /// A location expression that describes the function frame
+ /// base.
+ //------------------------------------------------------------------
+ DWARFExpression &
+ GetFrameBaseExpression()
+ {
+ return m_frame_base;
+ }
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the frame base location.
+ ///
+ /// @return
+ /// A const compile unit object pointer.
+ //------------------------------------------------------------------
+ const DWARFExpression &
+ GetFrameBaseExpression() const
+ {
+ return m_frame_base;
+ }
+
+ const ConstString &
+ GetName() const
+ {
+ return m_mangled.GetName();
+ }
+
+ const Mangled &
+ GetMangled() const
+ {
+ return m_mangled;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the DeclContext for this function, if available.
+ ///
+ /// @return
+ /// The DeclContext, or NULL if none exists.
+ //------------------------------------------------------------------
+ clang::DeclContext *
+ GetClangDeclContext();
+
+ //------------------------------------------------------------------
+ /// Get accessor for the type that describes the function
+ /// return value type, and paramter types.
+ ///
+ /// @return
+ /// A type object pointer.
+ //------------------------------------------------------------------
+ Type*
+ GetType();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the type that describes the function
+ /// return value type, and paramter types.
+ ///
+ /// @return
+ /// A const type object pointer.
+ //------------------------------------------------------------------
+ const Type*
+ GetType() const;
+
+ ClangASTType
+ GetClangType ();
+
+ uint32_t
+ GetPrologueByteSize ();
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] show_context
+ /// If \b true, variables will dump their symbol context
+ /// information.
+ //------------------------------------------------------------------
+ void
+ Dump(Stream *s, bool show_context) const;
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext(Stream *s);
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ /// The returned value does not include the bytes for any
+ /// shared string values.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ size_t
+ MemorySize () const;
+
+protected:
+
+ enum
+ {
+ flagsCalculatedPrologueSize = (1 << 0) ///< Have we already tried to calculate the prologue size?
+ };
+
+
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ CompileUnit *m_comp_unit; ///< The compile unit that owns this function.
+ lldb::user_id_t m_type_uid; ///< The user ID of for the prototype Type for this function.
+ Type * m_type; ///< The function prototype type for this function that include the function info (FunctionInfo), return type and parameters.
+ Mangled m_mangled; ///< The mangled function name if any, if empty, there is no mangled information.
+ Block m_block; ///< All lexical blocks contained in this function.
+ AddressRange m_range; ///< The function address range that covers the widest range needed to contain all blocks
+ DWARFExpression m_frame_base; ///< The frame base expression for variables that are relative to the frame pointer.
+ Flags m_flags;
+ uint32_t m_prologue_byte_size; ///< Compute the prologue size once and cache it
+private:
+ DISALLOW_COPY_AND_ASSIGN(Function);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Function_h_
diff --git a/include/lldb/Symbol/LineEntry.h b/include/lldb/Symbol/LineEntry.h
new file mode 100644
index 000000000000..d7750cd34916
--- /dev/null
+++ b/include/lldb/Symbol/LineEntry.h
@@ -0,0 +1,174 @@
+//===-- LineEntry.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LineEntry_h_
+#define liblldb_LineEntry_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Host/FileSpec.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class LineEntry LineEntry.h "lldb/Symbol/LineEntry.h"
+/// @brief A line table entry class.
+//----------------------------------------------------------------------
+struct LineEntry
+{
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize all member variables to invalid values.
+ //------------------------------------------------------------------
+ LineEntry ();
+
+ LineEntry
+ (
+ const lldb::SectionSP &section_sp,
+ lldb::addr_t section_offset,
+ lldb::addr_t byte_size,
+ const FileSpec &file,
+ uint32_t _line,
+ uint16_t _column,
+ bool _is_start_of_statement,
+ bool _is_start_of_basic_block,
+ bool _is_prologue_end,
+ bool _is_epilogue_begin,
+ bool _is_terminal_entry
+ );
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Clears all member variables to invalid values.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] comp_unit
+ /// The compile unit object that contains the support file
+ /// list so the line entry can dump the file name (since this
+ /// object contains a file index into the support file list).
+ ///
+ /// @param[in] show_file
+ /// If \b true, display the filename with the line entry which
+ /// requires that the compile unit object \a comp_unit be a
+ /// valid pointer.
+ ///
+ /// @param[in] style
+ /// The display style for the section offset address.
+ ///
+ /// @return
+ /// Returns \b true if the address was able to be displayed
+ /// using \a style. File and load addresses may be unresolved
+ /// and it may not be possible to display a valid address value.
+ /// Returns \b false if the address was not able to be properly
+ /// dumped.
+ ///
+ /// @see Address::DumpStyle
+ //------------------------------------------------------------------
+ bool
+ Dump (Stream *s, Target *target, bool show_file, Address::DumpStyle style, Address::DumpStyle fallback_style, bool show_range) const;
+
+ bool
+ GetDescription (Stream *s,
+ lldb::DescriptionLevel level,
+ CompileUnit* cu,
+ Target *target,
+ bool show_address_only) const;
+
+ //------------------------------------------------------------------
+ /// Dumps information specific to a process that stops at this
+ /// line entry to the supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] comp_unit
+ /// The compile unit object that contains the support file
+ /// list so the line entry can dump the file name (since this
+ /// object contains a file index into the support file list).
+ ///
+ /// @return
+ /// Returns \b true if the file and line were properly dumped,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ DumpStopContext (Stream *s, bool show_fullpaths) const;
+
+ //------------------------------------------------------------------
+ /// Check if a line entry object is valid.
+ ///
+ /// @return
+ /// Returns \b true if the line entry contains a valid section
+ /// offset address, file index, and line number, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsValid () const;
+
+ //------------------------------------------------------------------
+ /// Compare two LineEntry objects.
+ ///
+ /// @param[in] lhs
+ /// The Left Hand Side const LineEntry object reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const LineEntry object reference.
+ ///
+ /// @return
+ /// @li -1 if lhs < rhs
+ /// @li 0 if lhs == rhs
+ /// @li 1 if lhs > rhs
+ //------------------------------------------------------------------
+ static int
+ Compare (const LineEntry& lhs, const LineEntry& rhs);
+
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ AddressRange range; ///< The section offset address range for this line entry.
+ FileSpec file;
+ uint32_t line; ///< The source line number, or zero if there is no line number information.
+ uint16_t column; ///< The column number of the source line, or zero if there is no column information.
+ uint16_t is_start_of_statement:1, ///< Indicates this entry is the beginning of a statement.
+ is_start_of_basic_block:1, ///< Indicates this entry is the beginning of a basic block.
+ is_prologue_end:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an entry breakpoint of a function.
+ is_epilogue_begin:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an exit breakpoint of a function.
+ is_terminal_entry:1; ///< Indicates this entry is that of the first byte after the end of a sequence of target machine instructions.
+};
+
+//------------------------------------------------------------------
+/// Less than operator.
+///
+/// @param[in] lhs
+/// The Left Hand Side const LineEntry object reference.
+///
+/// @param[in] rhs
+/// The Right Hand Side const LineEntry object reference.
+///
+/// @return
+/// Returns \b true if lhs < rhs, false otherwise.
+//------------------------------------------------------------------
+bool operator<(const LineEntry& lhs, const LineEntry& rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_LineEntry_h_
diff --git a/include/lldb/Symbol/LineTable.h b/include/lldb/Symbol/LineTable.h
new file mode 100644
index 000000000000..477c8455ded8
--- /dev/null
+++ b/include/lldb/Symbol/LineTable.h
@@ -0,0 +1,422 @@
+//===-- LineTable.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LineTable_h_
+#define liblldb_LineTable_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Symbol/LineEntry.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/RangeMap.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class LineSequence LineTable.h "lldb/Symbol/LineTable.h"
+/// @brief An abstract base class used during symbol table creation.
+//----------------------------------------------------------------------
+class LineSequence
+{
+public:
+ LineSequence ();
+
+ virtual
+ ~LineSequence() {}
+
+ virtual void
+ Clear() = 0;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (LineSequence);
+};
+
+//----------------------------------------------------------------------
+/// @class LineTable LineTable.h "lldb/Symbol/LineTable.h"
+/// @brief A line table class.
+//----------------------------------------------------------------------
+class LineTable
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with compile unit.
+ ///
+ /// @param[in] comp_unit
+ /// The compile unit to which this line table belongs.
+ //------------------------------------------------------------------
+ LineTable (CompileUnit* comp_unit);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~LineTable ();
+
+ //------------------------------------------------------------------
+ /// Adds a new line entry to this line table.
+ ///
+ /// All line entries are maintained in file address order.
+ ///
+ /// @param[in] line_entry
+ /// A const reference to a new line_entry to add to this line
+ /// table.
+ ///
+ /// @see Address::DumpStyle
+ //------------------------------------------------------------------
+// void
+// AddLineEntry (const LineEntry& line_entry);
+
+ // Called when you can't guarantee the addresses are in increasing order
+ void
+ InsertLineEntry (lldb::addr_t file_addr,
+ uint32_t line,
+ uint16_t column,
+ uint16_t file_idx,
+ bool is_start_of_statement,
+ bool is_start_of_basic_block,
+ bool is_prologue_end,
+ bool is_epilogue_begin,
+ bool is_terminal_entry);
+
+ // Used to instantiate the LineSequence helper classw
+ LineSequence*
+ CreateLineSequenceContainer ();
+
+ // Append an entry to a caller-provided collection that will later be
+ // inserted in this line table.
+ void
+ AppendLineEntryToSequence (LineSequence* sequence,
+ lldb::addr_t file_addr,
+ uint32_t line,
+ uint16_t column,
+ uint16_t file_idx,
+ bool is_start_of_statement,
+ bool is_start_of_basic_block,
+ bool is_prologue_end,
+ bool is_epilogue_begin,
+ bool is_terminal_entry);
+
+ // Insert a sequence of entries into this line table.
+ void
+ InsertSequence (LineSequence* sequence);
+
+ //------------------------------------------------------------------
+ /// Dump all line entries in this line table to the stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] style
+ /// The display style for the address.
+ ///
+ /// @see Address::DumpStyle
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, Target *target,
+ Address::DumpStyle style,
+ Address::DumpStyle fallback_style,
+ bool show_line_ranges);
+
+ void
+ GetDescription (Stream *s,
+ Target *target,
+ lldb::DescriptionLevel level);
+
+ //------------------------------------------------------------------
+ /// Find a line entry that contains the section offset address \a
+ /// so_addr.
+ ///
+ /// @param[in] so_addr
+ /// A section offset address object containing the address we
+ /// are searching for.
+ ///
+ /// @param[out] line_entry
+ /// A copy of the line entry that was found if \b true is
+ /// returned, otherwise \a entry is left unmodified.
+ ///
+ /// @param[out] index_ptr
+ /// A pointer to a 32 bit integer that will get the actual line
+ /// entry index if it is not NULL.
+ ///
+ /// @return
+ /// Returns \b true if \a so_addr is contained in a line entry
+ /// in this line table, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ FindLineEntryByAddress (const Address &so_addr, LineEntry& line_entry, uint32_t *index_ptr = NULL);
+
+ //------------------------------------------------------------------
+ /// Find a line entry index that has a matching file index and
+ /// source line number.
+ ///
+ /// Finds the next line entry that has a matching \a file_idx and
+ /// source line number \a line starting at the \a start_idx entries
+ /// into the line entry collection.
+ ///
+ /// @param[in] start_idx
+ /// The number of entries to skip when starting the search.
+ ///
+ /// @param[out] file_idx
+ /// The file index to search for that should be found prior
+ /// to calling this function using the following functions:
+ /// CompileUnit::GetSupportFiles()
+ /// FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const
+ ///
+ /// @param[in] line
+ /// The source line to match.
+ ///
+ /// @param[in] exact
+ /// If true, match only if you find a line entry exactly matching \a line.
+ /// If false, return the closest line entry greater than \a line.
+ ///
+ /// @param[out] line_entry
+ /// A reference to a line entry object that will get a copy of
+ /// the line entry if \b true is returned, otherwise \a
+ /// line_entry is left untouched.
+ ///
+ /// @return
+ /// Returns \b true if a matching line entry is found in this
+ /// line table, \b false otherwise.
+ ///
+ /// @see CompileUnit::GetSupportFiles()
+ /// @see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const
+ //------------------------------------------------------------------
+ uint32_t
+ FindLineEntryIndexByFileIndex (uint32_t start_idx,
+ uint32_t file_idx,
+ uint32_t line,
+ bool exact,
+ LineEntry* line_entry_ptr);
+
+ uint32_t
+ FindLineEntryIndexByFileIndex (uint32_t start_idx,
+ const std::vector<uint32_t> &file_indexes,
+ uint32_t line,
+ bool exact,
+ LineEntry* line_entry_ptr);
+
+ size_t
+ FineLineEntriesForFileIndex (uint32_t file_idx,
+ bool append,
+ SymbolContextList &sc_list);
+
+ //------------------------------------------------------------------
+ /// Get the line entry from the line table at index \a idx.
+ ///
+ /// @param[in] idx
+ /// An index into the line table entry collection.
+ ///
+ /// @return
+ /// A valid line entry if \a idx is a valid index, or an invalid
+ /// line entry if \a idx is not valid.
+ ///
+ /// @see LineTable::GetSize()
+ /// @see LineEntry::IsValid() const
+ //------------------------------------------------------------------
+ bool
+ GetLineEntryAtIndex(uint32_t idx, LineEntry& line_entry);
+
+ //------------------------------------------------------------------
+ /// Gets the size of the line table in number of line table entries.
+ ///
+ /// @return
+ /// The number of line table entries in this line table.
+ //------------------------------------------------------------------
+ uint32_t
+ GetSize () const;
+
+ typedef lldb_private::RangeArray<lldb::addr_t, lldb::addr_t, 32> FileAddressRanges;
+
+ //------------------------------------------------------------------
+ /// Gets all contiguous file address ranges for the entire line table.
+ ///
+ /// @param[out] file_ranges
+ /// A collection of file address ranges that will be filled in
+ /// by this function.
+ ///
+ /// @param[out] append
+ /// If \b true, then append to \a file_ranges, otherwise clear
+ /// \a file_ranges prior to adding any ranges.
+ ///
+ /// @return
+ /// The number of address ranges added to \a file_ranges
+ //------------------------------------------------------------------
+ size_t
+ GetContiguousFileAddressRanges (FileAddressRanges &file_ranges, bool append);
+
+ //------------------------------------------------------------------
+ /// Given a file range link map, relink the current line table
+ /// and return a fixed up line table.
+ ///
+ /// @param[out] file_range_map
+ /// A collection of file ranges that maps to new file ranges
+ /// that will be used when linking the line table.
+ ///
+ /// @return
+ /// A new line table if at least one line table entry was able
+ /// to be mapped.
+ //------------------------------------------------------------------
+ typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
+
+ LineTable *
+ LinkLineTable (const FileRangeMap &file_range_map);
+
+protected:
+
+ struct Entry
+ {
+ Entry () :
+ file_addr (LLDB_INVALID_ADDRESS),
+ line (0),
+ column (0),
+ file_idx (0),
+ is_start_of_statement (false),
+ is_start_of_basic_block (false),
+ is_prologue_end (false),
+ is_epilogue_begin (false),
+ is_terminal_entry (false)
+ {
+ }
+
+ Entry ( lldb::addr_t _file_addr,
+ uint32_t _line,
+ uint16_t _column,
+ uint16_t _file_idx,
+ bool _is_start_of_statement,
+ bool _is_start_of_basic_block,
+ bool _is_prologue_end,
+ bool _is_epilogue_begin,
+ bool _is_terminal_entry) :
+ file_addr (_file_addr),
+ line (_line),
+ column (_column),
+ file_idx (_file_idx),
+ is_start_of_statement (_is_start_of_statement),
+ is_start_of_basic_block (_is_start_of_basic_block),
+ is_prologue_end (_is_prologue_end),
+ is_epilogue_begin (_is_epilogue_begin),
+ is_terminal_entry (_is_terminal_entry)
+ {
+ }
+
+ int
+ bsearch_compare (const void *key, const void *arrmem);
+
+ void
+ Clear ()
+ {
+ file_addr = LLDB_INVALID_ADDRESS;
+ line = 0;
+ column = 0;
+ file_idx = 0;
+ is_start_of_statement = false;
+ is_start_of_basic_block = false;
+ is_prologue_end = false;
+ is_epilogue_begin = false;
+ is_terminal_entry = false;
+ }
+
+ static int
+ Compare (const Entry& lhs, const Entry& rhs)
+ {
+ // Compare the sections before calling
+ #define SCALAR_COMPARE(a,b) if (a < b) return -1; if (a > b) return +1
+ SCALAR_COMPARE (lhs.file_addr, rhs.file_addr);
+ SCALAR_COMPARE (lhs.line, rhs.line);
+ SCALAR_COMPARE (lhs.column, rhs.column);
+ SCALAR_COMPARE (lhs.is_start_of_statement, rhs.is_start_of_statement);
+ SCALAR_COMPARE (lhs.is_start_of_basic_block, rhs.is_start_of_basic_block);
+ // rhs and lhs reversed on purpose below.
+ SCALAR_COMPARE (rhs.is_prologue_end, lhs.is_prologue_end);
+ SCALAR_COMPARE (lhs.is_epilogue_begin, rhs.is_epilogue_begin);
+ // rhs and lhs reversed on purpose below.
+ SCALAR_COMPARE (rhs.is_terminal_entry, lhs.is_terminal_entry);
+ SCALAR_COMPARE (lhs.file_idx, rhs.file_idx);
+ #undef SCALAR_COMPARE
+ return 0;
+ }
+
+
+ class LessThanBinaryPredicate
+ {
+ public:
+ LessThanBinaryPredicate(LineTable *line_table);
+ bool operator() (const LineTable::Entry&, const LineTable::Entry&) const;
+ protected:
+ LineTable *m_line_table;
+ };
+
+ static bool EntryAddressLessThan (const Entry& lhs, const Entry& rhs)
+ {
+ return lhs.file_addr < rhs.file_addr;
+ }
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ lldb::addr_t file_addr; ///< The file address for this line entry
+ uint32_t line; ///< The source line number, or zero if there is no line number information.
+ uint16_t column; ///< The column number of the source line, or zero if there is no column information.
+ uint16_t file_idx:11, ///< The file index into CompileUnit's file table, or zero if there is no file information.
+ is_start_of_statement:1, ///< Indicates this entry is the beginning of a statement.
+ is_start_of_basic_block:1, ///< Indicates this entry is the beginning of a basic block.
+ is_prologue_end:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an entry breakpoint of a function.
+ is_epilogue_begin:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an exit breakpoint of a function.
+ is_terminal_entry:1; ///< Indicates this entry is that of the first byte after the end of a sequence of target machine instructions.
+ };
+
+ struct EntrySearchInfo
+ {
+ LineTable* line_table;
+ lldb_private::Section *a_section;
+ Entry *a_entry;
+ };
+
+ //------------------------------------------------------------------
+ // Types
+ //------------------------------------------------------------------
+ typedef std::vector<lldb_private::Section*> section_collection; ///< The collection type for the sections.
+ typedef std::vector<Entry> entry_collection; ///< The collection type for the line entries.
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ CompileUnit* m_comp_unit; ///< The compile unit that this line table belongs to.
+ entry_collection m_entries; ///< The collection of line entries in this line table.
+
+ //------------------------------------------------------------------
+ // Helper class
+ //------------------------------------------------------------------
+ class LineSequenceImpl : public LineSequence
+ {
+ public:
+ LineSequenceImpl() :
+ LineSequence()
+ {}
+
+ virtual
+ ~LineSequenceImpl()
+ {}
+
+ virtual void
+ Clear();
+
+ entry_collection m_entries; ///< The collection of line entries in this sequence.
+ };
+
+ bool
+ ConvertEntryAtIndexToLineEntry (uint32_t idx, LineEntry &line_entry);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (LineTable);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_LineTable_h_
diff --git a/include/lldb/Symbol/ObjectContainer.h b/include/lldb/Symbol/ObjectContainer.h
new file mode 100644
index 000000000000..7fb686245057
--- /dev/null
+++ b/include/lldb/Symbol/ObjectContainer.h
@@ -0,0 +1,236 @@
+//===-- ObjectContainer.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ObjectContainer_h_
+#define liblldb_ObjectContainer_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Host/Endian.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ObjectContainer ObjectContainer.h "lldb/Symbol/ObjectContainer.h"
+/// @brief A plug-in interface definition class for object containers.
+///
+/// Object containers contain object files from one or more
+/// architectures, and also can contain one or more named objects.
+///
+/// Typical object containers are static libraries (.a files) that
+/// contain multiple named object files, and universal files that contain
+/// multiple architectures.
+//----------------------------------------------------------------------
+class ObjectContainer :
+ public PluginInterface,
+ public ModuleChild
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with a parent module, offset, and header data.
+ ///
+ /// Object files belong to modules and a valid module must be
+ /// supplied upon construction. The at an offset within a file for
+ /// objects that contain more than one architecture or object.
+ //------------------------------------------------------------------
+ ObjectContainer (const lldb::ModuleSP &module_sp,
+ const FileSpec *file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset) :
+ ModuleChild (module_sp),
+ m_file (), // This file can be different than the module's file spec
+ m_offset (file_offset),
+ m_length (length),
+ m_data ()
+ {
+ if (file)
+ m_file = *file;
+ if (data_sp)
+ m_data.SetData (data_sp, data_offset, length);
+ }
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be
+ /// inherited from by the plug-in instance.
+ //------------------------------------------------------------------
+ virtual
+ ~ObjectContainer()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the current contents of this object
+ /// to the supplied stream \a s. The dumping should include the
+ /// section list if it has been parsed, and the symbol table
+ /// if it has been parsed.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ virtual void
+ Dump (Stream *s) const = 0;
+
+ //------------------------------------------------------------------
+ /// Gets the architecture given an index.
+ ///
+ /// Copies the architecture specification for index \a idx.
+ ///
+ /// @param[in] idx
+ /// The architecture index to extract.
+ ///
+ /// @param[out] arch
+ /// A architecture object that will be filled in if \a idx is a
+ /// architecture valid index.
+ ///
+ /// @return
+ /// Returns \b true if \a idx is valid and \a arch has been
+ /// filled in, \b false otherwise.
+ ///
+ /// @see ObjectContainer::GetNumArchitectures() const
+ //------------------------------------------------------------------
+ virtual bool
+ GetArchitectureAtIndex (uint32_t idx, ArchSpec& arch) const
+ {
+ return false;
+ }
+
+ //------------------------------------------------------------------
+ /// Returns the offset into a file at which this object resides.
+ ///
+ /// Some files contain many object files, and this function allows
+ /// access to an object's offset within the file.
+ ///
+ /// @return
+ /// The offset in bytes into the file. Defaults to zero for
+ /// simple object files that a represented by an entire file.
+ //------------------------------------------------------------------
+ virtual lldb::addr_t
+ GetOffset () const
+ { return m_offset; }
+
+ virtual lldb::addr_t
+ GetByteSize () const
+ { return m_length; }
+
+ //------------------------------------------------------------------
+ /// Get the number of objects within this object file (archives).
+ ///
+ /// @return
+ /// Zero for object files that are not archives, or the number
+ /// of objects contained in the archive.
+ //------------------------------------------------------------------
+ virtual size_t
+ GetNumObjects () const
+ { return 0; }
+
+ //------------------------------------------------------------------
+ /// Get the number of architectures in this object file.
+ ///
+ /// The default implementation returns 1 as for object files that
+ /// contain a single architecture. ObjectContainer instances that
+ /// contain more than one architecture should override this function
+ /// and return an appropriate value.
+ ///
+ /// @return
+ /// The number of architectures contained in this object file.
+ //------------------------------------------------------------------
+ virtual size_t
+ GetNumArchitectures () const
+ { return 0; }
+
+ //------------------------------------------------------------------
+ /// Attempts to parse the object header.
+ ///
+ /// This function is used as a test to see if a given plug-in
+ /// instance can parse the header data already contained in
+ /// ObjectContainer::m_data. If an object file parser does not
+ /// recognize that magic bytes in a header, false should be returned
+ /// and the next plug-in can attempt to parse an object file.
+ ///
+ /// @return
+ /// Returns \b true if the header was parsed succesfully, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ ParseHeader () = 0;
+
+ //------------------------------------------------------------------
+ /// Selects an architecture in an object file.
+ ///
+ /// Object files that contain a single architecture should verify
+ /// that the specified \a arch matches the architecture in in
+ /// object file and return \b true or \b false accordingly.
+ ///
+ /// Object files that contain more than one architecture should
+ /// attempt to select that architecture, and if successful, clear
+ /// out any previous state from any previously selected architecture
+ /// and prepare to return information for the new architecture.
+ ///
+ /// @return
+ /// Returns a pointer to the object file of the requested \a
+ /// arch and optional \a name. Returns NULL of no such object
+ /// file exists in the container.
+ //------------------------------------------------------------------
+ virtual lldb::ObjectFileSP
+ GetObjectFile (const FileSpec *file) = 0;
+
+ virtual bool
+ ObjectAtIndexIsContainer (uint32_t object_idx)
+ {
+ return false;
+ }
+
+ virtual ObjectFile *
+ GetObjectFileAtIndex (uint32_t object_idx)
+ {
+ return NULL;
+ }
+
+ virtual ObjectContainer *
+ GetObjectContainerAtIndex (uint32_t object_idx)
+ {
+ return NULL;
+ }
+
+ virtual const char *
+ GetObjectNameAtIndex (uint32_t object_idx) const
+ {
+ return NULL;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ FileSpec m_file; ///< The file that represents this container objects (which can be different from the module's file).
+ lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory
+ lldb::addr_t m_length; ///< The size in bytes if known (can be zero).
+ DataExtractor m_data; ///< The data for this object file so things can be parsed lazily.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (ObjectContainer);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ObjectContainer_h_
diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h
new file mode 100644
index 000000000000..8934c31bb988
--- /dev/null
+++ b/include/lldb/Symbol/ObjectFile.h
@@ -0,0 +1,706 @@
+//===-- ObjectFile.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ObjectFile_h_
+#define liblldb_ObjectFile_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/Symtab.h"
+#include "lldb/Symbol/UnwindTable.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ObjectFile ObjectFile.h "lldb/Symbol/ObjectFile.h"
+/// @brief A plug-in interface definition class for object file parsers.
+///
+/// Object files belong to Module objects and know how to extract
+/// information from executable, shared library, and object (.o) files
+/// used by operating system runtime. The symbol table and section list
+/// for an object file.
+///
+/// Object files can be represented by the entire file, or by part of a
+/// file. Examples of object files that are part of a file include
+/// object files that contain information for multiple architectures in
+/// the same file, or archive files that contain multiple objects
+/// (ranlib archives) (possibly for multiple architectures as well).
+///
+/// Object archive files (e.g. ranlib archives) can contain
+/// multiple .o (object) files that must be selected by index or by name.
+/// The number of objects that an ObjectFile contains can be determined
+/// using the ObjectFile::GetNumObjects() const
+/// function, and followed by a call to
+/// ObjectFile::SelectObjectAtIndex (uint32_t) to change the currently
+/// selected object. Objects can also be selected by name using the
+/// ObjectFile::SelectObject(const char *) function.
+///
+/// Once an architecture is selected (and an object is selected for
+/// for archives), the object file information can be extracted from
+/// this abstract class.
+//----------------------------------------------------------------------
+class ObjectFile:
+ public std::enable_shared_from_this<ObjectFile>,
+ public PluginInterface,
+ public ModuleChild
+{
+friend class lldb_private::Module;
+
+public:
+ typedef enum
+ {
+ eTypeInvalid = 0,
+ eTypeCoreFile, /// A core file that has a checkpoint of a program's execution state
+ eTypeExecutable, /// A normal executable
+ eTypeDebugInfo, /// An object file that contains only debug information
+ eTypeDynamicLinker, /// The platform's dynamic linker executable
+ eTypeObjectFile, /// An intermediate object file
+ eTypeSharedLibrary, /// A shared library that can be used during execution
+ eTypeStubLibrary, /// A library that can be linked against but not used for execution
+ eTypeUnknown
+ } Type;
+
+ typedef enum
+ {
+ eStrataInvalid = 0,
+ eStrataUnknown,
+ eStrataUser,
+ eStrataKernel,
+ eStrataRawImage
+ } Strata;
+
+ //------------------------------------------------------------------
+ /// Construct with a parent module, offset, and header data.
+ ///
+ /// Object files belong to modules and a valid module must be
+ /// supplied upon construction. The at an offset within a file for
+ /// objects that contain more than one architecture or object.
+ //------------------------------------------------------------------
+ ObjectFile (const lldb::ModuleSP &module_sp,
+ const FileSpec *file_spec_ptr,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset);
+
+ ObjectFile (const lldb::ModuleSP &module_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr,
+ lldb::DataBufferSP& data_sp);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be
+ /// inherited from by the plug-in instance.
+ //------------------------------------------------------------------
+ virtual
+ ~ObjectFile();
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the current contents of this object
+ /// to the supplied stream \a s. The dumping should include the
+ /// section list if it has been parsed, and the symbol table
+ /// if it has been parsed.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ virtual void
+ Dump (Stream *s) = 0;
+
+ //------------------------------------------------------------------
+ /// Find a ObjectFile plug-in that can parse \a file_spec.
+ ///
+ /// Scans all loaded plug-in interfaces that implement versions of
+ /// the ObjectFile plug-in interface and returns the first
+ /// instance that can parse the file.
+ ///
+ /// @param[in] module
+ /// The parent module that owns this object file.
+ ///
+ /// @param[in] file_spec
+ /// A file specification that indicates which file to use as the
+ /// object file.
+ ///
+ /// @param[in] file_offset
+ /// The offset into the file at which to start parsing the
+ /// object. This is for files that contain multiple
+ /// architectures or objects.
+ ///
+ /// @param[in] file_size
+ /// The size of the current object file if it can be determined
+ /// or if it is known. This can be zero.
+ ///
+ /// @see ObjectFile::ParseHeader()
+ //------------------------------------------------------------------
+ static lldb::ObjectFileSP
+ FindPlugin (const lldb::ModuleSP &module_sp,
+ const FileSpec* file_spec,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t &data_offset);
+
+ //------------------------------------------------------------------
+ /// Find a ObjectFile plug-in that can parse a file in memory.
+ ///
+ /// Scans all loaded plug-in interfaces that implement versions of
+ /// the ObjectFile plug-in interface and returns the first
+ /// instance that can parse the file.
+ ///
+ /// @param[in] module
+ /// The parent module that owns this object file.
+ ///
+ /// @param[in] process_sp
+ /// A shared pointer to the process whose memory space contains
+ /// an object file. This will be stored as a std::weak_ptr.
+ ///
+ /// @param[in] header_addr
+ /// The address of the header for the object file in memory.
+ //------------------------------------------------------------------
+ static lldb::ObjectFileSP
+ FindPlugin (const lldb::ModuleSP &module_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr,
+ lldb::DataBufferSP &file_data_sp);
+
+
+ static size_t
+ GetModuleSpecifications (const FileSpec &file,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ ModuleSpecList &specs);
+
+ static size_t
+ GetModuleSpecifications (const lldb_private::FileSpec& file,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ lldb_private::ModuleSpecList &specs);
+ //------------------------------------------------------------------
+ /// Split a path into a file path with object name.
+ ///
+ /// For paths like "/tmp/foo.a(bar.o)" we often need to split a path
+ /// up into the actual path name and into the object name so we can
+ /// make a valid object file from it.
+ ///
+ /// @param[in] path_with_object
+ /// A path that might contain an archive path with a .o file
+ /// specified in parens in the basename of the path.
+ ///
+ /// @param[out] archive_file
+ /// If \b true is returned, \a file_spec will be filled in with
+ /// the path to the archive.
+ ///
+ /// @param[out] archive_object
+ /// If \b true is returned, \a object will be filled in with
+ /// the name of the object inside the archive.
+ ///
+ /// @return
+ /// \b true if the path matches the pattern of archive + object
+ /// and \a archive_file and \a archive_object are modified,
+ /// \b false otherwise and \a archive_file and \a archive_object
+ /// are guaranteed to be remain unchanged.
+ //------------------------------------------------------------------
+ static bool
+ SplitArchivePathWithObject (const char *path_with_object,
+ lldb_private::FileSpec &archive_file,
+ lldb_private::ConstString &archive_object,
+ bool must_exist);
+
+ //------------------------------------------------------------------
+ /// Gets the address size in bytes for the current object file.
+ ///
+ /// @return
+ /// The size of an address in bytes for the currently selected
+ /// architecture (and object for archives). Returns zero if no
+ /// architecture or object has been selected.
+ //------------------------------------------------------------------
+ virtual uint32_t
+ GetAddressByteSize () const = 0;
+
+ //------------------------------------------------------------------
+ /// Get the address type given a file address in an object file.
+ ///
+ /// Many binary file formats know what kinds
+ /// This is primarily for ARM binaries, though it can be applied to
+ /// any executable file format that supports different opcode types
+ /// within the same binary. ARM binaries support having both ARM and
+ /// Thumb within the same executable container. We need to be able
+ /// to get
+ /// @return
+ /// The size of an address in bytes for the currently selected
+ /// architecture (and object for archives). Returns zero if no
+ /// architecture or object has been selected.
+ //------------------------------------------------------------------
+ virtual lldb::AddressClass
+ GetAddressClass (lldb::addr_t file_addr);
+
+ //------------------------------------------------------------------
+ /// Extract the dependent modules from an object file.
+ ///
+ /// If an object file has information about which other images it
+ /// depends on (such as shared libraries), this function will
+ /// provide the list. Since many executables or shared libraries
+ /// may depend on the same files,
+ /// FileSpecList::AppendIfUnique(const FileSpec &) should be
+ /// used to make sure any files that are added are not already in
+ /// the list.
+ ///
+ /// @param[out] file_list
+ /// A list of file specification objects that gets dependent
+ /// files appended to.
+ ///
+ /// @return
+ /// The number of new files that were appended to \a file_list.
+ ///
+ /// @see FileSpecList::AppendIfUnique(const FileSpec &)
+ //------------------------------------------------------------------
+ virtual uint32_t
+ GetDependentModules (FileSpecList& file_list) = 0;
+
+ //------------------------------------------------------------------
+ /// Tells whether this object file is capable of being the main executable
+ /// for a process.
+ ///
+ /// @return
+ /// \b true if it is, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ IsExecutable () const = 0;
+
+ //------------------------------------------------------------------
+ /// Returns the offset into a file at which this object resides.
+ ///
+ /// Some files contain many object files, and this function allows
+ /// access to an object's offset within the file.
+ ///
+ /// @return
+ /// The offset in bytes into the file. Defaults to zero for
+ /// simple object files that a represented by an entire file.
+ //------------------------------------------------------------------
+ virtual lldb::addr_t
+ GetFileOffset () const
+ { return m_file_offset; }
+
+ virtual lldb::addr_t
+ GetByteSize () const
+ { return m_length; }
+
+ //------------------------------------------------------------------
+ /// Get accessor to the object file specification.
+ ///
+ /// @return
+ /// The file specification object pointer if there is one, or
+ /// NULL if this object is only from memory.
+ //------------------------------------------------------------------
+ virtual FileSpec&
+ GetFileSpec() { return m_file; }
+
+ //------------------------------------------------------------------
+ /// Get const accessor to the object file specification.
+ ///
+ /// @return
+ /// The const file specification object pointer if there is one,
+ /// or NULL if this object is only from memory.
+ //------------------------------------------------------------------
+ virtual const FileSpec&
+ GetFileSpec() const { return m_file; }
+
+ //------------------------------------------------------------------
+ /// Get the name of the cpu, vendor and OS for this object file.
+ ///
+ /// This value is a string that represents the target triple where
+ /// the cpu type, the vendor and the OS are encoded into a string.
+ ///
+ /// @param[out] target_triple
+ /// The string value of the target triple.
+ ///
+ /// @return
+ /// \b True if the target triple was able to be computed, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ GetArchitecture (ArchSpec &arch) = 0;
+
+ //------------------------------------------------------------------
+ /// Gets the section list for the currently selected architecture
+ /// (and object for archives).
+ ///
+ /// Section list parsing can be deferred by ObjectFile instances
+ /// until this accessor is called the first time.
+ ///
+ /// @return
+ /// The list of sections contained in this object file.
+ //------------------------------------------------------------------
+ virtual SectionList *
+ GetSectionList ();
+
+ virtual void
+ CreateSections (SectionList &unified_section_list) = 0;
+
+ //------------------------------------------------------------------
+ /// Gets the symbol table for the currently selected architecture
+ /// (and object for archives).
+ ///
+ /// Symbol table parsing can be deferred by ObjectFile instances
+ /// until this accessor is called the first time.
+ ///
+ /// @return
+ /// The symbol table for this object file.
+ //------------------------------------------------------------------
+ virtual Symtab *
+ GetSymtab () = 0;
+
+ //------------------------------------------------------------------
+ /// Detect if this object file has been stripped of local symbols.
+ ///
+ /// @return
+ /// Return \b true if the object file has been stripped of local
+ /// symbols.
+ //------------------------------------------------------------------
+ virtual bool
+ IsStripped () = 0;
+
+ //------------------------------------------------------------------
+ /// Frees the symbol table.
+ ///
+ /// This function should only be used when an object file is
+ ///
+ /// @param[in] flags
+ /// eSymtabFromUnifiedSectionList: Whether to clear symbol table
+ /// for unified module section list, or object file.
+ ///
+ /// @return
+ /// The symbol table for this object file.
+ //------------------------------------------------------------------
+ virtual void
+ ClearSymtab ();
+
+ //------------------------------------------------------------------
+ /// Gets the UUID for this object file.
+ ///
+ /// If the object file format contains a UUID, the value should be
+ /// returned. Else ObjectFile instances should return the MD5
+ /// checksum of all of the bytes for the object file (or memory for
+ /// memory based object files).
+ ///
+ /// @return
+ /// Returns \b true if a UUID was successfully extracted into
+ /// \a uuid, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ GetUUID (lldb_private::UUID* uuid) = 0;
+
+ //------------------------------------------------------------------
+ /// Gets the symbol file spec list for this object file.
+ ///
+ /// If the object file format contains a debug symbol file link,
+ /// the values will be return in the FileSpecList.
+ ///
+ /// @return
+ /// Returns filespeclist.
+ //------------------------------------------------------------------
+ virtual lldb_private::FileSpecList
+ GetDebugSymbolFilePaths()
+ {
+ return FileSpecList();
+ }
+
+ //------------------------------------------------------------------
+ /// Gets whether endian swapping should occur when extracting data
+ /// from this object file.
+ ///
+ /// @return
+ /// Returns \b true if endian swapping is needed, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ virtual lldb::ByteOrder
+ GetByteOrder () const = 0;
+
+ //------------------------------------------------------------------
+ /// Attempts to parse the object header.
+ ///
+ /// This function is used as a test to see if a given plug-in
+ /// instance can parse the header data already contained in
+ /// ObjectFile::m_data. If an object file parser does not
+ /// recognize that magic bytes in a header, false should be returned
+ /// and the next plug-in can attempt to parse an object file.
+ ///
+ /// @return
+ /// Returns \b true if the header was parsed succesfully, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ ParseHeader () = 0;
+
+ //------------------------------------------------------------------
+ /// Returns a reference to the UnwindTable for this ObjectFile
+ ///
+ /// The UnwindTable contains FuncUnwinders objects for any function in
+ /// this ObjectFile. If a FuncUnwinders object hasn't been created yet
+ /// (i.e. the function has yet to be unwound in a stack walk), it
+ /// will be created when requested. Specifically, we do not create
+ /// FuncUnwinders objects for functions until they are needed.
+ ///
+ /// @return
+ /// Returns the unwind table for this object file.
+ //------------------------------------------------------------------
+ virtual lldb_private::UnwindTable&
+ GetUnwindTable () { return m_unwind_table; }
+
+ //------------------------------------------------------------------
+ /// Similar to Process::GetImageInfoAddress().
+ ///
+ /// Some platforms embed auxiliary structures useful to debuggers in the
+ /// address space of the inferior process. This method returns the address
+ /// of such a structure if the information can be resolved via entries in
+ /// the object file. ELF, for example, provides a means to hook into the
+ /// runtime linker so that a debugger may monitor the loading and unloading
+ /// of shared libraries.
+ ///
+ /// @return
+ /// The address of any auxiliary tables, or an invalid address if this
+ /// object file format does not support or contain such information.
+ virtual lldb_private::Address
+ GetImageInfoAddress () { return Address(); }
+
+ //------------------------------------------------------------------
+ /// Returns the address of the Entry Point in this object file - if
+ /// the object file doesn't have an entry point (because it is not an
+ /// executable file) then an invalid address is returned.
+ ///
+ /// @return
+ /// Returns the entry address for this module.
+ //------------------------------------------------------------------
+ virtual lldb_private::Address
+ GetEntryPointAddress () { return Address();}
+
+ //------------------------------------------------------------------
+ /// Returns the address that represents the header of this object
+ /// file.
+ ///
+ /// The header address is defined as where the header for the object
+ /// file is that describes the content of the file. If the header
+ /// doesn't appear in a section that is defined in the object file,
+ /// an address with no section is returned that has the file offset
+ /// set in the m_file_offset member of the lldb_private::Address object.
+ ///
+ /// @return
+ /// Returns the entry address for this module.
+ //------------------------------------------------------------------
+ virtual lldb_private::Address
+ GetHeaderAddress () { return Address(m_memory_addr);}
+
+
+ virtual uint32_t
+ GetNumThreadContexts ()
+ {
+ return 0;
+ }
+
+ virtual lldb::RegisterContextSP
+ GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
+ {
+ return lldb::RegisterContextSP();
+ }
+
+ //------------------------------------------------------------------
+ /// The object file should be able to calculate its type by looking
+ /// at its file header and possibly the sections or other data in
+ /// the object file. The file type is used in the debugger to help
+ /// select the correct plug-ins for the job at hand, so this is
+ /// important to get right. If any eTypeXXX definitions do not match
+ /// up with the type of file you are loading, please feel free to
+ /// add a new enumeration value.
+ ///
+ /// @return
+ /// The calculated file type for the current object file.
+ //------------------------------------------------------------------
+ virtual Type
+ CalculateType() = 0;
+
+ //------------------------------------------------------------------
+ /// In cases where the type can't be calculated (elf files), this
+ /// routine allows someone to explicitly set it. As an example,
+ /// SymbolVendorELF uses this routine to set eTypeDebugInfo when
+ /// loading debug link files.
+ virtual void
+ SetType (Type type)
+ {
+ m_type = type;
+ }
+
+ //------------------------------------------------------------------
+ /// The object file should be able to calculate the strata of the
+ /// object file.
+ ///
+ /// Many object files for platforms might be for either user space
+ /// debugging or for kernel debugging. If your object file subclass
+ /// can figure this out, it will help with debugger plug-in selection
+ /// when it comes time to debug.
+ ///
+ /// @return
+ /// The calculated object file strata for the current object
+ /// file.
+ //------------------------------------------------------------------
+ virtual Strata
+ CalculateStrata() = 0;
+
+ //------------------------------------------------------------------
+ /// Get the object file version numbers.
+ ///
+ /// Many object files have a set of version numbers that describe
+ /// the version of the executable or shared library. Typically there
+ /// are major, minor and build, but there may be more. This function
+ /// will extract the versions from object files if they are available.
+ ///
+ /// If \a versions is NULL, or if \a num_versions is 0, the return
+ /// value will indicate how many version numbers are available in
+ /// this object file. Then a subsequent call can be made to this
+ /// function with a value of \a versions and \a num_versions that
+ /// has enough storage to store some or all version numbers.
+ ///
+ /// @param[out] versions
+ /// A pointer to an array of uint32_t types that is \a num_versions
+ /// long. If this value is NULL, the return value will indicate
+ /// how many version numbers are required for a subsequent call
+ /// to this function so that all versions can be retrieved. If
+ /// the value is non-NULL, then at most \a num_versions of the
+ /// existing versions numbers will be filled into \a versions.
+ /// If there is no version information available, \a versions
+ /// will be filled with \a num_versions UINT32_MAX values
+ /// and zero will be returned.
+ ///
+ /// @param[in] num_versions
+ /// The maximum number of entries to fill into \a versions. If
+ /// this value is zero, then the return value will indicate
+ /// how many version numbers there are in total so another call
+ /// to this function can be make with adequate storage in
+ /// \a versions to get all of the version numbers. If \a
+ /// num_versions is less than the actual number of version
+ /// numbers in this object file, only \a num_versions will be
+ /// filled into \a versions (if \a versions is non-NULL).
+ ///
+ /// @return
+ /// This function always returns the number of version numbers
+ /// that this object file has regardless of the number of
+ /// version numbers that were copied into \a versions.
+ //------------------------------------------------------------------
+ virtual uint32_t
+ GetVersion (uint32_t *versions, uint32_t num_versions)
+ {
+ if (versions && num_versions)
+ {
+ for (uint32_t i=0; i<num_versions; ++i)
+ versions[i] = UINT32_MAX;
+ }
+ return 0;
+ }
+
+ //------------------------------------------------------------------
+ // Member Functions
+ //------------------------------------------------------------------
+ Type
+ GetType ()
+ {
+ if (m_type == eTypeInvalid)
+ m_type = CalculateType();
+ return m_type;
+ }
+
+ Strata
+ GetStrata ()
+ {
+ if (m_strata == eStrataInvalid)
+ m_strata = CalculateStrata();
+ return m_strata;
+ }
+
+ // When an object file is in memory, subclasses should try and lock
+ // the process weak pointer. If the process weak pointer produces a
+ // valid ProcessSP, then subclasses can call this function to read
+ // memory.
+ static lldb::DataBufferSP
+ ReadMemory (const lldb::ProcessSP &process_sp,
+ lldb::addr_t addr,
+ size_t byte_size);
+
+ size_t
+ GetData (off_t offset, size_t length, DataExtractor &data) const;
+
+ size_t
+ CopyData (off_t offset, size_t length, void *dst) const;
+
+ size_t
+ ReadSectionData (const Section *section,
+ off_t section_offset,
+ void *dst,
+ size_t dst_len) const;
+ size_t
+ ReadSectionData (const Section *section,
+ DataExtractor& section_data) const;
+
+ size_t
+ MemoryMapSectionData (const Section *section,
+ DataExtractor& section_data) const;
+
+ bool
+ IsInMemory () const
+ {
+ return m_memory_addr != LLDB_INVALID_ADDRESS;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ FileSpec m_file;
+ Type m_type;
+ Strata m_strata;
+ lldb::addr_t m_file_offset; ///< The offset in bytes into the file, or the address in memory
+ lldb::addr_t m_length; ///< The length of this object file if it is known (can be zero if length is unknown or can't be determined).
+ DataExtractor m_data; ///< The data for this object file so things can be parsed lazily.
+ lldb_private::UnwindTable m_unwind_table; /// < Table of FuncUnwinders objects created for this ObjectFile's functions
+ lldb::ProcessWP m_process_wp;
+ const lldb::addr_t m_memory_addr;
+ std::unique_ptr<lldb_private::SectionList> m_sections_ap;
+ std::unique_ptr<lldb_private::Symtab> m_symtab_ap;
+
+ //------------------------------------------------------------------
+ /// Sets the architecture for a module. At present the architecture
+ /// can only be set if it is invalid. It is not allowed to switch from
+ /// one concrete architecture to another.
+ ///
+ /// @param[in] new_arch
+ /// The architecture this module will be set to.
+ ///
+ /// @return
+ /// Returns \b true if the architecture was changed, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ bool SetModulesArchitecture (const ArchSpec &new_arch);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (ObjectFile);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ObjectFile_h_
+
diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h
new file mode 100644
index 000000000000..11c1cc7af9ab
--- /dev/null
+++ b/include/lldb/Symbol/Symbol.h
@@ -0,0 +1,317 @@
+//===-- Symbol.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Symbol_h_
+#define liblldb_Symbol_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/Mangled.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Symbol/SymbolContextScope.h"
+
+namespace lldb_private {
+
+class Symbol :
+ public SymbolContextScope
+{
+public:
+ // ObjectFile readers can classify their symbol table entries and searches can be made
+ // on specific types where the symbol values will have drastically different meanings
+ // and sorting requirements.
+ Symbol();
+
+ Symbol (uint32_t symID,
+ const char *name,
+ bool name_is_mangled,
+ lldb::SymbolType type,
+ bool external,
+ bool is_debug,
+ bool is_trampoline,
+ bool is_artificial,
+ const lldb::SectionSP &section_sp,
+ lldb::addr_t value,
+ lldb::addr_t size,
+ bool size_is_valid,
+ uint32_t flags);
+
+ Symbol (uint32_t symID,
+ const char *name,
+ bool name_is_mangled,
+ lldb::SymbolType type,
+ bool external,
+ bool is_debug,
+ bool is_trampoline,
+ bool is_artificial,
+ const AddressRange &range,
+ bool size_is_valid,
+ uint32_t flags);
+
+ Symbol (const Symbol& rhs);
+
+ const Symbol&
+ operator= (const Symbol& rhs);
+
+ void
+ Clear();
+
+ bool
+ Compare (const ConstString& name, lldb::SymbolType type) const;
+
+ void
+ Dump (Stream *s, Target *target, uint32_t index) const;
+
+ bool
+ ValueIsAddress() const;
+
+ //------------------------------------------------------------------
+ // Access the address value. Do NOT hand out the AddressRange as an
+ // object as the byte size of the address range may not be filled in
+ // and it should be accessed via GetByteSize().
+ //------------------------------------------------------------------
+ Address &
+ GetAddress()
+ {
+ return m_addr_range.GetBaseAddress();
+ }
+
+ //------------------------------------------------------------------
+ // Access the address value. Do NOT hand out the AddressRange as an
+ // object as the byte size of the address range may not be filled in
+ // and it should be accessed via GetByteSize().
+ //------------------------------------------------------------------
+ const Address &
+ GetAddress() const
+ {
+ return m_addr_range.GetBaseAddress();
+ }
+
+ const ConstString &
+ GetName () const
+ {
+ return m_mangled.GetName();
+ }
+
+ uint32_t
+ GetID() const
+ {
+ return m_uid;
+ }
+
+ void
+ SetID(uint32_t uid)
+ {
+ m_uid = uid;
+ }
+
+ Mangled&
+ GetMangled ()
+ {
+ return m_mangled;
+ }
+
+ const Mangled&
+ GetMangled () const
+ {
+ return m_mangled;
+ }
+
+ uint32_t
+ GetSiblingIndex () const;
+
+ lldb::SymbolType
+ GetType () const
+ {
+ return (lldb::SymbolType)m_type;
+ }
+
+ void
+ SetType (lldb::SymbolType type)
+ {
+ m_type = (lldb::SymbolType)type;
+ }
+
+ const char *
+ GetTypeAsString () const;
+
+ uint32_t
+ GetFlags () const
+ {
+ return m_flags;
+ }
+
+ void
+ SetFlags (uint32_t flags)
+ {
+ m_flags = flags;
+ }
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const;
+
+ bool
+ IsSynthetic () const
+ {
+ return m_is_synthetic;
+ }
+
+ void
+ SetIsSynthetic (bool b)
+ {
+ m_is_synthetic = b;
+ }
+
+
+ bool
+ GetSizeIsSynthesized() const
+ {
+ return m_size_is_synthesized;
+ }
+
+ void
+ SetSizeIsSynthesized(bool b)
+ {
+ m_size_is_synthesized = b;
+ }
+
+ bool
+ IsDebug () const
+ {
+ return m_is_debug;
+ }
+
+ void
+ SetDebug (bool b)
+ {
+ m_is_debug = b;
+ }
+
+ bool
+ IsExternal () const
+ {
+ return m_is_external;
+ }
+
+ void
+ SetExternal (bool b)
+ {
+ m_is_external = b;
+ }
+
+ bool
+ IsTrampoline () const;
+
+ bool
+ IsIndirect () const;
+
+ bool
+ GetByteSizeIsValid () const
+ {
+ return m_size_is_valid;
+ }
+
+ lldb::addr_t
+ GetByteSize () const;
+
+ void
+ SetByteSize (lldb::addr_t size)
+ {
+ m_size_is_valid = size > 0;
+ m_addr_range.SetByteSize(size);
+ }
+
+ bool
+ GetSizeIsSibling () const
+ {
+ return m_size_is_sibling;
+ }
+
+ void
+ SetSizeIsSibling (bool b)
+ {
+ m_size_is_sibling = b;
+ }
+
+// void
+// SetValue (Address &value)
+// {
+// m_addr_range.GetBaseAddress() = value;
+// }
+//
+// void
+// SetValue (const AddressRange &range)
+// {
+// m_addr_range = range;
+// }
+//
+// void
+// SetValue (lldb::addr_t value);
+// {
+// m_addr_range.GetBaseAddress().SetRawAddress(value);
+// }
+
+ // If m_type is "Code" or "Function" then this will return the prologue size
+ // in bytes, else it will return zero.
+ uint32_t
+ GetPrologueByteSize ();
+
+ bool
+ GetDemangledNameIsSynthesized() const
+ {
+ return m_demangled_is_synthesized;
+ }
+ void
+ SetDemangledNameIsSynthesized(bool b)
+ {
+ m_demangled_is_synthesized = b;
+ }
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext (SymbolContext *sc);
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ();
+
+ virtual Symbol *
+ CalculateSymbolContextSymbol ();
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext (Stream *s);
+
+protected:
+
+ uint32_t m_uid; // User ID (usually the original symbol table index)
+ uint16_t m_type_data; // data specific to m_type
+ uint16_t m_type_data_resolved:1, // True if the data in m_type_data has already been calculated
+ m_is_synthetic:1, // non-zero if this symbol is not actually in the symbol table, but synthesized from other info in the object file.
+ m_is_debug:1, // non-zero if this symbol is debug information in a symbol
+ m_is_external:1, // non-zero if this symbol is globally visible
+ m_size_is_sibling:1, // m_size contains the index of this symbol's sibling
+ m_size_is_synthesized:1,// non-zero if this symbol's size was calculated using a delta between this symbol and the next
+ m_size_is_valid:1,
+ m_demangled_is_synthesized:1, // The demangled name was created should not be used for expressions or other lookups
+ m_type:8;
+ Mangled m_mangled; // uniqued symbol name/mangled name pair
+ AddressRange m_addr_range; // Contains the value, or the section offset address when the value is an address in a section, and the size (if any)
+ uint32_t m_flags; // A copy of the flags from the original symbol table, the ObjectFile plug-in can interpret these
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Symbol_h_
diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h
new file mode 100644
index 000000000000..5b12adebf5f5
--- /dev/null
+++ b/include/lldb/Symbol/SymbolContext.h
@@ -0,0 +1,566 @@
+//===-- SymbolContext.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef liblldb_SymbolContext_h_
+#define liblldb_SymbolContext_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/Mangled.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/LineEntry.h"
+
+namespace lldb_private {
+
+class SymbolContextScope;
+//----------------------------------------------------------------------
+/// @class SymbolContext SymbolContext.h "lldb/Symbol/SymbolContext.h"
+/// @brief Defines a symbol context baton that can be handed other debug
+/// core functions.
+///
+/// Many debugger functions require a context when doing lookups. This
+/// class provides a common structure that can be used as the result
+/// of a query that can contain a single result. Examples of such
+/// queries include
+/// @li Looking up a load address.
+//----------------------------------------------------------------------
+class SymbolContext
+{
+public:
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize all pointer members to NULL and all struct members
+ /// to their default state.
+ //------------------------------------------------------------------
+ SymbolContext ();
+
+ //------------------------------------------------------------------
+ /// Construct with an object that knows how to reconstruct its
+ /// symbol context.
+ ///
+ /// @param[in] sc_scope
+ /// A symbol context scope object that knows how to reconstruct
+ /// it's context.
+ //------------------------------------------------------------------
+ explicit
+ SymbolContext (SymbolContextScope *sc_scope);
+
+ //------------------------------------------------------------------
+ /// Construct with module, and optional compile unit, function,
+ /// block, line table, line entry and symbol.
+ ///
+ /// Initialize all pointer to the specified values.
+ ///
+ /// @param[in] module
+ /// A Module pointer to the module for this context.
+ ///
+ /// @param[in] comp_unit
+ /// A CompileUnit pointer to the compile unit for this context.
+ ///
+ /// @param[in] function
+ /// A Function pointer to the function for this context.
+ ///
+ /// @param[in] block
+ /// A Block pointer to the deepest block for this context.
+ ///
+ /// @param[in] line_entry
+ /// A LineEntry pointer to the line entry for this context.
+ ///
+ /// @param[in] symbol
+ /// A Symbol pointer to the symbol for this context.
+ //------------------------------------------------------------------
+ explicit
+ SymbolContext (const lldb::TargetSP &target_sp,
+ const lldb::ModuleSP &module_sp,
+ CompileUnit *comp_unit = NULL,
+ Function *function = NULL,
+ Block *block = NULL,
+ LineEntry *line_entry = NULL,
+ Symbol *symbol = NULL);
+
+ // This version sets the target to a NULL TargetSP if you don't know it.
+ explicit
+ SymbolContext (const lldb::ModuleSP &module_sp,
+ CompileUnit *comp_unit = NULL,
+ Function *function = NULL,
+ Block *block = NULL,
+ LineEntry *line_entry = NULL,
+ Symbol *symbol = NULL);
+
+ ~SymbolContext ();
+ //------------------------------------------------------------------
+ /// Copy constructor
+ ///
+ /// Makes a copy of the another SymbolContext object \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A const SymbolContext object reference to copy.
+ //------------------------------------------------------------------
+ SymbolContext (const SymbolContext& rhs);
+
+ //------------------------------------------------------------------
+ /// Assignment operator.
+ ///
+ /// Copies the address value from another SymbolContext object \a
+ /// rhs into \a this object.
+ ///
+ /// @param[in] rhs
+ /// A const SymbolContext object reference to copy.
+ ///
+ /// @return
+ /// A const SymbolContext object reference to \a this.
+ //------------------------------------------------------------------
+ const SymbolContext&
+ operator= (const SymbolContext& rhs);
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Resets all pointer members to NULL, and clears any class objects
+ /// to their default state.
+ //------------------------------------------------------------------
+ void
+ Clear (bool clear_target);
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Dump the stop context in this object to a Stream.
+ ///
+ /// Dump the best description of this object to the stream. The
+ /// information displayed depends on the amount and quality of the
+ /// information in this context. If a module, function, file and
+ /// line number are available, they will be dumped. If only a
+ /// module and function or symbol name with offset is available,
+ /// that will be output. Else just the address at which the target
+ /// was stopped will be displayed.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] so_addr
+ /// The resolved section offset address.
+ //------------------------------------------------------------------
+ bool
+ DumpStopContext (Stream *s,
+ ExecutionContextScope *exe_scope,
+ const Address &so_addr,
+ bool show_fullpaths,
+ bool show_module,
+ bool show_inlined_frames) const;
+
+ //------------------------------------------------------------------
+ /// Get the address range contained within a symbol context.
+ ///
+ /// Address range priority is as follows:
+ /// - line_entry address range if line_entry is valid and eSymbolContextLineEntry is set in \a scope
+ /// - block address range if block is not NULL and eSymbolContextBlock is set in \a scope
+ /// - function address range if function is not NULL and eSymbolContextFunction is set in \a scope
+ /// - symbol address range if symbol is not NULL and eSymbolContextSymbol is set in \a scope
+ ///
+ /// @param[in] scope
+ /// A mask of symbol context bits telling this function which
+ /// address ranges it can use when trying to extract one from
+ /// the valid (non-NULL) symbol context classes.
+ ///
+ /// @param[in] range_idx
+ /// The address range index to grab. Since many functions and
+ /// blocks are not always contiguous, they may have more than
+ /// one address range.
+ ///
+ /// @param[in] use_inline_block_range
+ /// If \a scope has the eSymbolContextBlock bit set, and there
+ /// is a valid block in the symbol context, return the block
+ /// address range for the containing inline function block, not
+ /// the deepest most block. This allows us to extract information
+ /// for the address range of the inlined function block, not
+ /// the deepest lexical block.
+ ///
+ /// @param[out] range
+ /// An address range object that will be filled in if \b true
+ /// is returned.
+ ///
+ /// @return
+ /// \b True if this symbol context contains items that describe
+ /// an address range, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetAddressRange (uint32_t scope,
+ uint32_t range_idx,
+ bool use_inline_block_range,
+ AddressRange &range) const;
+
+
+ void
+ GetDescription(Stream *s,
+ lldb::DescriptionLevel level,
+ Target *target) const;
+
+ uint32_t
+ GetResolvedMask () const;
+
+
+ //------------------------------------------------------------------
+ /// Find a block that defines the function represented by this
+ /// symbol context.
+ ///
+ /// If this symbol context points to a block that is an inlined
+ /// function, or is contained within an inlined function, the block
+ /// that defines the inlined function is returned.
+ ///
+ /// If this symbol context has no block in it, or the block is not
+ /// itself an inlined function block or contained within one, we
+ /// return the top level function block.
+ ///
+ /// This is a handy function to call when you want to get the block
+ /// whose variable list will include the arguments for the function
+ /// that is represented by this symbol context (whether the function
+ /// is an inline function or not).
+ ///
+ /// @return
+ /// The block object pointer that defines the function that is
+ /// represented by this symbol context object, NULL otherwise.
+ //------------------------------------------------------------------
+ Block *
+ GetFunctionBlock ();
+
+
+ //------------------------------------------------------------------
+ /// If this symbol context represents a function that is a method,
+ /// return true and provide information about the method.
+ ///
+ /// @param[out] language
+ /// If \b true is returned, the language for the method.
+ ///
+ /// @param[out] is_instance_method
+ /// If \b true is returned, \b true if this is a instance method,
+ /// \b false if this is a static/class function.
+ ///
+ /// @param[out] language_object_name
+ /// If \b true is returned, the name of the artificial variable
+ /// for the language ("this" for C++, "self" for ObjC).
+ ///
+ /// @return
+ /// \b True if this symbol context represents a function that
+ /// is a method of a class, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetFunctionMethodInfo (lldb::LanguageType &language,
+ bool &is_instance_method,
+ ConstString &language_object_name);
+
+ //------------------------------------------------------------------
+ /// Find a name of the innermost function for the symbol context.
+ ///
+ /// For instance, if the symbol context contains an inlined block,
+ /// it will return the inlined function name.
+ ///
+ /// @param[in] prefer_mangled
+ /// if \btrue, then the mangled name will be returned if there
+ /// is one. Otherwise the unmangled name will be returned if it
+ /// is available.
+ ///
+ /// @return
+ /// The name of the function represented by this symbol context.
+ //------------------------------------------------------------------
+ ConstString
+ GetFunctionName (Mangled::NamePreference preference = Mangled::ePreferDemangled) const;
+
+
+ //------------------------------------------------------------------
+ /// Get the line entry that corresponds to the function.
+ ///
+ /// If the symbol context contains an inlined block, the line entry
+ /// for the start address of the inlined function will be returned,
+ /// otherwise the line entry for the start address of the function
+ /// will be returned. This can be used after doing a
+ /// Module::FindFunctions(...) or ModuleList::FindFunctions(...)
+ /// call in order to get the correct line table information for
+ /// the symbol context.
+ /// it will return the inlined function name.
+ ///
+ /// @param[in] prefer_mangled
+ /// if \btrue, then the mangled name will be returned if there
+ /// is one. Otherwise the unmangled name will be returned if it
+ /// is available.
+ ///
+ /// @return
+ /// The name of the function represented by this symbol context.
+ //------------------------------------------------------------------
+ LineEntry
+ GetFunctionStartLineEntry () const;
+
+ //------------------------------------------------------------------
+ /// Find the block containing the inlined block that contains this block.
+ ///
+ /// For instance, if the symbol context contains an inlined block,
+ /// it will return the inlined function name.
+ ///
+ /// @param[in] curr_frame_pc
+ /// The address within the block of this object.
+ ///
+ /// @param[out] next_frame_sc
+ /// A new symbol context that does what the title says it does.
+ ///
+ /// @param[out] next_frame_addr
+ /// This is what you should report as the PC in \a next_frame_sc.
+ ///
+ /// @return
+ /// \b true if this SymbolContext specifies a block contained in an
+ /// inlined block. If this returns \b true, \a next_frame_sc and
+ /// \a next_frame_addr will be filled in correctly.
+ //------------------------------------------------------------------
+ bool
+ GetParentOfInlinedScope (const Address &curr_frame_pc,
+ SymbolContext &next_frame_sc,
+ Address &inlined_frame_addr) const;
+
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ lldb::TargetSP target_sp; ///< The Target for a given query
+ lldb::ModuleSP module_sp; ///< The Module for a given query
+ CompileUnit * comp_unit; ///< The CompileUnit for a given query
+ Function * function; ///< The Function for a given query
+ Block * block; ///< The Block for a given query
+ LineEntry line_entry; ///< The LineEntry for a given query
+ Symbol * symbol; ///< The Symbol for a given query
+};
+
+
+class SymbolContextSpecifier
+{
+public:
+ typedef enum SpecificationType
+ {
+ eNothingSpecified = 0,
+ eModuleSpecified = 1 << 0,
+ eFileSpecified = 1 << 1,
+ eLineStartSpecified = 1 << 2,
+ eLineEndSpecified = 1 << 3,
+ eFunctionSpecified = 1 << 4,
+ eClassOrNamespaceSpecified = 1 << 5,
+ eAddressRangeSpecified = 1 << 6
+ } SpecificationType;
+
+ // This one produces a specifier that matches everything...
+ SymbolContextSpecifier (const lldb::TargetSP& target_sp);
+
+ ~SymbolContextSpecifier();
+
+ bool
+ AddSpecification (const char *spec_string, SpecificationType type);
+
+ bool
+ AddLineSpecification (uint32_t line_no, SpecificationType type);
+
+ void
+ Clear();
+
+ bool
+ SymbolContextMatches(SymbolContext &sc);
+
+ bool
+ AddressMatches(lldb::addr_t addr);
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+private:
+ lldb::TargetSP m_target_sp;
+ std::string m_module_spec;
+ lldb::ModuleSP m_module_sp;
+ std::unique_ptr<FileSpec> m_file_spec_ap;
+ size_t m_start_line;
+ size_t m_end_line;
+ std::string m_function_spec;
+ std::string m_class_name;
+ std::unique_ptr<AddressRange> m_address_range_ap;
+ uint32_t m_type; // Or'ed bits from SpecificationType
+
+};
+
+//----------------------------------------------------------------------
+/// @class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h"
+/// @brief Defines a list of symbol context objects.
+///
+/// This class provides a common structure that can be used to contain
+/// the result of a query that can contain a multiple results. Examples
+/// of such queries include:
+/// @li Looking up a function by name.
+/// @li Finding all addressses for a specified file and line number.
+//----------------------------------------------------------------------
+class SymbolContextList
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize with an empty list.
+ //------------------------------------------------------------------
+ SymbolContextList ();
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~SymbolContextList ();
+
+ //------------------------------------------------------------------
+ /// Append a new symbol context to the list.
+ ///
+ /// @param[in] sc
+ /// A symbol context to append to the list.
+ //------------------------------------------------------------------
+ void
+ Append (const SymbolContext& sc);
+
+ void
+ Append (const SymbolContextList& sc_list);
+
+ bool
+ AppendIfUnique (const SymbolContext& sc,
+ bool merge_symbol_into_function);
+
+ bool
+ MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc,
+ uint32_t start_idx = 0,
+ uint32_t stop_idx = UINT32_MAX);
+
+ uint32_t
+ AppendIfUnique (const SymbolContextList& sc_list,
+ bool merge_symbol_into_function);
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Clears the symbol context list.
+ //------------------------------------------------------------------
+ void
+ Clear();
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of each symbol context in
+ /// the list to the supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump(Stream *s, Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for a symbol context at index \a idx.
+ ///
+ /// Dump a description of the contents of each symbol context in
+ /// the list to the supplied stream \a s.
+ ///
+ /// @param[in] idx
+ /// The zero based index into the symbol context list.
+ ///
+ /// @param[out] sc
+ /// A reference to the symbol context to fill in.
+ ///
+ /// @return
+ /// Returns \b true if \a idx was a valid index into this
+ /// symbol context list and \a sc was filled in, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetContextAtIndex(size_t idx, SymbolContext& sc) const;
+
+ //------------------------------------------------------------------
+ /// Direct reference accessor for a symbol context at index \a idx.
+ ///
+ /// The index \a idx must be a valid index, no error checking will
+ /// be done to ensure that it is valid.
+ ///
+ /// @param[in] idx
+ /// The zero based index into the symbol context list.
+ ///
+ /// @return
+ /// A const reference to the symbol context to fill in.
+ //------------------------------------------------------------------
+ SymbolContext&
+ operator [] (size_t idx)
+ {
+ return m_symbol_contexts[idx];
+ }
+
+ const SymbolContext&
+ operator [] (size_t idx) const
+ {
+ return m_symbol_contexts[idx];
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor for the last symbol context in the list.
+ ///
+ /// @param[out] sc
+ /// A reference to the symbol context to fill in.
+ ///
+ /// @return
+ /// Returns \b true if \a sc was filled in, \b false if the
+ /// list is empty.
+ //------------------------------------------------------------------
+ bool
+ GetLastContext(SymbolContext& sc) const;
+
+ bool
+ RemoveContextAtIndex (size_t idx);
+ //------------------------------------------------------------------
+ /// Get accessor for a symbol context list size.
+ ///
+ /// @return
+ /// Returns the number of symbol context objects in the list.
+ //------------------------------------------------------------------
+ uint32_t
+ GetSize() const;
+
+ uint32_t
+ NumLineEntriesWithLine (uint32_t line) const;
+
+ void
+ GetDescription(Stream *s,
+ lldb::DescriptionLevel level,
+ Target *target) const;
+
+protected:
+ typedef std::vector<SymbolContext> collection; ///< The collection type for the list.
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ collection m_symbol_contexts; ///< The list of symbol contexts.
+};
+
+bool operator== (const SymbolContext& lhs, const SymbolContext& rhs);
+bool operator!= (const SymbolContext& lhs, const SymbolContext& rhs);
+
+bool operator== (const SymbolContextList& lhs, const SymbolContextList& rhs);
+bool operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_SymbolContext_h_
diff --git a/include/lldb/Symbol/SymbolContextScope.h b/include/lldb/Symbol/SymbolContextScope.h
new file mode 100644
index 000000000000..693cc0131e27
--- /dev/null
+++ b/include/lldb/Symbol/SymbolContextScope.h
@@ -0,0 +1,137 @@
+//===-- SymbolContextScope.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SymbolContextScope_h_
+#define liblldb_SymbolContextScope_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class SymbolContextScope SymbolContextScope.h "lldb/Symbol/SymbolContextScope.h"
+/// @brief Inherit from this if your object is part of a symbol context
+/// and can reconstruct its symbol context.
+///
+/// Many objects that are part of a symbol context that have pointers
+/// back to parent objects that own them. Any members of a symbol
+/// context that, once they are built, will not go away, can inherit
+/// from this pure virtual class and can then reconstruct their symbol
+/// context without having to keep a complete SymbolContext object in
+/// the object.
+///
+/// Examples of these objects include:
+/// @li Module
+/// @li CompileUnit
+/// @li Function
+/// @li Block
+/// @li Symbol
+///
+/// Other objects can store a "SymbolContextScope *" using any pointers
+/// to one of the above objects. This allows clients to hold onto a
+/// pointer that uniquely will identify a symbol context. Those clients
+/// can then always reconstruct the symbol context using the pointer, or
+/// use it to uniquely identify a symbol context for an object.
+///
+/// Example objects include that currently use "SymbolContextScope *"
+/// objects include:
+/// @li Variable objects that can reconstruct where they are scoped
+/// by making sure the SymbolContextScope * comes from the scope
+/// in which the variable was declared. If a variable is a global,
+/// the appropriate CompileUnit * will be used when creating the
+/// variable. A static function variables, can the Block scope
+/// in which the variable is defined. Function arguments can use
+/// the Function object as their scope. The SymbolFile parsers
+/// will set these correctly as the variables are parsed.
+/// @li Type objects that know exactly in which scope they
+/// originated much like the variables above.
+/// @li StackID objects that are able to know that if the CFA
+/// (stack pointer at the beginning of a function) and the
+/// start PC for the function/symbol and the SymbolContextScope
+/// pointer (a unique pointer that identifies a symbol context
+/// location) match within the same thread, that the stack
+/// frame is the same as the previous stack frame.
+///
+/// Objects that adhere to this protocol can reconstruct enough of a
+/// symbol context to allow functions that take a symbol context to be
+/// called. Lists can also be created using a SymbolContextScope* and
+/// and object pairs that allow large collections of objects to be
+/// passed around with minimal overhead.
+//----------------------------------------------------------------------
+class SymbolContextScope
+{
+public:
+ virtual
+ ~SymbolContextScope () {}
+
+ //------------------------------------------------------------------
+ /// Reconstruct the object's symbolc context into \a sc.
+ ///
+ /// The object should fill in as much of the SymbolContext as it
+ /// can so function calls that require a symbol context can be made
+ /// for the given object.
+ ///
+ /// @param[out] sc
+ /// A symbol context object pointer that gets filled in.
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext (SymbolContext *sc) = 0;
+
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ()
+ {
+ return lldb::ModuleSP();
+ }
+
+ virtual CompileUnit *
+ CalculateSymbolContextCompileUnit ()
+ {
+ return NULL;
+ }
+
+ virtual Function *
+ CalculateSymbolContextFunction ()
+ {
+ return NULL;
+ }
+
+ virtual Block *
+ CalculateSymbolContextBlock ()
+ {
+ return NULL;
+ }
+
+ virtual Symbol *
+ CalculateSymbolContextSymbol ()
+ {
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Dump the object's symbolc context to the stream \a s.
+ ///
+ /// The object should dump its symbol context to the stream \a s.
+ /// This function is widely used in the DumpDebug and verbose output
+ /// for lldb objets.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object's symbol context.
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext (Stream *s) = 0;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_SymbolContextScope_h_
diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h
new file mode 100644
index 000000000000..5b774e3a7d13
--- /dev/null
+++ b/include/lldb/Symbol/SymbolFile.h
@@ -0,0 +1,167 @@
+//===-- SymbolFile.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SymbolFile_h_
+#define liblldb_SymbolFile_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/ClangNamespaceDecl.h"
+#include "lldb/Symbol/Type.h"
+
+namespace lldb_private {
+
+class SymbolFile :
+ public PluginInterface
+{
+public:
+ //------------------------------------------------------------------
+ // Symbol file ability bits.
+ //
+ // Each symbol file can claim to support one or more symbol file
+ // abilities. These get returned from SymbolFile::GetAbilities().
+ // These help us to determine which plug-in will be best to load
+ // the debug information found in files.
+ //------------------------------------------------------------------
+ enum Abilities
+ {
+ CompileUnits = (1u << 0),
+ LineTables = (1u << 1),
+ Functions = (1u << 2),
+ Blocks = (1u << 3),
+ GlobalVariables = (1u << 4),
+ LocalVariables = (1u << 5),
+ VariableTypes = (1u << 6),
+ kAllAbilities =((1u << 7) - 1u)
+ };
+
+ static SymbolFile *
+ FindPlugin (ObjectFile* obj_file);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFile(ObjectFile* obj_file) :
+ m_obj_file(obj_file),
+ m_abilities(0),
+ m_calculated_abilities(false)
+ {
+ }
+
+ virtual
+ ~SymbolFile()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Get a mask of what this symbol file supports for the object file
+ /// that it was constructed with.
+ ///
+ /// Each symbol file gets to respond with a mask of abilities that
+ /// it supports for each object file. This happens when we are
+ /// trying to figure out which symbol file plug-in will get used
+ /// for a given object file. The plug-in that resoonds with the
+ /// best mix of "SymbolFile::Abilities" bits set, will get chosen to
+ /// be the symbol file parser. This allows each plug-in to check for
+ /// sections that contain data a symbol file plug-in would need. For
+ /// example the DWARF plug-in requires DWARF sections in a file that
+ /// contain debug information. If the DWARF plug-in doesn't find
+ /// these sections, it won't respond with many ability bits set, and
+ /// we will probably fall back to the symbol table SymbolFile plug-in
+ /// which uses any information in the symbol table. Also, plug-ins
+ /// might check for some specific symbols in a symbol table in the
+ /// case where the symbol table contains debug information (STABS
+ /// and COFF). Not a lot of work should happen in these functions
+ /// as the plug-in might not get selected due to another plug-in
+ /// having more abilities. Any initialization work should be saved
+ /// for "void SymbolFile::InitializeObject()" which will get called
+ /// on the SymbolFile object with the best set of abilities.
+ ///
+ /// @return
+ /// A uint32_t mask containing bits from the SymbolFile::Abilities
+ /// enumeration. Any bits that are set represent an ability that
+ /// this symbol plug-in can parse from the object file.
+ ///------------------------------------------------------------------
+ uint32_t GetAbilities ()
+ {
+ if (!m_calculated_abilities)
+ {
+ m_abilities = CalculateAbilities();
+ m_calculated_abilities = true;
+ }
+
+ return m_abilities;
+ }
+
+ virtual uint32_t CalculateAbilities() = 0;
+
+ //------------------------------------------------------------------
+ /// Initialize the SymbolFile object.
+ ///
+ /// The SymbolFile object with the best set of abilities (detected
+ /// in "uint32_t SymbolFile::GetAbilities()) will have this function
+ /// called if it is chosen to parse an object file. More complete
+ /// initialization can happen in this function which will get called
+ /// prior to any other functions in the SymbolFile protocol.
+ //------------------------------------------------------------------
+ virtual void InitializeObject() {}
+
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
+ // Approach 1 - iterator
+ virtual uint32_t GetNumCompileUnits() = 0;
+ virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) = 0;
+
+ virtual lldb::LanguageType ParseCompileUnitLanguage (const SymbolContext& sc) = 0;
+ virtual size_t ParseCompileUnitFunctions (const SymbolContext& sc) = 0;
+ virtual bool ParseCompileUnitLineTable (const SymbolContext& sc) = 0;
+ virtual bool ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) = 0;
+ virtual size_t ParseFunctionBlocks (const SymbolContext& sc) = 0;
+ virtual size_t ParseTypes (const SymbolContext& sc) = 0;
+ virtual size_t ParseVariablesForContext (const SymbolContext& sc) = 0;
+ virtual Type* ResolveTypeUID (lldb::user_id_t type_uid) = 0;
+ virtual bool ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) = 0;
+ virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) { return NULL; }
+ virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) { return NULL; }
+ virtual uint32_t ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) = 0;
+ virtual uint32_t ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) = 0;
+ virtual uint32_t FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables) = 0;
+ virtual uint32_t FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) = 0;
+ virtual uint32_t FindFunctions (const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list) = 0;
+ virtual uint32_t FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) = 0;
+ virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types) = 0;
+// virtual uint32_t FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) = 0;
+ virtual TypeList * GetTypeList ();
+ virtual size_t GetTypes (lldb_private::SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) = 0;
+ virtual ClangASTContext &
+ GetClangASTContext ();
+ virtual ClangNamespaceDecl
+ FindNamespace (const SymbolContext& sc,
+ const ConstString &name,
+ const ClangNamespaceDecl *parent_namespace_decl) = 0;
+
+ ObjectFile* GetObjectFile() { return m_obj_file; }
+ const ObjectFile* GetObjectFile() const { return m_obj_file; }
+
+protected:
+ ObjectFile* m_obj_file; // The object file that symbols can be extracted from.
+ uint32_t m_abilities;
+ bool m_calculated_abilities;
+private:
+ DISALLOW_COPY_AND_ASSIGN (SymbolFile);
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_SymbolFile_h_
diff --git a/include/lldb/Symbol/SymbolVendor.h b/include/lldb/Symbol/SymbolVendor.h
new file mode 100644
index 000000000000..0eeea4eb466b
--- /dev/null
+++ b/include/lldb/Symbol/SymbolVendor.h
@@ -0,0 +1,207 @@
+//===-- SymbolVendor.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SymbolVendor_h_
+#define liblldb_SymbolVendor_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/ClangNamespaceDecl.h"
+#include "lldb/Symbol/TypeList.h"
+
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// The symbol vendor class is designed to abstract the process of
+// searching for debug information for a given module. Platforms can
+// subclass this class and provide extra ways to find debug information.
+// Examples would be a subclass that would allow for locating a stand
+// alone debug file, parsing debug maps, or runtime data in the object
+// files. A symbol vendor can use multiple sources (SymbolFile
+// objects) to provide the information and only parse as deep as needed
+// in order to provide the information that is requested.
+//----------------------------------------------------------------------
+class SymbolVendor :
+ public ModuleChild,
+ public PluginInterface
+{
+public:
+ static SymbolVendor*
+ FindPlugin (const lldb::ModuleSP &module_sp,
+ Stream *feedback_strm);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolVendor(const lldb::ModuleSP &module_sp);
+
+ virtual
+ ~SymbolVendor();
+
+ void
+ AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp);
+
+ virtual void
+ Dump(Stream *s);
+
+ virtual lldb::LanguageType
+ ParseCompileUnitLanguage (const SymbolContext& sc);
+
+ virtual size_t
+ ParseCompileUnitFunctions (const SymbolContext& sc);
+
+ virtual bool
+ ParseCompileUnitLineTable (const SymbolContext& sc);
+
+ virtual bool
+ ParseCompileUnitSupportFiles (const SymbolContext& sc,
+ FileSpecList& support_files);
+
+ virtual size_t
+ ParseFunctionBlocks (const SymbolContext& sc);
+
+ virtual size_t
+ ParseTypes (const SymbolContext& sc);
+
+ virtual size_t
+ ParseVariablesForContext (const SymbolContext& sc);
+
+ virtual Type*
+ ResolveTypeUID(lldb::user_id_t type_uid);
+
+ virtual uint32_t
+ ResolveSymbolContext (const Address& so_addr,
+ uint32_t resolve_scope,
+ SymbolContext& sc);
+
+ virtual uint32_t
+ ResolveSymbolContext (const FileSpec& file_spec,
+ uint32_t line,
+ bool check_inlines,
+ uint32_t resolve_scope,
+ SymbolContextList& sc_list);
+
+ virtual size_t
+ FindGlobalVariables (const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ bool append,
+ size_t max_matches,
+ VariableList& variables);
+
+ virtual size_t
+ FindGlobalVariables (const RegularExpression& regex,
+ bool append,
+ size_t max_matches,
+ VariableList& variables);
+
+ virtual size_t
+ FindFunctions (const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ uint32_t name_type_mask,
+ bool include_inlines,
+ bool append,
+ SymbolContextList& sc_list);
+
+ virtual size_t
+ FindFunctions (const RegularExpression& regex,
+ bool include_inlines,
+ bool append,
+ SymbolContextList& sc_list);
+
+ virtual size_t
+ FindTypes (const SymbolContext& sc,
+ const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ bool append,
+ size_t max_matches,
+ TypeList& types);
+
+ virtual ClangNamespaceDecl
+ FindNamespace (const SymbolContext& sc,
+ const ConstString &name,
+ const ClangNamespaceDecl *parent_namespace_decl);
+
+ virtual size_t
+ GetNumCompileUnits();
+
+ virtual bool
+ SetCompileUnitAtIndex (size_t cu_idx,
+ const lldb::CompUnitSP &cu_sp);
+
+ virtual lldb::CompUnitSP
+ GetCompileUnitAtIndex(size_t idx);
+
+ TypeList&
+ GetTypeList()
+ {
+ return m_type_list;
+ }
+
+ const TypeList&
+ GetTypeList() const
+ {
+ return m_type_list;
+ }
+
+ virtual size_t
+ GetTypes (SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ TypeList &type_list);
+
+ SymbolFile *
+ GetSymbolFile()
+ {
+ return m_sym_file_ap.get();
+ }
+
+ // Get module unified section list symbol table.
+ virtual Symtab *
+ GetSymtab ();
+
+ // Clear module unified section list symbol table.
+ virtual void
+ ClearSymtab ();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual ConstString
+ GetPluginName();
+
+ virtual uint32_t
+ GetPluginVersion();
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from SymbolVendor can see and modify these
+ //------------------------------------------------------------------
+ typedef std::vector<lldb::CompUnitSP> CompileUnits;
+ typedef CompileUnits::iterator CompileUnitIter;
+ typedef CompileUnits::const_iterator CompileUnitConstIter;
+
+ TypeList m_type_list; // Uniqued types for all parsers owned by this module
+ CompileUnits m_compile_units; // The current compile units
+ lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in case it isn't the same as the module object file (debug symbols in a separate file)
+ std::unique_ptr<SymbolFile> m_sym_file_ap; // A single symbol file. Subclasses can add more of these if needed.
+
+private:
+ //------------------------------------------------------------------
+ // For SymbolVendor only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (SymbolVendor);
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_SymbolVendor_h_
diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h
new file mode 100644
index 000000000000..666c3b5686b9
--- /dev/null
+++ b/include/lldb/Symbol/Symtab.h
@@ -0,0 +1,160 @@
+//===-- Symtab.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef liblldb_Symtab_h_
+#define liblldb_Symtab_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/Symbol.h"
+
+namespace lldb_private {
+
+class Symtab
+{
+public:
+ typedef std::vector<uint32_t> IndexCollection;
+ typedef UniqueCStringMap<uint32_t> NameToIndexMap;
+
+ typedef enum Debug {
+ eDebugNo, // Not a debug symbol
+ eDebugYes, // A debug symbol
+ eDebugAny
+ } Debug;
+
+ typedef enum Visibility {
+ eVisibilityAny,
+ eVisibilityExtern,
+ eVisibilityPrivate
+ } Visibility;
+
+ Symtab(ObjectFile *objfile);
+ ~Symtab();
+
+ void Reserve (size_t count);
+ Symbol * Resize (size_t count);
+ uint32_t AddSymbol(const Symbol& symbol);
+ size_t GetNumSymbols() const;
+ void Dump(Stream *s, Target *target, SortOrder sort_type);
+ void Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const;
+ uint32_t GetIndexForSymbol (const Symbol *symbol) const;
+ Mutex & GetMutex ()
+ {
+ return m_mutex;
+ }
+ Symbol * FindSymbolByID (lldb::user_id_t uid) const;
+ Symbol * SymbolAtIndex (size_t idx);
+ const Symbol * SymbolAtIndex (size_t idx) const;
+ Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx);
+ uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
+ uint32_t AppendSymbolIndexesWithTypeAndFlagsValue (lldb::SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
+ uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
+ uint32_t AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& matches);
+ uint32_t AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches);
+ uint32_t AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, lldb::SymbolType symbol_type, std::vector<uint32_t>& matches);
+ uint32_t AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches);
+ uint32_t AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regex, lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes);
+ uint32_t AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes);
+ size_t FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes);
+ size_t FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes);
+ size_t FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes);
+ Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility);
+ Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes);
+ Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr);
+ size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list);
+ void CalculateSymbolSizes ();
+
+ void SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const;
+
+ static void DumpSymbolHeader (Stream *s);
+
+
+ void Finalize ()
+ {
+ // Shrink to fit the symbols so we don't waste memory
+ if (m_symbols.capacity() > m_symbols.size())
+ {
+ collection new_symbols (m_symbols.begin(), m_symbols.end());
+ m_symbols.swap (new_symbols);
+ }
+ }
+
+ void AppendSymbolNamesToMap (const IndexCollection &indexes,
+ bool add_demangled,
+ bool add_mangled,
+ NameToIndexMap &name_to_index_map) const;
+
+protected:
+ typedef std::vector<Symbol> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+ typedef RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> FileRangeToIndexMap;
+ void InitNameIndexes ();
+ void InitAddressIndexes ();
+
+ ObjectFile * m_objfile;
+ collection m_symbols;
+ FileRangeToIndexMap m_file_addr_to_index;
+ UniqueCStringMap<uint32_t> m_name_to_index;
+ UniqueCStringMap<uint32_t> m_basename_to_index;
+ UniqueCStringMap<uint32_t> m_method_to_index;
+ UniqueCStringMap<uint32_t> m_selector_to_index;
+ mutable Mutex m_mutex; // Provide thread safety for this symbol table
+ bool m_file_addr_to_index_computed:1,
+ m_name_indexes_computed:1;
+private:
+
+ bool
+ CheckSymbolAtIndex (size_t idx, Debug symbol_debug_type, Visibility symbol_visibility) const
+ {
+ switch (symbol_debug_type)
+ {
+ case eDebugNo:
+ if (m_symbols[idx].IsDebug() == true)
+ return false;
+ break;
+
+ case eDebugYes:
+ if (m_symbols[idx].IsDebug() == false)
+ return false;
+ break;
+
+ case eDebugAny:
+ break;
+ }
+
+ switch (symbol_visibility)
+ {
+ case eVisibilityAny:
+ return true;
+
+ case eVisibilityExtern:
+ return m_symbols[idx].IsExternal();
+
+ case eVisibilityPrivate:
+ return !m_symbols[idx].IsExternal();
+ }
+ return false;
+ }
+
+ void
+ SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes,
+ SymbolContextList &sc_list);
+
+ DISALLOW_COPY_AND_ASSIGN (Symtab);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Symtab_h_
diff --git a/include/lldb/Symbol/TaggedASTType.h b/include/lldb/Symbol/TaggedASTType.h
new file mode 100644
index 000000000000..c44a5356f86d
--- /dev/null
+++ b/include/lldb/Symbol/TaggedASTType.h
@@ -0,0 +1,61 @@
+//===-- TaggedASTType.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TaggedASTType_h_
+#define liblldb_TaggedASTType_h_
+
+#include "lldb/Symbol/ClangASTType.h"
+
+namespace lldb_private
+{
+
+// For cases in which there are multiple classes of types that are not
+// interchangeable, to allow static type checking.
+template <unsigned int C> class TaggedASTType : public ClangASTType
+{
+public:
+ TaggedASTType (const ClangASTType &clang_type) :
+ ClangASTType(clang_type)
+ {
+ }
+
+ TaggedASTType (lldb::clang_type_t type, clang::ASTContext *ast_context) :
+ ClangASTType(ast_context, type)
+ {
+ }
+
+ TaggedASTType (const TaggedASTType<C> &tw) :
+ ClangASTType(tw)
+ {
+ }
+
+ TaggedASTType () :
+ ClangASTType()
+ {
+ }
+
+ virtual
+ ~TaggedASTType()
+ {
+ }
+
+ TaggedASTType<C> &operator= (const TaggedASTType<C> &tw)
+ {
+ ClangASTType::operator= (tw);
+ return *this;
+ }
+};
+
+// Commonly-used tagged types, so code using them is interoperable
+typedef TaggedASTType<0> TypeFromParser;
+typedef TaggedASTType<1> TypeFromUser;
+
+}
+
+#endif
diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h
new file mode 100644
index 000000000000..50b22fe96b9d
--- /dev/null
+++ b/include/lldb/Symbol/Type.h
@@ -0,0 +1,596 @@
+//===-- Type.h --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Type_h_
+#define liblldb_Type_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/Declaration.h"
+
+#include <set>
+
+namespace lldb_private {
+
+class SymbolFileType :
+ public std::enable_shared_from_this<SymbolFileType>,
+ public UserID
+ {
+ public:
+ SymbolFileType (SymbolFile &symbol_file, lldb::user_id_t uid) :
+ UserID (uid),
+ m_symbol_file (symbol_file)
+ {
+ }
+
+ ~SymbolFileType ()
+ {
+ }
+
+ Type *
+ operator->()
+ {
+ return GetType ();
+ }
+
+ Type *
+ GetType ();
+
+ protected:
+ SymbolFile &m_symbol_file;
+ lldb::TypeSP m_type_sp;
+ };
+
+class Type :
+ public std::enable_shared_from_this<Type>,
+ public UserID
+{
+public:
+ typedef enum EncodingDataTypeTag
+ {
+ eEncodingInvalid,
+ eEncodingIsUID, ///< This type is the type whose UID is m_encoding_uid
+ eEncodingIsConstUID, ///< This type is the type whose UID is m_encoding_uid with the const qualifier added
+ eEncodingIsRestrictUID, ///< This type is the type whose UID is m_encoding_uid with the restrict qualifier added
+ eEncodingIsVolatileUID, ///< This type is the type whose UID is m_encoding_uid with the volatile qualifier added
+ eEncodingIsTypedefUID, ///< This type is pointer to a type whose UID is m_encoding_uid
+ eEncodingIsPointerUID, ///< This type is pointer to a type whose UID is m_encoding_uid
+ eEncodingIsLValueReferenceUID, ///< This type is L value reference to a type whose UID is m_encoding_uid
+ eEncodingIsRValueReferenceUID, ///< This type is R value reference to a type whose UID is m_encoding_uid
+ eEncodingIsSyntheticUID
+ } EncodingDataType;
+
+ typedef enum ResolveStateTag
+ {
+ eResolveStateUnresolved = 0,
+ eResolveStateForward = 1,
+ eResolveStateLayout = 2,
+ eResolveStateFull = 3
+ } ResolveState;
+
+ Type (lldb::user_id_t uid,
+ SymbolFile* symbol_file,
+ const ConstString &name,
+ uint64_t byte_size,
+ SymbolContextScope *context,
+ lldb::user_id_t encoding_uid,
+ EncodingDataType encoding_uid_type,
+ const Declaration& decl,
+ const ClangASTType &clang_qual_type,
+ ResolveState clang_type_resolve_state);
+
+ // This makes an invalid type. Used for functions that return a Type when they
+ // get an error.
+ Type();
+
+ Type (const Type &rhs);
+
+ const Type&
+ operator= (const Type& rhs);
+
+ void
+ Dump(Stream *s, bool show_context);
+
+ void
+ DumpTypeName(Stream *s);
+
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name);
+
+ SymbolFile *
+ GetSymbolFile()
+ {
+ return m_symbol_file;
+ }
+ const SymbolFile *
+ GetSymbolFile() const
+ {
+ return m_symbol_file;
+ }
+
+ TypeList*
+ GetTypeList();
+
+ const ConstString&
+ GetName();
+
+ uint64_t
+ GetByteSize();
+
+ uint32_t
+ GetNumChildren (bool omit_empty_base_classes);
+
+ bool
+ IsAggregateType ();
+
+ bool
+ IsValidType ()
+ {
+ return m_encoding_uid_type != eEncodingInvalid;
+ }
+
+ bool
+ IsTypedef ()
+ {
+ return m_encoding_uid_type == eEncodingIsTypedefUID;
+ }
+
+ lldb::TypeSP
+ GetTypedefType();
+
+ const ConstString &
+ GetName () const
+ {
+ return m_name;
+ }
+
+ ConstString
+ GetQualifiedName ();
+
+ void
+ DumpValue(ExecutionContext *exe_ctx,
+ Stream *s,
+ const DataExtractor &data,
+ uint32_t data_offset,
+ bool show_type,
+ bool show_summary,
+ bool verbose,
+ lldb::Format format = lldb::eFormatDefault);
+
+ bool
+ DumpValueInMemory(ExecutionContext *exe_ctx,
+ Stream *s,
+ lldb::addr_t address,
+ AddressType address_type,
+ bool show_types,
+ bool show_summary,
+ bool verbose);
+
+ bool
+ ReadFromMemory (ExecutionContext *exe_ctx,
+ lldb::addr_t address,
+ AddressType address_type,
+ DataExtractor &data);
+
+ bool
+ WriteToMemory (ExecutionContext *exe_ctx,
+ lldb::addr_t address,
+ AddressType address_type,
+ DataExtractor &data);
+
+ bool
+ GetIsDeclaration() const;
+
+ void
+ SetIsDeclaration(bool b);
+
+ bool
+ GetIsExternal() const;
+
+ void
+ SetIsExternal(bool b);
+
+ lldb::Format
+ GetFormat ();
+
+ lldb::Encoding
+ GetEncoding (uint64_t &count);
+
+ SymbolContextScope *
+ GetSymbolContextScope()
+ {
+ return m_context;
+ }
+ const SymbolContextScope *
+ GetSymbolContextScope() const
+ {
+ return m_context;
+ }
+ void
+ SetSymbolContextScope(SymbolContextScope *context)
+ {
+ m_context = context;
+ }
+
+ const lldb_private::Declaration &
+ GetDeclaration () const;
+
+ // Get the clang type, and resolve definitions for any
+ // class/struct/union/enum types completely.
+ ClangASTType
+ GetClangFullType ();
+
+ // Get the clang type, and resolve definitions enough so that the type could
+ // have layout performed. This allows ptrs and refs to class/struct/union/enum
+ // types remain forward declarations.
+ ClangASTType
+ GetClangLayoutType ();
+
+ // Get the clang type and leave class/struct/union/enum types as forward
+ // declarations if they haven't already been fully defined.
+ ClangASTType
+ GetClangForwardType ();
+
+ ClangASTContext &
+ GetClangASTContext ();
+
+ static int
+ Compare(const Type &a, const Type &b);
+
+ // From a fully qualified typename, split the type into the type basename
+ // and the remaining type scope (namespaces/classes).
+ static bool
+ GetTypeScopeAndBasename (const char* &name_cstr,
+ std::string &scope,
+ std::string &basename,
+ lldb::TypeClass &type_class);
+ void
+ SetEncodingType (Type *encoding_type)
+ {
+ m_encoding_type = encoding_type;
+ }
+
+ uint32_t
+ GetEncodingMask ();
+
+ ClangASTType
+ CreateClangTypedefType (Type *typedef_type, Type *base_type);
+
+ bool
+ IsRealObjCClass();
+
+ bool
+ IsCompleteObjCClass()
+ {
+ return m_flags.is_complete_objc_class;
+ }
+
+ void
+ SetIsCompleteObjCClass(bool is_complete_objc_class)
+ {
+ m_flags.is_complete_objc_class = is_complete_objc_class;
+ }
+
+protected:
+ ConstString m_name;
+ SymbolFile *m_symbol_file;
+ SymbolContextScope *m_context; // The symbol context in which this type is defined
+ Type *m_encoding_type;
+ lldb::user_id_t m_encoding_uid;
+ EncodingDataType m_encoding_uid_type;
+ uint64_t m_byte_size;
+ Declaration m_decl;
+ ClangASTType m_clang_type;
+
+ struct Flags {
+ ResolveState clang_type_resolve_state : 2;
+ bool is_complete_objc_class : 1;
+ } m_flags;
+
+ Type *
+ GetEncodingType ();
+
+ bool
+ ResolveClangType (ResolveState clang_type_resolve_state);
+};
+
+
+///
+/// Sometimes you can find the name of the type corresponding to an object, but we don't have debug
+/// information for it. If that is the case, you can return one of these objects, and then if it
+/// has a full type, you can use that, but if not at least you can print the name for informational
+/// purposes.
+///
+
+class TypeAndOrName
+{
+public:
+ TypeAndOrName ();
+ TypeAndOrName (lldb::TypeSP &type_sp);
+ TypeAndOrName (const char *type_str);
+ TypeAndOrName (const TypeAndOrName &rhs);
+ TypeAndOrName (ConstString &type_const_string);
+
+ TypeAndOrName &
+ operator= (const TypeAndOrName &rhs);
+
+ bool
+ operator==(const TypeAndOrName &other) const;
+
+ bool
+ operator!=(const TypeAndOrName &other) const;
+
+ ConstString GetName () const;
+
+ lldb::TypeSP
+ GetTypeSP () const
+ {
+ return m_type_sp;
+ }
+
+ void
+ SetName (const ConstString &type_name);
+
+ void
+ SetName (const char *type_name_cstr);
+
+ void
+ SetTypeSP (lldb::TypeSP type_sp);
+
+ bool
+ IsEmpty ();
+
+ bool
+ HasName ();
+
+ bool
+ HasTypeSP ();
+
+ void
+ Clear ();
+
+ operator
+ bool ()
+ {
+ return !IsEmpty();
+ }
+
+private:
+ lldb::TypeSP m_type_sp;
+ ConstString m_type_name;
+};
+
+// the two classes here are used by the public API as a backend to
+// the SBType and SBTypeList classes
+
+class TypeImpl
+{
+public:
+
+ TypeImpl() :
+ m_clang_ast_type(),
+ m_type_sp()
+ {
+ }
+
+ TypeImpl(const TypeImpl& rhs) :
+ m_clang_ast_type(rhs.m_clang_ast_type),
+ m_type_sp(rhs.m_type_sp)
+ {
+ }
+
+ TypeImpl(const lldb_private::ClangASTType& type);
+
+ TypeImpl(const lldb::TypeSP& type);
+
+ TypeImpl&
+ operator = (const TypeImpl& rhs);
+
+ bool
+ operator == (const TypeImpl& rhs)
+ {
+ return m_clang_ast_type == rhs.m_clang_ast_type && m_type_sp.get() == rhs.m_type_sp.get();
+ }
+
+ bool
+ operator != (const TypeImpl& rhs)
+ {
+ return m_clang_ast_type != rhs.m_clang_ast_type || m_type_sp.get() != rhs.m_type_sp.get();
+ }
+
+ bool
+ IsValid()
+ {
+ return m_type_sp.get() != NULL || m_clang_ast_type.IsValid();
+ }
+
+ const lldb_private::ClangASTType &
+ GetClangASTType() const
+ {
+ return m_clang_ast_type;
+ }
+
+ clang::ASTContext*
+ GetASTContext();
+
+ lldb::clang_type_t
+ GetOpaqueQualType();
+
+ lldb::TypeSP
+ GetTypeSP ()
+ {
+ return m_type_sp;
+ }
+
+ ConstString
+ GetName ();
+
+ bool
+ GetDescription (lldb_private::Stream &strm,
+ lldb::DescriptionLevel description_level);
+
+ void
+ SetType (const lldb::TypeSP &type_sp);
+
+private:
+ ClangASTType m_clang_ast_type;
+ lldb::TypeSP m_type_sp;
+};
+
+class TypeListImpl
+{
+public:
+ TypeListImpl() :
+ m_content()
+ {
+ }
+
+ void
+ Append (const lldb::TypeImplSP& type)
+ {
+ m_content.push_back(type);
+ }
+
+ class AppendVisitor
+ {
+ public:
+ AppendVisitor(TypeListImpl &type_list) :
+ m_type_list(type_list)
+ {
+ }
+
+ void
+ operator() (const lldb::TypeImplSP& type)
+ {
+ m_type_list.Append(type);
+ }
+
+ private:
+ TypeListImpl &m_type_list;
+ };
+
+ void
+ Append (const lldb_private::TypeList &type_list);
+
+ lldb::TypeImplSP
+ GetTypeAtIndex(size_t idx)
+ {
+ lldb::TypeImplSP type_sp;
+ if (idx < GetSize())
+ type_sp = m_content[idx];
+ return type_sp;
+ }
+
+ size_t
+ GetSize()
+ {
+ return m_content.size();
+ }
+
+private:
+ std::vector<lldb::TypeImplSP> m_content;
+};
+
+class TypeMemberImpl
+{
+public:
+ TypeMemberImpl () :
+ m_type_impl_sp (),
+ m_bit_offset (0),
+ m_name (),
+ m_bitfield_bit_size (0),
+ m_is_bitfield (false)
+
+ {
+ }
+
+ TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp,
+ uint64_t bit_offset,
+ const ConstString &name,
+ uint32_t bitfield_bit_size = 0,
+ bool is_bitfield = false) :
+ m_type_impl_sp (type_impl_sp),
+ m_bit_offset (bit_offset),
+ m_name (name),
+ m_bitfield_bit_size (bitfield_bit_size),
+ m_is_bitfield (is_bitfield)
+ {
+ }
+
+ TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp,
+ uint64_t bit_offset):
+ m_type_impl_sp (type_impl_sp),
+ m_bit_offset (bit_offset),
+ m_name (),
+ m_bitfield_bit_size (0),
+ m_is_bitfield (false)
+ {
+ if (m_type_impl_sp)
+ m_name = m_type_impl_sp->GetName();
+ }
+
+ const lldb::TypeImplSP &
+ GetTypeImpl ()
+ {
+ return m_type_impl_sp;
+ }
+
+ const ConstString &
+ GetName () const
+ {
+ return m_name;
+ }
+
+ uint64_t
+ GetBitOffset () const
+ {
+ return m_bit_offset;
+ }
+
+ uint32_t
+ GetBitfieldBitSize () const
+ {
+ return m_bitfield_bit_size;
+ }
+
+ void
+ SetBitfieldBitSize (uint32_t bitfield_bit_size)
+ {
+ m_bitfield_bit_size = bitfield_bit_size;
+ }
+
+ bool
+ GetIsBitfield () const
+ {
+ return m_is_bitfield;
+ }
+
+ void
+ SetIsBitfield (bool is_bitfield)
+ {
+ m_is_bitfield = is_bitfield;
+ }
+
+protected:
+ lldb::TypeImplSP m_type_impl_sp;
+ uint64_t m_bit_offset;
+ ConstString m_name;
+ uint32_t m_bitfield_bit_size; // Bit size for bitfield members only
+ bool m_is_bitfield;
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_Type_h_
+
diff --git a/include/lldb/Symbol/TypeList.h b/include/lldb/Symbol/TypeList.h
new file mode 100644
index 000000000000..9c74db6bf1f4
--- /dev/null
+++ b/include/lldb/Symbol/TypeList.h
@@ -0,0 +1,88 @@
+//===-- TypeList.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TypeList_h_
+#define liblldb_TypeList_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Symbol/Type.h"
+#include <map>
+
+namespace lldb_private {
+
+class TypeList
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ TypeList();
+
+ virtual
+ ~TypeList();
+
+ void
+ Clear();
+
+ void
+ Dump(Stream *s, bool show_context);
+
+// lldb::TypeSP
+// FindType(lldb::user_id_t uid);
+
+ TypeList
+ FindTypes(const ConstString &name);
+
+ void
+ Insert (const lldb::TypeSP& type);
+
+ bool
+ InsertUnique (const lldb::TypeSP& type);
+
+ uint32_t
+ GetSize() const;
+
+ lldb::TypeSP
+ GetTypeAtIndex(uint32_t idx);
+
+ void
+ ForEach (std::function <bool(const lldb::TypeSP &type_sp)> const &callback) const;
+
+ void
+ ForEach (std::function <bool(lldb::TypeSP &type_sp)> const &callback);
+
+ bool
+ RemoveTypeWithUID (lldb::user_id_t uid);
+
+ void
+ RemoveMismatchedTypes (const char *qualified_typename,
+ bool exact_match);
+
+ void
+ RemoveMismatchedTypes (const std::string &type_scope,
+ const std::string &type_basename,
+ lldb::TypeClass type_class,
+ bool exact_match);
+
+ void
+ RemoveMismatchedTypes (lldb::TypeClass type_class);
+
+private:
+ typedef std::multimap<lldb::user_id_t, lldb::TypeSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ collection m_types;
+
+ DISALLOW_COPY_AND_ASSIGN (TypeList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_TypeList_h_
diff --git a/include/lldb/Symbol/TypeVendor.h b/include/lldb/Symbol/TypeVendor.h
new file mode 100644
index 000000000000..559b21eeb95a
--- /dev/null
+++ b/include/lldb/Symbol/TypeVendor.h
@@ -0,0 +1,61 @@
+//===-- TypeVendor.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TypeVendor_h_
+#define liblldb_TypeVendor_h_
+
+#include "lldb/Core/ClangForward.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// The type vendor class is intended as a generic interface to search
+// for Clang types that are not necessarily backed by a specific symbol
+// file.
+//----------------------------------------------------------------------
+class TypeVendor
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ TypeVendor()
+ {
+ }
+
+ virtual
+ ~TypeVendor()
+ {
+ }
+
+ virtual uint32_t
+ FindTypes (const ConstString &name,
+ bool append,
+ uint32_t max_matches,
+ std::vector <ClangASTType> &types) = 0;
+
+ virtual clang::ASTContext *
+ GetClangASTContext () = 0;
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from TypeVendor can see and modify these
+ //------------------------------------------------------------------
+
+private:
+ //------------------------------------------------------------------
+ // For TypeVendor only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (TypeVendor);
+};
+
+
+} // namespace lldb_private
+
+#endif
diff --git a/include/lldb/Symbol/UnwindPlan.h b/include/lldb/Symbol/UnwindPlan.h
new file mode 100644
index 000000000000..6fc5ce042357
--- /dev/null
+++ b/include/lldb/Symbol/UnwindPlan.h
@@ -0,0 +1,499 @@
+#ifndef liblldb_UnwindPlan_h
+#define liblldb_UnwindPlan_h
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ConstString.h"
+
+#include <map>
+#include <vector>
+
+namespace lldb_private {
+
+// The UnwindPlan object specifies how to unwind out of a function - where
+// this function saves the caller's register values before modifying them
+// (for non-volatile aka saved registers) and how to find this frame's
+// Canonical Frame Address (CFA).
+
+// Most commonly, registers are saved on the stack, offset some bytes from
+// the Canonical Frame Address, or CFA, which is the starting address of
+// this function's stack frame (the CFA is same as the eh_frame's CFA,
+// whatever that may be on a given architecture).
+// The CFA address for the stack frame does not change during
+// the lifetime of the function.
+
+// Internally, the UnwindPlan is structured as a vector of register locations
+// organized by code address in the function, showing which registers have been
+// saved at that point and where they are saved.
+// It can be thought of as the expanded table form of the DWARF CFI
+// encoded information.
+
+// Other unwind information sources will be converted into UnwindPlans before
+// being added to a FuncUnwinders object. The unwind source may be
+// an eh_frame FDE, a DWARF debug_frame FDE, or assembly language based
+// prologue analysis.
+// The UnwindPlan is the canonical form of this information that the unwinder
+// code will use when walking the stack.
+
+class UnwindPlan {
+public:
+
+ class Row {
+ public:
+ class RegisterLocation
+ {
+ public:
+
+ enum RestoreType
+ {
+ unspecified, // not specified, we may be able to assume this
+ // is the same register. gcc doesn't specify all
+ // initial values so we really don't know...
+ undefined, // reg is not available, e.g. volatile reg
+ same, // reg is unchanged
+ atCFAPlusOffset, // reg = deref(CFA + offset)
+ isCFAPlusOffset, // reg = CFA + offset
+ inOtherRegister, // reg = other reg
+ atDWARFExpression, // reg = deref(eval(dwarf_expr))
+ isDWARFExpression // reg = eval(dwarf_expr)
+ };
+
+ RegisterLocation() :
+ m_type(unspecified),
+ m_location()
+ {
+ }
+
+ bool
+ operator == (const RegisterLocation& rhs) const;
+
+ bool
+ operator != (const RegisterLocation &rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ void
+ SetUnspecified()
+ {
+ m_type = unspecified;
+ }
+
+ void
+ SetUndefined()
+ {
+ m_type = undefined;
+ }
+
+ void
+ SetSame()
+ {
+ m_type = same;
+ }
+
+ bool
+ IsSame () const
+ {
+ return m_type == same;
+ }
+
+ bool
+ IsUnspecified () const
+ {
+ return m_type == unspecified;
+ }
+
+ bool
+ IsCFAPlusOffset () const
+ {
+ return m_type == isCFAPlusOffset;
+ }
+
+ bool
+ IsAtCFAPlusOffset () const
+ {
+ return m_type == atCFAPlusOffset;
+ }
+
+ bool
+ IsInOtherRegister () const
+ {
+ return m_type == inOtherRegister;
+ }
+
+ bool
+ IsAtDWARFExpression () const
+ {
+ return m_type == atDWARFExpression;
+ }
+
+ bool
+ IsDWARFExpression () const
+ {
+ return m_type == isDWARFExpression;
+ }
+
+ void
+ SetAtCFAPlusOffset (int32_t offset)
+ {
+ m_type = atCFAPlusOffset;
+ m_location.offset = offset;
+ }
+
+ void
+ SetIsCFAPlusOffset (int32_t offset)
+ {
+ m_type = isCFAPlusOffset;
+ m_location.offset = offset;
+ }
+
+ void
+ SetInRegister (uint32_t reg_num)
+ {
+ m_type = inOtherRegister;
+ m_location.reg_num = reg_num;
+ }
+
+ uint32_t
+ GetRegisterNumber () const
+ {
+ if (m_type == inOtherRegister)
+ return m_location.reg_num;
+ return LLDB_INVALID_REGNUM;
+ }
+
+ RestoreType
+ GetLocationType () const
+ {
+ return m_type;
+ }
+
+ int32_t
+ GetOffset () const
+ {
+ if (m_type == atCFAPlusOffset || m_type == isCFAPlusOffset)
+ return m_location.offset;
+ return 0;
+ }
+
+ void
+ GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const
+ {
+ if (m_type == atDWARFExpression || m_type == isDWARFExpression)
+ {
+ *opcodes = m_location.expr.opcodes;
+ len = m_location.expr.length;
+ }
+ else
+ {
+ *opcodes = NULL;
+ len = 0;
+ }
+ }
+
+ void
+ SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len);
+
+ void
+ SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len);
+
+ const uint8_t *
+ GetDWARFExpressionBytes ()
+ {
+ if (m_type == atDWARFExpression || m_type == isDWARFExpression)
+ return m_location.expr.opcodes;
+ return NULL;
+ }
+
+ int
+ GetDWARFExpressionLength ()
+ {
+ if (m_type == atDWARFExpression || m_type == isDWARFExpression)
+ return m_location.expr.length;
+ return 0;
+ }
+
+ void
+ Dump (Stream &s,
+ const UnwindPlan* unwind_plan,
+ const UnwindPlan::Row* row,
+ Thread* thread,
+ bool verbose) const;
+
+ private:
+ RestoreType m_type; // How do we locate this register?
+ union
+ {
+ // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset
+ int32_t offset;
+ // For m_type == inOtherRegister
+ uint32_t reg_num; // The register number
+ // For m_type == atDWARFExpression or m_type == isDWARFExpression
+ struct {
+ const uint8_t *opcodes;
+ uint16_t length;
+ } expr;
+ } m_location;
+ };
+
+ public:
+ Row ();
+
+ Row (const UnwindPlan::Row& rhs) :
+ m_offset (rhs.m_offset),
+ m_cfa_reg_num (rhs.m_cfa_reg_num),
+ m_cfa_offset (rhs.m_cfa_offset),
+ m_register_locations (rhs.m_register_locations)
+ {
+ }
+
+ bool
+ operator == (const Row &rhs) const;
+
+ bool
+ GetRegisterInfo (uint32_t reg_num, RegisterLocation& register_location) const;
+
+ void
+ SetRegisterInfo (uint32_t reg_num, const RegisterLocation register_location);
+
+ lldb::addr_t
+ GetOffset() const
+ {
+ return m_offset;
+ }
+
+ void
+ SetOffset(lldb::addr_t offset)
+ {
+ m_offset = offset;
+ }
+
+ void
+ SlideOffset(lldb::addr_t offset)
+ {
+ m_offset += offset;
+ }
+
+ uint32_t
+ GetCFARegister () const
+ {
+ return m_cfa_reg_num;
+ }
+
+ bool
+ SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num,
+ int32_t offset,
+ bool can_replace);
+
+ bool
+ SetRegisterLocationToIsCFAPlusOffset (uint32_t reg_num,
+ int32_t offset,
+ bool can_replace);
+
+ bool
+ SetRegisterLocationToUndefined (uint32_t reg_num,
+ bool can_replace,
+ bool can_replace_only_if_unspecified);
+
+ bool
+ SetRegisterLocationToUnspecified (uint32_t reg_num,
+ bool can_replace);
+
+ bool
+ SetRegisterLocationToRegister (uint32_t reg_num,
+ uint32_t other_reg_num,
+ bool can_replace);
+
+ bool
+ SetRegisterLocationToSame (uint32_t reg_num,
+ bool must_replace);
+
+
+
+ void
+ SetCFARegister (uint32_t reg_num);
+
+ int32_t
+ GetCFAOffset () const
+ {
+ return m_cfa_offset;
+ }
+
+ void
+ SetCFAOffset (int32_t offset)
+ {
+ m_cfa_offset = offset;
+ }
+
+ void
+ Clear ();
+
+ void
+ Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, lldb::addr_t base_addr) const;
+
+ protected:
+ typedef std::map<uint32_t, RegisterLocation> collection;
+ lldb::addr_t m_offset; // Offset into the function for this row
+ uint32_t m_cfa_reg_num; // The Call Frame Address register number
+ int32_t m_cfa_offset; // The offset from the CFA for this row
+ collection m_register_locations;
+ }; // class Row
+
+public:
+
+ typedef std::shared_ptr<Row> RowSP;
+
+ UnwindPlan (lldb::RegisterKind reg_kind) :
+ m_row_list (),
+ m_plan_valid_address_range (),
+ m_register_kind (reg_kind),
+ m_return_addr_register (LLDB_INVALID_REGNUM),
+ m_source_name (),
+ m_plan_is_sourced_from_compiler (eLazyBoolCalculate),
+ m_plan_is_valid_at_all_instruction_locations (eLazyBoolCalculate)
+ {
+ }
+
+ ~UnwindPlan ()
+ {
+ }
+
+ void
+ Dump (Stream& s, Thread* thread, lldb::addr_t base_addr) const;
+
+ void
+ AppendRow (const RowSP& row_sp);
+
+ // Returns a pointer to the best row for the given offset into the function's instructions.
+ // If offset is -1 it indicates that the function start is unknown - the final row in the UnwindPlan is returned.
+ // In practice, the UnwindPlan for a function with no known start address will be the architectural default
+ // UnwindPlan which will only have one row.
+ UnwindPlan::RowSP
+ GetRowForFunctionOffset (int offset) const;
+
+ lldb::RegisterKind
+ GetRegisterKind () const
+ {
+ return m_register_kind;
+ }
+
+ void
+ SetRegisterKind (lldb::RegisterKind kind)
+ {
+ m_register_kind = kind;
+ }
+
+ void
+ SetReturnAddressRegister (uint32_t regnum)
+ {
+ m_return_addr_register = regnum;
+ }
+
+ uint32_t
+ GetReturnAddressRegister (void)
+ {
+ return m_return_addr_register;
+ }
+
+ uint32_t
+ GetInitialCFARegister () const
+ {
+ if (m_row_list.empty())
+ return LLDB_INVALID_REGNUM;
+ return m_row_list.front()->GetCFARegister();
+ }
+
+ // This UnwindPlan may not be valid at every address of the function span.
+ // For instance, a FastUnwindPlan will not be valid at the prologue setup
+ // instructions - only in the body of the function.
+ void
+ SetPlanValidAddressRange (const AddressRange& range);
+
+ const AddressRange &
+ GetAddressRange () const
+ {
+ return m_plan_valid_address_range;
+ }
+
+ bool
+ PlanValidAtAddress (Address addr);
+
+ bool
+ IsValidRowIndex (uint32_t idx) const;
+
+ const UnwindPlan::RowSP
+ GetRowAtIndex (uint32_t idx) const;
+
+ const UnwindPlan::RowSP
+ GetLastRow () const;
+
+ lldb_private::ConstString
+ GetSourceName () const;
+
+ void
+ SetSourceName (const char *);
+
+ // Was this UnwindPlan emitted by a compiler?
+ lldb_private::LazyBool
+ GetSourcedFromCompiler () const
+ {
+ return m_plan_is_sourced_from_compiler;
+ }
+
+ // Was this UnwindPlan emitted by a compiler?
+ void
+ SetSourcedFromCompiler (lldb_private::LazyBool from_compiler)
+ {
+ m_plan_is_sourced_from_compiler = from_compiler;
+ }
+
+ // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites,
+ // e.g. for exception handling.
+ lldb_private::LazyBool
+ GetUnwindPlanValidAtAllInstructions () const
+ {
+ return m_plan_is_valid_at_all_instruction_locations;
+ }
+
+ // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites,
+ // e.g. for exception handling.
+ void
+ SetUnwindPlanValidAtAllInstructions (lldb_private::LazyBool valid_at_all_insn)
+ {
+ m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn;
+ }
+
+ int
+ GetRowCount () const;
+
+ void
+ Clear()
+ {
+ m_row_list.clear();
+ m_plan_valid_address_range.Clear();
+ m_register_kind = lldb::eRegisterKindDWARF;
+ m_source_name.Clear();
+ }
+
+ const RegisterInfo *
+ GetRegisterInfo (Thread* thread, uint32_t reg_num) const;
+
+private:
+
+
+ typedef std::vector<RowSP> collection;
+ collection m_row_list;
+ AddressRange m_plan_valid_address_range;
+ lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers are in terms of - will need to be
+ // translated to lldb native reg nums at unwind time
+ uint32_t m_return_addr_register; // The register that has the return address for the caller frame
+ // e.g. the lr on arm
+ lldb_private::ConstString m_source_name; // for logging, where this UnwindPlan originated from
+ lldb_private::LazyBool m_plan_is_sourced_from_compiler;
+ lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations;
+}; // class UnwindPlan
+
+} // namespace lldb_private
+
+#endif //liblldb_UnwindPlan_h
diff --git a/include/lldb/Symbol/UnwindTable.h b/include/lldb/Symbol/UnwindTable.h
new file mode 100644
index 000000000000..cefb91eb371a
--- /dev/null
+++ b/include/lldb/Symbol/UnwindTable.h
@@ -0,0 +1,69 @@
+//===-- Symtab.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef liblldb_UnwindTable_h
+#define liblldb_UnwindTable_h
+
+#include <map>
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// A class which holds all the FuncUnwinders objects for a given ObjectFile.
+// The UnwindTable is populated with FuncUnwinders objects lazily during
+// the debug session.
+
+class UnwindTable
+{
+public:
+ UnwindTable(ObjectFile& objfile);
+ ~UnwindTable();
+
+ lldb_private::DWARFCallFrameInfo *
+ GetEHFrameInfo ();
+
+ lldb::FuncUnwindersSP
+ GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc);
+
+// Normally when we create a new FuncUnwinders object we track it in this UnwindTable so it can
+// be reused later. But for the target modules show-unwind we want to create brand new
+// UnwindPlans for the function of interest - so ignore any existing FuncUnwinders for that
+// function and don't add this new one to our UnwindTable.
+// This FuncUnwinders object does have a reference to the UnwindTable but the lifetime of this
+// uncached FuncUnwinders is expected to be short so in practice this will not be a problem.
+ lldb::FuncUnwindersSP
+ GetUncachedFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc);
+
+private:
+ void
+ Dump (Stream &s);
+
+ void Initialize ();
+
+ typedef std::map<lldb::addr_t, lldb::FuncUnwindersSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ ObjectFile& m_object_file;
+ collection m_unwinds;
+
+ bool m_initialized; // delay some initialization until ObjectFile is set up
+
+ UnwindAssembly* m_assembly_profiler;
+
+ DWARFCallFrameInfo* m_eh_frame;
+
+ DISALLOW_COPY_AND_ASSIGN (UnwindTable);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_UnwindTable_h
diff --git a/include/lldb/Symbol/Variable.h b/include/lldb/Symbol/Variable.h
new file mode 100644
index 000000000000..07295d090ee6
--- /dev/null
+++ b/include/lldb/Symbol/Variable.h
@@ -0,0 +1,184 @@
+//===-- Variable.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Variable_h_
+#define liblldb_Variable_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/Mangled.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Symbol/Declaration.h"
+
+namespace lldb_private {
+
+class Variable : public UserID
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ Variable (lldb::user_id_t uid,
+ const char *name,
+ const char *mangled, // The mangled variable name for variables in namespaces
+ const lldb::SymbolFileTypeSP &symfile_type_sp,
+ lldb::ValueType scope,
+ SymbolContextScope *owner_scope,
+ Declaration* decl,
+ const DWARFExpression& location,
+ bool external,
+ bool artificial);
+
+ virtual
+ ~Variable();
+
+ void
+ Dump(Stream *s, bool show_context) const;
+
+ bool
+ DumpDeclaration (Stream *s,
+ bool show_fullpaths,
+ bool show_module);
+
+ const Declaration&
+ GetDeclaration() const
+ {
+ return m_declaration;
+ }
+
+ const ConstString&
+ GetName() const;
+
+ SymbolContextScope *
+ GetSymbolContextScope() const
+ {
+ return m_owner_scope;
+ }
+
+ // Since a variable can have a basename "i" and also a mangled
+ // named "_ZN12_GLOBAL__N_11iE" and a demangled mangled name
+ // "(anonymous namespace)::i", this function will allow a generic match
+ // function that can be called by commands and expression parsers to make
+ // sure we match anything we come across.
+ bool
+ NameMatches (const ConstString &name) const
+ {
+ if (m_name == name)
+ return true;
+ return m_mangled.NameMatches (name);
+ }
+
+ bool
+ NameMatches (const RegularExpression& regex) const;
+
+ Type *
+ GetType();
+
+ lldb::ValueType
+ GetScope() const
+ {
+ return m_scope;
+ }
+
+ bool
+ IsExternal() const
+ {
+ return m_external;
+ }
+
+ bool
+ IsArtificial() const
+ {
+ return m_artificial;
+ }
+
+ DWARFExpression &
+ LocationExpression()
+ {
+ return m_location;
+ }
+
+ const DWARFExpression &
+ LocationExpression() const
+ {
+ return m_location;
+ }
+
+ bool
+ DumpLocationForAddress (Stream *s,
+ const Address &address);
+
+ size_t
+ MemorySize() const;
+
+ void
+ CalculateSymbolContext (SymbolContext *sc);
+
+ bool
+ IsInScope (StackFrame *frame);
+
+ bool
+ LocationIsValidForFrame (StackFrame *frame);
+
+ bool
+ LocationIsValidForAddress (const Address &address);
+
+ bool
+ GetLocationIsConstantValueData () const
+ {
+ return m_loc_is_const_data;
+ }
+
+ void
+ SetLocationIsConstantValueData (bool b)
+ {
+ m_loc_is_const_data = b;
+ }
+
+ typedef size_t (*GetVariableCallback) (void *baton,
+ const char *name,
+ VariableList &var_list);
+
+
+ static Error
+ GetValuesForVariableExpressionPath (const char *variable_expr_path,
+ ExecutionContextScope *scope,
+ GetVariableCallback callback,
+ void *baton,
+ VariableList &variable_list,
+ ValueObjectList &valobj_list);
+
+ static size_t
+ AutoComplete (const ExecutionContext &exe_ctx,
+ const char *name,
+ StringList &matches,
+ bool &word_complete);
+
+protected:
+ ConstString m_name; // The basename of the variable (no namespaces)
+ Mangled m_mangled; // The mangled name of the variable
+ lldb::SymbolFileTypeSP m_symfile_type_sp; // The type pointer of the variable (int, struct, class, etc)
+ lldb::ValueType m_scope; // global, parameter, local
+ SymbolContextScope *m_owner_scope; // The symbol file scope that this variable was defined in
+ Declaration m_declaration; // Declaration location for this item.
+ DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate()
+ uint8_t m_external:1, // Visible outside the containing compile unit?
+ m_artificial:1, // Non-zero if the variable is not explicitly declared in source
+ m_loc_is_const_data:1; // The m_location expression contains the constant variable value data, not a DWARF location
+private:
+ Variable(const Variable& rhs);
+ Variable& operator=(const Variable& rhs);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Variable_h_
diff --git a/include/lldb/Symbol/VariableList.h b/include/lldb/Symbol/VariableList.h
new file mode 100644
index 000000000000..2ce6146f4627
--- /dev/null
+++ b/include/lldb/Symbol/VariableList.h
@@ -0,0 +1,95 @@
+//===-- VariableList.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_VariableList_h_
+#define liblldb_VariableList_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/Variable.h"
+
+namespace lldb_private {
+
+class VariableList
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+// VariableList(const SymbolContext &symbol_context);
+ VariableList();
+ virtual ~VariableList();
+
+ void
+ AddVariable (const lldb::VariableSP &var_sp);
+
+ bool
+ AddVariableIfUnique (const lldb::VariableSP &var_sp);
+
+ void
+ AddVariables (VariableList *variable_list);
+
+ void
+ Clear();
+
+ void
+ Dump(Stream *s, bool show_context) const;
+
+ lldb::VariableSP
+ GetVariableAtIndex(size_t idx) const;
+
+ lldb::VariableSP
+ RemoveVariableAtIndex (size_t idx);
+
+ lldb::VariableSP
+ FindVariable (const ConstString& name);
+
+ uint32_t
+ FindVariableIndex (const lldb::VariableSP &var_sp);
+
+ // Returns the actual number of unique variables that were added to the
+ // list. "total_matches" will get updated with the actualy number of
+ // matches that were found regardless of whether they were unique or not
+ // to allow for error conditions when nothing is found, versus conditions
+ // where any varaibles that match "regex" were already in "var_list".
+ size_t
+ AppendVariablesIfUnique (const RegularExpression& regex,
+ VariableList &var_list,
+ size_t& total_matches);
+
+ size_t
+ AppendVariablesWithScope (lldb::ValueType type,
+ VariableList &var_list,
+ bool if_unique = true);
+
+ uint32_t
+ FindIndexForVariable (Variable* variable);
+
+ size_t
+ MemorySize() const;
+
+ size_t
+ GetSize() const;
+
+protected:
+ typedef std::vector<lldb::VariableSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ collection m_variables;
+private:
+ //------------------------------------------------------------------
+ // For VariableList only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (VariableList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_VariableList_h_
diff --git a/include/lldb/Symbol/VerifyDecl.h b/include/lldb/Symbol/VerifyDecl.h
new file mode 100644
index 000000000000..228e635652e6
--- /dev/null
+++ b/include/lldb/Symbol/VerifyDecl.h
@@ -0,0 +1,20 @@
+//===-- VerifyDecl.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_VariableList_h_
+#define lldb_VariableList_h_
+
+#include "lldb/Core/ClangForward.h"
+
+namespace lldb_private
+{
+ void VerifyDecl (clang::Decl *decl);
+}
+
+#endif
diff --git a/include/lldb/Target/ABI.h b/include/lldb/Target/ABI.h
new file mode 100644
index 000000000000..16f8ee7fc7d7
--- /dev/null
+++ b/include/lldb/Target/ABI.h
@@ -0,0 +1,137 @@
+//===-- ABI.h ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ABI_h_
+#define liblldb_ABI_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Error.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class ABI :
+ public PluginInterface
+{
+public:
+ virtual
+ ~ABI();
+
+ virtual size_t
+ GetRedZoneSize () const = 0;
+
+ virtual bool
+ PrepareTrivialCall (Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ lldb::addr_t *arg1_ptr = NULL,
+ lldb::addr_t *arg2_ptr = NULL,
+ lldb::addr_t *arg3_ptr = NULL,
+ lldb::addr_t *arg4_ptr = NULL,
+ lldb::addr_t *arg5_ptr = NULL,
+ lldb::addr_t *arg6_ptr = NULL) const = 0;
+
+ virtual bool
+ GetArgumentValues (Thread &thread,
+ ValueList &values) const = 0;
+
+ lldb::ValueObjectSP
+ GetReturnValueObject (Thread &thread,
+ ClangASTType &type,
+ bool persistent = true) const;
+
+ // Set the Return value object in the current frame as though a function with
+ virtual Error
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) = 0;
+
+protected:
+ // This is the method the ABI will call to actually calculate the return value.
+ // Don't put it in a persistant value object, that will be done by the ABI::GetReturnValueObject.
+ virtual lldb::ValueObjectSP
+ GetReturnValueObjectImpl (Thread &thread,
+ ClangASTType &type) const = 0;
+public:
+ virtual bool
+ CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan) = 0;
+
+ virtual bool
+ CreateDefaultUnwindPlan (UnwindPlan &unwind_plan) = 0;
+
+ virtual bool
+ RegisterIsVolatile (const RegisterInfo *reg_info) = 0;
+
+ // Should return true if your ABI uses frames when doing stack backtraces. This
+ // means a frame pointer is used that points to the previous stack frame in some
+ // way or another.
+ virtual bool
+ StackUsesFrames () = 0;
+
+ // Should take a look at a call frame address (CFA) which is just the stack
+ // pointer value upon entry to a function. ABIs usually impose alignment
+ // restrictions (4, 8 or 16 byte aligned), and zero is usually not allowed.
+ // This function should return true if "cfa" is valid call frame address for
+ // the ABI, and false otherwise. This is used by the generic stack frame unwinding
+ // code to help determine when a stack ends.
+ virtual bool
+ CallFrameAddressIsValid (lldb::addr_t cfa) = 0;
+
+ // Validates a possible PC value and returns true if an opcode can be at "pc".
+ virtual bool
+ CodeAddressIsValid (lldb::addr_t pc) = 0;
+
+ virtual lldb::addr_t
+ FixCodeAddress (lldb::addr_t pc)
+ {
+ // Some targets might use bits in a code address to indicate
+ // a mode switch. ARM uses bit zero to signify a code address is
+ // thumb, so any ARM ABI plug-ins would strip those bits.
+ return pc;
+ }
+
+ virtual const RegisterInfo *
+ GetRegisterInfoArray (uint32_t &count) = 0;
+
+ // Some architectures (e.g. x86) will push the return address on the stack and decrement
+ // the stack pointer when making a function call. This means that every stack frame will
+ // have a unique CFA.
+ // Other architectures (e.g. arm) pass the return address in a register so it is possible
+ // to have a frame on a backtrace that does not push anything on the stack or change the
+ // CFA.
+ virtual bool
+ FunctionCallsChangeCFA () = 0;
+
+
+ bool
+ GetRegisterInfoByName (const ConstString &name, RegisterInfo &info);
+
+ bool
+ GetRegisterInfoByKind (lldb::RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterInfo &info);
+
+ static lldb::ABISP
+ FindPlugin (const ArchSpec &arch);
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from ABI can see and modify these
+ //------------------------------------------------------------------
+ ABI();
+private:
+ DISALLOW_COPY_AND_ASSIGN (ABI);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ABI_h_
diff --git a/include/lldb/Target/CPPLanguageRuntime.h b/include/lldb/Target/CPPLanguageRuntime.h
new file mode 100644
index 000000000000..98a4ab88cb25
--- /dev/null
+++ b/include/lldb/Target/CPPLanguageRuntime.h
@@ -0,0 +1,158 @@
+//===-- CPPLanguageRuntime.h ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CPPLanguageRuntime_h_
+#define liblldb_CPPLanguageRuntime_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Target/LanguageRuntime.h"
+
+namespace lldb_private {
+
+class CPPLanguageRuntime :
+ public LanguageRuntime
+{
+public:
+
+ class MethodName
+ {
+ public:
+ enum Type
+ {
+ eTypeInvalid,
+ eTypeUnknownMethod,
+ eTypeClassMethod,
+ eTypeInstanceMethod
+ };
+
+ MethodName () :
+ m_full(),
+ m_basename(),
+ m_context(),
+ m_arguments(),
+ m_qualifiers(),
+ m_type (eTypeInvalid),
+ m_parsed (false),
+ m_parse_error (false)
+ {
+ }
+
+ MethodName (const ConstString &s) :
+ m_full(s),
+ m_basename(),
+ m_context(),
+ m_arguments(),
+ m_qualifiers(),
+ m_type (eTypeInvalid),
+ m_parsed (false),
+ m_parse_error (false)
+ {
+ }
+
+ void
+ Clear();
+
+ bool
+ IsValid () const
+ {
+ if (m_parse_error)
+ return false;
+ if (m_type == eTypeInvalid)
+ return false;
+ return (bool)m_full;
+ }
+
+ Type
+ GetType () const
+ {
+ return m_type;
+ }
+
+ const ConstString &
+ GetFullName () const
+ {
+ return m_full;
+ }
+
+ llvm::StringRef
+ GetBasename ();
+
+ llvm::StringRef
+ GetContext ();
+
+ llvm::StringRef
+ GetArguments ();
+
+ llvm::StringRef
+ GetQualifiers ();
+
+ protected:
+ void
+ Parse();
+
+ ConstString m_full; // Full name: "lldb::SBTarget::GetBreakpointAtIndex(unsigned int) const"
+ llvm::StringRef m_basename; // Basename: "GetBreakpointAtIndex"
+ llvm::StringRef m_context; // Decl context: "lldb::SBTarget"
+ llvm::StringRef m_arguments; // Arguments: "(unsigned int)"
+ llvm::StringRef m_qualifiers; // Qualifiers: "const"
+ Type m_type;
+ bool m_parsed;
+ bool m_parse_error;
+ };
+
+ virtual
+ ~CPPLanguageRuntime();
+
+ virtual lldb::LanguageType
+ GetLanguageType () const
+ {
+ return lldb::eLanguageTypeC_plus_plus;
+ }
+
+ virtual bool
+ IsVTableName (const char *name) = 0;
+
+ virtual bool
+ GetObjectDescription (Stream &str, ValueObject &object);
+
+ virtual bool
+ GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope);
+
+ static bool
+ IsCPPMangledName(const char *name);
+
+ static bool
+ StripNamespacesFromVariableName (const char *name, const char *&base_name_start, const char *&base_name_end);
+
+ // in some cases, compilers will output different names for one same type. when tht happens, it might be impossible
+ // to construct SBType objects for a valid type, because the name that is available is not the same as the name that
+ // can be used as a search key in FindTypes(). the equivalents map here is meant to return possible alternative names
+ // for a type through which a search can be conducted. Currently, this is only enabled for C++ but can be extended
+ // to ObjC or other languages if necessary
+ static uint32_t
+ FindEquivalentNames(ConstString type_name, std::vector<ConstString>& equivalents);
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from CPPLanguageRuntime can see and modify these
+ //------------------------------------------------------------------
+ CPPLanguageRuntime(Process *process);
+private:
+ DISALLOW_COPY_AND_ASSIGN (CPPLanguageRuntime);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CPPLanguageRuntime_h_
diff --git a/include/lldb/Target/DynamicLoader.h b/include/lldb/Target/DynamicLoader.h
new file mode 100644
index 000000000000..6b76e5891ae8
--- /dev/null
+++ b/include/lldb/Target/DynamicLoader.h
@@ -0,0 +1,239 @@
+//===-- DynamicLoader.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DynamicLoader_h_
+#define liblldb_DynamicLoader_h_
+
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/PluginInterface.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class DynamicLoader DynamicLoader.h "lldb/Target/DynamicLoader.h"
+/// @brief A plug-in interface definition class for dynamic loaders.
+///
+/// Dynamic loader plug-ins track image (shared library) loading and
+/// unloading. The class is initialized given a live process that is
+/// halted at its entry point or just after attaching.
+///
+/// Dynamic loader plug-ins can track the process by registering
+/// callbacks using the:
+/// Process::RegisterNotificationCallbacks (const Notifications&)
+/// function.
+///
+/// Breakpoints can also be set in the process which can register
+/// functions that get called using:
+/// Process::BreakpointSetCallback (lldb::user_id_t, BreakpointHitCallback, void *).
+/// These breakpoint callbacks return a boolean value that indicates if
+/// the process should continue or halt and should return the global
+/// setting for this using:
+/// DynamicLoader::StopWhenImagesChange() const.
+//----------------------------------------------------------------------
+class DynamicLoader :
+ public PluginInterface
+{
+public:
+ //------------------------------------------------------------------
+ /// Find a dynamic loader plugin for a given process.
+ ///
+ /// Scans the installed DynamicLoader plug-ins and tries to find
+ /// an instance that can be used to track image changes in \a
+ /// process.
+ ///
+ /// @param[in] process
+ /// The process for which to try and locate a dynamic loader
+ /// plug-in instance.
+ ///
+ /// @param[in] plugin_name
+ /// An optional name of a specific dynamic loader plug-in that
+ /// should be used. If NULL, pick the best plug-in.
+ //------------------------------------------------------------------
+ static DynamicLoader*
+ FindPlugin (Process *process, const char *plugin_name);
+
+ //------------------------------------------------------------------
+ /// Construct with a process.
+ //------------------------------------------------------------------
+ DynamicLoader (Process *process);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be
+ /// inherited from by the plug-in instance.
+ //------------------------------------------------------------------
+ virtual
+ ~DynamicLoader ();
+
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ virtual void
+ DidAttach () = 0;
+
+ //------------------------------------------------------------------
+ /// Called after launching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// the process has stopped for the first time on launch.
+ //------------------------------------------------------------------
+ virtual void
+ DidLaunch () = 0;
+
+
+ //------------------------------------------------------------------
+ /// Helper function that can be used to detect when a process has
+ /// called exec and is now a new and different process. This can
+ /// be called when necessary to try and detect the exec. The process
+ /// might be able to answer this question, but sometimes it might
+ /// not be able and the dynamic loader often knows what the program
+ /// entry point is. So the process and the dynamic loader can work
+ /// together to detect this.
+ //------------------------------------------------------------------
+ virtual bool
+ ProcessDidExec ()
+ {
+ return false;
+ }
+ //------------------------------------------------------------------
+ /// Get whether the process should stop when images change.
+ ///
+ /// When images (executables and shared libraries) get loaded or
+ /// unloaded, often debug sessions will want to try and resolve or
+ /// unresolve breakpoints that are set in these images. Any
+ /// breakpoints set by DynamicLoader plug-in instances should
+ /// return this value to ensure consistent debug session behaviour.
+ ///
+ /// @return
+ /// Returns \b true if the process should stop when images
+ /// change, \b false if the process should resume.
+ //------------------------------------------------------------------
+ bool
+ GetStopWhenImagesChange () const;
+
+ //------------------------------------------------------------------
+ /// Set whether the process should stop when images change.
+ ///
+ /// When images (executables and shared libraries) get loaded or
+ /// unloaded, often debug sessions will want to try and resolve or
+ /// unresolve breakpoints that are set in these images. The default
+ /// is set so that the process stops when images change, but this
+ /// can be overridden using this function callback.
+ ///
+ /// @param[in] stop
+ /// Boolean value that indicates whether the process should stop
+ /// when images change.
+ //------------------------------------------------------------------
+ void
+ SetStopWhenImagesChange (bool stop);
+
+ //------------------------------------------------------------------
+ /// Provides a plan to step through the dynamic loader trampoline
+ /// for the current state of \a thread.
+ ///
+ ///
+ /// @param[in] stop_others
+ /// Whether the plan should be set to stop other threads.
+ ///
+ /// @return
+ /// A pointer to the plan (caller owned) or NULL if we are not at such
+ /// a trampoline.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP
+ GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0;
+
+
+ //------------------------------------------------------------------
+ /// Some dynamic loaders provide features where there are a group of symbols "equivalent to"
+ /// a given symbol one of which will be chosen when the symbol is bound. If you want to
+ /// set a breakpoint on one of these symbols, you really need to set it on all the
+ /// equivalent symbols.
+ ///
+ ///
+ /// @param[in] original_symbol
+ /// The symbol for which we are finding equivalences.
+ ///
+ /// @param[in] module_list
+ /// The set of modules in which to search.
+ ///
+ /// @param[out] equivalent_symbols
+ /// The equivalent symbol list - any equivalent symbols found are appended to this list.
+ ///
+ /// @return
+ /// Number of equivalent symbols found.
+ //------------------------------------------------------------------
+ virtual size_t
+ FindEquivalentSymbols (Symbol *original_symbol, ModuleList &module_list, SymbolContextList &equivalent_symbols)
+ {
+ return 0;
+ }
+
+ //------------------------------------------------------------------
+ /// Ask if it is ok to try and load or unload an shared library
+ /// (image).
+ ///
+ /// The dynamic loader often knows when it would be ok to try and
+ /// load or unload a shared library. This function call allows the
+ /// dynamic loader plug-ins to check any current dyld state to make
+ /// sure it is an ok time to load a shared library.
+ ///
+ /// @return
+ /// \b true if it is currently ok to try and load a shared
+ /// library into the process, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual Error
+ CanLoadImage () = 0;
+
+ //------------------------------------------------------------------
+ /// Ask if the eh_frame information for the given SymbolContext should
+ /// be relied on even when it's the first frame in a stack unwind.
+ ///
+ /// The CFI instructions from the eh_frame section are normally only
+ /// valid at call sites -- places where a program could throw an
+ /// exception and need to unwind out. But some Modules may be known
+ /// to the system as having reliable eh_frame information at all call
+ /// sites. This would be the case if the Module's contents are largely
+ /// hand-written assembly with hand-written eh_frame information.
+ /// Normally when unwinding from a function at the beginning of a stack
+ /// unwind lldb will examine the assembly instructions to understand
+ /// how the stack frame is set up and where saved registers are stored.
+ /// But with hand-written assembly this is not reliable enough -- we need
+ /// to consult those function's hand-written eh_frame information.
+ ///
+ /// @return
+ /// \b True if the symbol context should use eh_frame instructions
+ /// unconditionally when unwinding from this frame. Else \b false,
+ /// the normal lldb unwind behavior of only using eh_frame when the
+ /// function appears in the middle of the stack.
+ //------------------------------------------------------------------
+ virtual bool
+ AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
+ {
+ return false;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ Process* m_process; ///< The process that this dynamic loader plug-in is tracking.
+private:
+ DISALLOW_COPY_AND_ASSIGN (DynamicLoader);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_DynamicLoader_h_
diff --git a/include/lldb/Target/ExecutionContext.h b/include/lldb/Target/ExecutionContext.h
new file mode 100644
index 000000000000..de5fe14934a7
--- /dev/null
+++ b/include/lldb/Target/ExecutionContext.h
@@ -0,0 +1,778 @@
+//===-- ExecutionContext.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// Execution context objects refer to objects in the execution of the
+/// program that is being debugged. The consist of one or more of the
+/// following objects: target, process, thread, and frame. Many objects
+/// in the debugger need to track different executions contexts. For
+/// example, a local function variable might have an execution context
+/// that refers to a stack frame. A global or static variable might
+/// refer to a target since a stack frame isn't required in order to
+/// evaluate a global or static variable (a process isn't necessarily
+/// needed for a global variable since we might be able to read the
+/// variable value from a data section in one of the object files in
+/// a target). There are two types of objects that hold onto execution
+/// contexts: ExecutionContextRef and ExecutionContext. Both of these
+/// objects are deascribed below.
+///
+/// Not all objects in an ExectionContext objects will be valid. If you want
+/// to refer stronly (ExectionContext) or weakly (ExectionContextRef) to
+/// a process, then only the process and target references will be valid.
+/// For threads, only the thread, process and target references will be
+/// filled in. For frames, all of the objects will be filled in.
+///
+/// These classes are designed to be used as baton objects that get passed
+/// to a wide variety of functions that require execution contexts.
+//===----------------------------------------------------------------------===//
+
+
+
+#ifndef liblldb_ExecutionContext_h_
+#define liblldb_ExecutionContext_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Target/StackID.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ExecutionContextRef ExecutionContext.h "lldb/Target/ExecutionContext.h"
+/// @brief A class that holds a weak reference to an execution context.
+///
+/// ExecutionContextRef objects are designed to hold onto an execution
+/// context that might change over time. For example, if an object wants
+/// to refer to a stack frame, it should hold onto an ExecutionContextRef
+/// to a frame object. The backing object that represents the stack frame
+/// might change over time and instaces of this object can track the logical
+/// object that refers to a frame even if it does change.
+///
+/// These objects also don't keep execution objects around longer than they
+/// should since they use weak pointers. For example if an object refers
+/// to a stack frame and a stack frame is no longer in a thread, then a
+/// ExecutionContextRef object that refers to that frame will not be able
+/// to get a shared pointer to those objects since they are no longer around.
+///
+/// ExecutionContextRef objects can also be used as objects in classes
+/// that want to track a "previous execution context". Since the weak
+/// references to the execution objects (target, process, thread and frame)
+/// don't keep these objects around, they are safe to keep around.
+///
+/// The general rule of thumb is all long lived objects that want to
+/// refer to execution contexts should use ExecutionContextRef objcts.
+/// The ExecutionContext class is used to temporarily get shared
+/// pointers to any execution context objects that are still around
+/// so they are guaranteed to exist during a function that requires the
+/// objects. ExecutionContext objects should NOT be used for long term
+/// storage since they will keep objects alive with extra shared pointer
+/// references to these objects.
+//----------------------------------------------------------------------
+class ExecutionContextRef
+{
+public:
+ //------------------------------------------------------------------
+ /// Default Constructor.
+ //------------------------------------------------------------------
+ ExecutionContextRef();
+
+ //------------------------------------------------------------------
+ /// Copy Constructor.
+ //------------------------------------------------------------------
+ ExecutionContextRef (const ExecutionContextRef &rhs);
+
+ //------------------------------------------------------------------
+ /// Construct using an ExecutionContext object that might be NULL.
+ ///
+ /// If \a exe_ctx_ptr is valid, then make weak references to any
+ /// valid objects in the ExecutionContext, othewise no weak
+ /// references to any execution context objects will be made.
+ //------------------------------------------------------------------
+ ExecutionContextRef (const ExecutionContext *exe_ctx_ptr);
+
+ //------------------------------------------------------------------
+ /// Construct using an ExecutionContext object.
+ ///
+ /// Make weak references to any valid objects in the ExecutionContext.
+ //------------------------------------------------------------------
+ ExecutionContextRef (const ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Assignment operator
+ ///
+ /// Copy all weak refernces in \a rhs.
+ //------------------------------------------------------------------
+ ExecutionContextRef &
+ operator =(const ExecutionContextRef &rhs);
+
+ //------------------------------------------------------------------
+ /// Assignment operator from a ExecutionContext
+ ///
+ /// Make weak refernces to any stringly referenced objects in \a exe_ctx.
+ //------------------------------------------------------------------
+ ExecutionContextRef &
+ operator =(const ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Construct using the target and all the selected items inside of it
+ /// (the process and its selected thread, and the thread's selected
+ /// frame). If there is no selected thread, default to the first thread
+ /// If there is no selected frame, default to the first frame.
+ //------------------------------------------------------------------
+ ExecutionContextRef (Target *target, bool adopt_selected);
+
+ //------------------------------------------------------------------
+ /// Construct using an execution context scope.
+ ///
+ /// If the ExecutionContextScope object is valid and refers to a frame,
+ /// make weak refernces too the frame, thread, process and target.
+ /// If the ExecutionContextScope object is valid and refers to a thread,
+ /// make weak refernces too the thread, process and target.
+ /// If the ExecutionContextScope object is valid and refers to a process,
+ /// make weak refernces too the process and target.
+ /// If the ExecutionContextScope object is valid and refers to a target,
+ /// make weak refernces too the target.
+ //------------------------------------------------------------------
+ ExecutionContextRef (ExecutionContextScope *exe_scope);
+
+ //------------------------------------------------------------------
+ /// Construct using an execution context scope.
+ ///
+ /// If the ExecutionContextScope object refers to a frame,
+ /// make weak refernces too the frame, thread, process and target.
+ /// If the ExecutionContextScope object refers to a thread,
+ /// make weak refernces too the thread, process and target.
+ /// If the ExecutionContextScope object refers to a process,
+ /// make weak refernces too the process and target.
+ /// If the ExecutionContextScope object refers to a target,
+ /// make weak refernces too the target.
+ //------------------------------------------------------------------
+ ExecutionContextRef (ExecutionContextScope &exe_scope);
+
+ ~ExecutionContextRef();
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Sets the process and thread to NULL, and the frame index to an
+ /// invalid value.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Set accessor that creates a weak reference to the target
+ /// referenced in \a target_sp.
+ ///
+ /// If \a target_sp is valid this object will create a weak
+ /// reference to that object, otherwise any previous target weak
+ /// reference contained in this object will be reset.
+ ///
+ /// Only the weak reference to the target will be updated, no other
+ /// weak references will be modified. If you want this execution
+ /// context to make a weak reference to the target's process, use
+ /// the ExecutionContextRef::SetContext() functions.
+ ///
+ /// @see ExecutionContextRef::SetContext(const lldb::TargetSP &, bool)
+ //------------------------------------------------------------------
+ void
+ SetTargetSP (const lldb::TargetSP &target_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor that creates a weak reference to the process
+ /// referenced in \a process_sp.
+ ///
+ /// If \a process_sp is valid this object will create a weak
+ /// reference to that object, otherwise any previous process weak
+ /// reference contained in this object will be reset.
+ ///
+ /// Only the weak reference to the process will be updated, no other
+ /// weak references will be modified. If you want this execution
+ /// context to make a weak reference to the target, use the
+ /// ExecutionContextRef::SetContext() functions.
+ ///
+ /// @see ExecutionContextRef::SetContext(const lldb::ProcessSP &)
+ //------------------------------------------------------------------
+ void
+ SetProcessSP (const lldb::ProcessSP &process_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor that creates a weak reference to the thread
+ /// referenced in \a thread_sp.
+ ///
+ /// If \a thread_sp is valid this object will create a weak
+ /// reference to that object, otherwise any previous thread weak
+ /// reference contained in this object will be reset.
+ ///
+ /// Only the weak reference to the thread will be updated, no other
+ /// weak references will be modified. If you want this execution
+ /// context to make a weak reference to the thread's process and
+ /// target, use the ExecutionContextRef::SetContext() functions.
+ ///
+ /// @see ExecutionContextRef::SetContext(const lldb::ThreadSP &)
+ //------------------------------------------------------------------
+ void
+ SetThreadSP (const lldb::ThreadSP &thread_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor that creates a weak reference to the frame
+ /// referenced in \a frame_sp.
+ ///
+ /// If \a frame_sp is valid this object will create a weak
+ /// reference to that object, otherwise any previous frame weak
+ /// reference contained in this object will be reset.
+ ///
+ /// Only the weak reference to the frame will be updated, no other
+ /// weak references will be modified. If you want this execution
+ /// context to make a weak reference to the frame's thread, process
+ /// and target, use the ExecutionContextRef::SetContext() functions.
+ ///
+ /// @see ExecutionContextRef::SetContext(const lldb::StackFrameSP &)
+ //------------------------------------------------------------------
+ void
+ SetFrameSP (const lldb::StackFrameSP &frame_sp);
+
+ void
+ SetTargetPtr (Target* target, bool adopt_selected);
+
+ void
+ SetProcessPtr (Process *process);
+
+ void
+ SetThreadPtr (Thread *thread);
+
+ void
+ SetFramePtr (StackFrame *frame);
+
+ //------------------------------------------------------------------
+ /// Get accessor that creates a strong reference from the weak target
+ /// reference contained in this object.
+ ///
+ /// @returns
+ /// A shared pointer to a target that is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ lldb::TargetSP
+ GetTargetSP () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor that creates a strong reference from the weak process
+ /// reference contained in this object.
+ ///
+ /// @returns
+ /// A shared pointer to a process that is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ lldb::ProcessSP
+ GetProcessSP () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor that creates a strong reference from the weak thread
+ /// reference contained in this object.
+ ///
+ /// @returns
+ /// A shared pointer to a thread that is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ lldb::ThreadSP
+ GetThreadSP () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor that creates a strong reference from the weak frame
+ /// reference contained in this object.
+ ///
+ /// @returns
+ /// A shared pointer to a frame that is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ lldb::StackFrameSP
+ GetFrameSP () const;
+
+ //------------------------------------------------------------------
+ /// Create an ExecutionContext object from this object.
+ ///
+ /// Create strong references to any execution context objects that
+ /// are still valid. Any of the returned shared pointers in the
+ /// ExecutionContext objects is not guaranteed to be valid.
+ /// @returns
+ /// An execution context object that has strong references to
+ /// any valid weak references in this object.
+ //------------------------------------------------------------------
+ ExecutionContext
+ Lock () const;
+
+ //------------------------------------------------------------------
+ /// Returns true if this object has a weak reference to a thread.
+ /// The return value is only an indication of wether this object has
+ /// a weak reference and does not indicate wether the weak rerference
+ /// is valid or not.
+ //------------------------------------------------------------------
+ bool
+ HasThreadRef () const
+ {
+ return m_tid != LLDB_INVALID_THREAD_ID;
+ }
+
+ //------------------------------------------------------------------
+ /// Returns true if this object has a weak reference to a frame.
+ /// The return value is only an indication of wether this object has
+ /// a weak reference and does not indicate wether the weak rerference
+ /// is valid or not.
+ //------------------------------------------------------------------
+ bool
+ HasFrameRef () const
+ {
+ return m_stack_id.IsValid();
+ }
+
+ void
+ ClearThread ()
+ {
+ m_thread_wp.reset();
+ m_tid = LLDB_INVALID_THREAD_ID;
+ }
+
+ void
+ ClearFrame ()
+ {
+ m_stack_id.Clear();
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ lldb::TargetWP m_target_wp; ///< A weak reference to a target
+ lldb::ProcessWP m_process_wp; ///< A weak reference to a process
+ mutable lldb::ThreadWP m_thread_wp; ///< A weak reference to a thread
+ lldb::tid_t m_tid; ///< The thread ID that this object refers to in case the backing object changes
+ StackID m_stack_id; ///< The stack ID that this object refers to in case the backing object changes
+};
+
+//----------------------------------------------------------------------
+/// @class ExecutionContext ExecutionContext.h "lldb/Target/ExecutionContext.h"
+/// @brief A class that contains an execution context.
+///
+/// This baton object can be passed into any function that requires
+/// a context that specifies a target, process, thread and frame.
+/// These objects are designed to be used for short term execution
+/// context object storage while a function might be trying to evaluate
+/// something that requires a thread or frame. ExecutionContextRef
+/// objects can be used to initialize one of these objects to turn
+/// the weak execution context object references to the target, process,
+/// thread and frame into strong references (shared pointers) so that
+/// functions can guarantee that these objects won't go away in the
+/// middle of a function.
+///
+/// ExecutionContext objects should be used as short lived objects
+/// (typically on the stack) in order to lock down an execution context
+/// for local use and for passing down to other functions that also
+/// require specific contexts. They should NOT be used for long term
+/// storage, for long term storage use ExecutionContextRef objects.
+//----------------------------------------------------------------------
+class ExecutionContext
+{
+public:
+ //------------------------------------------------------------------
+ /// Default Constructor.
+ //------------------------------------------------------------------
+ ExecutionContext();
+
+ //------------------------------------------------------------------
+ // Copy constructor
+ //------------------------------------------------------------------
+ ExecutionContext (const ExecutionContext &rhs);
+
+ //------------------------------------------------------------------
+ // Adopt the target and optionally its current context.
+ //------------------------------------------------------------------
+ ExecutionContext (Target* t, bool fill_current_process_thread_frame = true);
+
+ //------------------------------------------------------------------
+ // Create execution contexts from shared pointers
+ //------------------------------------------------------------------
+ ExecutionContext (const lldb::TargetSP &target_sp, bool get_process);
+ ExecutionContext (const lldb::ProcessSP &process_sp);
+ ExecutionContext (const lldb::ThreadSP &thread_sp);
+ ExecutionContext (const lldb::StackFrameSP &frame_sp);
+ //------------------------------------------------------------------
+ // Create execution contexts from weak pointers
+ //------------------------------------------------------------------
+ ExecutionContext (const lldb::TargetWP &target_wp, bool get_process);
+ ExecutionContext (const lldb::ProcessWP &process_wp);
+ ExecutionContext (const lldb::ThreadWP &thread_wp);
+ ExecutionContext (const lldb::StackFrameWP &frame_wp);
+ ExecutionContext (const ExecutionContextRef &exe_ctx_ref);
+ ExecutionContext (const ExecutionContextRef *exe_ctx_ref);
+
+ // These two variants take in a locker, and grab the target, lock the API mutex into locker, then
+ // fill in the rest of the shared pointers.
+ ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker);
+ ExecutionContext (const ExecutionContextRef *exe_ctx_ref, Mutex::Locker &locker);
+ //------------------------------------------------------------------
+ // Create execution contexts from execution context scopes
+ //------------------------------------------------------------------
+ ExecutionContext (ExecutionContextScope *exe_scope);
+ ExecutionContext (ExecutionContextScope &exe_scope);
+
+
+ ExecutionContext &
+ operator =(const ExecutionContext &rhs);
+
+ bool
+ operator ==(const ExecutionContext &rhs) const;
+
+ bool
+ operator !=(const ExecutionContext &rhs) const;
+
+ //------------------------------------------------------------------
+ /// Construct with process, thread, and frame index.
+ ///
+ /// Initialize with process \a p, thread \a t, and frame index \a f.
+ ///
+ /// @param[in] process
+ /// The process for this execution context.
+ ///
+ /// @param[in] thread
+ /// The thread for this execution context.
+ ///
+ /// @param[in] frame
+ /// The frame index for this execution context.
+ //------------------------------------------------------------------
+ ExecutionContext (Process* process,
+ Thread *thread = NULL,
+ StackFrame * frame = NULL);
+
+
+ ~ExecutionContext();
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Sets the process and thread to NULL, and the frame index to an
+ /// invalid value.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ RegisterContext *
+ GetRegisterContext () const;
+
+ ExecutionContextScope *
+ GetBestExecutionContextScope () const;
+
+ uint32_t
+ GetAddressByteSize() const;
+
+ //------------------------------------------------------------------
+ /// Returns a pointer to the target object.
+ ///
+ /// The returned pointer might be NULL. Calling HasTargetScope(),
+ /// HasProcessScope(), HasThreadScope(), or HasFrameScope()
+ /// can help to pre-validate this pointer so that this accessor can
+ /// freely be used without having to check for NULL each time.
+ ///
+ /// @see ExecutionContext::HasTargetScope() const
+ /// @see ExecutionContext::HasProcessScope() const
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Target *
+ GetTargetPtr () const;
+
+ //------------------------------------------------------------------
+ /// Returns a pointer to the process object.
+ ///
+ /// The returned pointer might be NULL. Calling HasProcessScope(),
+ /// HasThreadScope(), or HasFrameScope() can help to pre-validate
+ /// this pointer so that this accessor can freely be used without
+ /// having to check for NULL each time.
+ ///
+ /// @see ExecutionContext::HasProcessScope() const
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Process *
+ GetProcessPtr () const;
+
+ //------------------------------------------------------------------
+ /// Returns a pointer to the thread object.
+ ///
+ /// The returned pointer might be NULL. Calling HasThreadScope() or
+ /// HasFrameScope() can help to pre-validate this pointer so that
+ /// this accessor can freely be used without having to check for
+ /// NULL each time.
+ ///
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Thread *
+ GetThreadPtr () const
+ {
+ return m_thread_sp.get();
+ }
+
+ //------------------------------------------------------------------
+ /// Returns a pointer to the frame object.
+ ///
+ /// The returned pointer might be NULL. Calling HasFrameScope(),
+ /// can help to pre-validate this pointer so that this accessor can
+ /// freely be used without having to check for NULL each time.
+ ///
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ StackFrame *
+ GetFramePtr () const
+ {
+ return m_frame_sp.get();
+ }
+
+ //------------------------------------------------------------------
+ /// Returns a reference to the target object.
+ ///
+ /// Clients should call HasTargetScope(), HasProcessScope(),
+ /// HasThreadScope(), or HasFrameScope() prior to calling this
+ /// function to ensure that this ExecutionContext object contains
+ /// a valid target.
+ ///
+ /// @see ExecutionContext::HasTargetScope() const
+ /// @see ExecutionContext::HasProcessScope() const
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Target &
+ GetTargetRef () const;
+
+ //------------------------------------------------------------------
+ /// Returns a reference to the process object.
+ ///
+ /// Clients should call HasProcessScope(), HasThreadScope(), or
+ /// HasFrameScope() prior to calling this function to ensure that
+ /// this ExecutionContext object contains a valid target.
+ ///
+ /// @see ExecutionContext::HasProcessScope() const
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Process &
+ GetProcessRef () const;
+
+ //------------------------------------------------------------------
+ /// Returns a reference to the thread object.
+ ///
+ /// Clients should call HasThreadScope(), or HasFrameScope() prior
+ /// to calling this function to ensure that this ExecutionContext
+ /// object contains a valid target.
+ ///
+ /// @see ExecutionContext::HasThreadScope() const
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ Thread &
+ GetThreadRef () const;
+
+ //------------------------------------------------------------------
+ /// Returns a reference to the thread object.
+ ///
+ /// Clients should call HasFrameScope() prior to calling this
+ /// function to ensure that this ExecutionContext object contains
+ /// a valid target.
+ ///
+ /// @see ExecutionContext::HasFrameScope() const
+ //------------------------------------------------------------------
+ StackFrame &
+ GetFrameRef () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor to get the target shared pointer.
+ ///
+ /// The returned shared pointer is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ const lldb::TargetSP &
+ GetTargetSP () const
+ {
+ return m_target_sp;
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor to get the process shared pointer.
+ ///
+ /// The returned shared pointer is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ const lldb::ProcessSP &
+ GetProcessSP () const
+ {
+ return m_process_sp;
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor to get the thread shared pointer.
+ ///
+ /// The returned shared pointer is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ const lldb::ThreadSP &
+ GetThreadSP () const
+ {
+ return m_thread_sp;
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor to get the frame shared pointer.
+ ///
+ /// The returned shared pointer is not guaranteed to be valid.
+ //------------------------------------------------------------------
+ const lldb::StackFrameSP &
+ GetFrameSP () const
+ {
+ return m_frame_sp;
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the target shared pointer.
+ //------------------------------------------------------------------
+ void
+ SetTargetSP (const lldb::TargetSP &target_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the process shared pointer.
+ //------------------------------------------------------------------
+ void
+ SetProcessSP (const lldb::ProcessSP &process_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the thread shared pointer.
+ //------------------------------------------------------------------
+ void
+ SetThreadSP (const lldb::ThreadSP &thread_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the frame shared pointer.
+ //------------------------------------------------------------------
+ void
+ SetFrameSP (const lldb::StackFrameSP &frame_sp);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the target shared pointer from a target
+ /// pointer.
+ //------------------------------------------------------------------
+ void
+ SetTargetPtr (Target* target);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the process shared pointer from a
+ /// process pointer.
+ //------------------------------------------------------------------
+ void
+ SetProcessPtr (Process *process);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the thread shared pointer from a thread
+ /// pointer.
+ //------------------------------------------------------------------
+ void
+ SetThreadPtr (Thread *thread);
+
+ //------------------------------------------------------------------
+ /// Set accessor to set only the frame shared pointer from a frame
+ /// pointer.
+ //------------------------------------------------------------------
+ void
+ SetFramePtr (StackFrame *frame);
+
+ //------------------------------------------------------------------
+ // Set the execution context using a target shared pointer.
+ //
+ // If "target_sp" is valid, sets the target context to match and
+ // if "get_process" is true, sets the process shared pointer if
+ // the target currently has a process.
+ //------------------------------------------------------------------
+ void
+ SetContext (const lldb::TargetSP &target_sp, bool get_process);
+
+ //------------------------------------------------------------------
+ // Set the execution context using a process shared pointer.
+ //
+ // If "process_sp" is valid, then set the process and target in this
+ // context. Thread and frame contexts will be cleared.
+ // If "process_sp" is not valid, all shared pointers are reset.
+ //------------------------------------------------------------------
+ void
+ SetContext (const lldb::ProcessSP &process_sp);
+
+ //------------------------------------------------------------------
+ // Set the execution context using a thread shared pointer.
+ //
+ // If "thread_sp" is valid, then set the thread, process and target
+ // in this context. The frame context will be cleared.
+ // If "thread_sp" is not valid, all shared pointers are reset.
+ //------------------------------------------------------------------
+ void
+ SetContext (const lldb::ThreadSP &thread_sp);
+
+ //------------------------------------------------------------------
+ // Set the execution context using a frame shared pointer.
+ //
+ // If "frame_sp" is valid, then set the frame, thread, process and
+ // target in this context
+ // If "frame_sp" is not valid, all shared pointers are reset.
+ //------------------------------------------------------------------
+ void
+ SetContext (const lldb::StackFrameSP &frame_sp);
+
+ //------------------------------------------------------------------
+ /// Returns true the ExecutionContext object contains a valid
+ /// target.
+ ///
+ /// This function can be called after initializing an ExecutionContext
+ /// object, and if it returns true, calls to GetTargetPtr() and
+ /// GetTargetRef() do not need to be checked for validity.
+ //------------------------------------------------------------------
+ bool
+ HasTargetScope () const;
+
+ //------------------------------------------------------------------
+ /// Returns true the ExecutionContext object contains a valid
+ /// target and process.
+ ///
+ /// This function can be called after initializing an ExecutionContext
+ /// object, and if it returns true, calls to GetTargetPtr() and
+ /// GetTargetRef(), GetProcessPtr(), and GetProcessRef(), do not
+ /// need to be checked for validity.
+ //------------------------------------------------------------------
+ bool
+ HasProcessScope () const;
+
+ //------------------------------------------------------------------
+ /// Returns true the ExecutionContext object contains a valid
+ /// target, process, and thread.
+ ///
+ /// This function can be called after initializing an ExecutionContext
+ /// object, and if it returns true, calls to GetTargetPtr(),
+ /// GetTargetRef(), GetProcessPtr(), GetProcessRef(), GetThreadPtr(),
+ /// and GetThreadRef() do not need to be checked for validity.
+ //------------------------------------------------------------------
+ bool
+ HasThreadScope () const;
+
+ //------------------------------------------------------------------
+ /// Returns true the ExecutionContext object contains a valid
+ /// target, process, thread and frame.
+ ///
+ /// This function can be called after initializing an ExecutionContext
+ /// object, and if it returns true, calls to GetTargetPtr(),
+ /// GetTargetRef(), GetProcessPtr(), GetProcessRef(), GetThreadPtr(),
+ /// GetThreadRef(), GetFramePtr(), and GetFrameRef() do not need
+ /// to be checked for validity.
+ //------------------------------------------------------------------
+ bool
+ HasFrameScope () const;
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ lldb::TargetSP m_target_sp; ///< The target that owns the process/thread/frame
+ lldb::ProcessSP m_process_sp; ///< The process that owns the thread/frame
+ lldb::ThreadSP m_thread_sp; ///< The thread that owns the frame
+ lldb::StackFrameSP m_frame_sp; ///< The stack frame in thread.
+};
+} // namespace lldb_private
+
+#endif // liblldb_ExecutionContext_h_
diff --git a/include/lldb/Target/ExecutionContextScope.h b/include/lldb/Target/ExecutionContextScope.h
new file mode 100644
index 000000000000..7ba40971af2c
--- /dev/null
+++ b/include/lldb/Target/ExecutionContextScope.h
@@ -0,0 +1,74 @@
+//===-- ExecutionContextScope.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ExecutionContextScope_h_
+#define liblldb_ExecutionContextScope_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ExecutionContextScope ExecutionContextScope.h "lldb/Symbol/ExecutionContextScope.h"
+/// @brief Inherit from this if your object can reconstruct its
+/// execution context.
+///
+/// Many objects that have pointers back to parent execution context
+/// objects can inherit from this pure virtual class can reconstruct
+/// their execution context without having to keep a complete
+/// ExecutionContext object in the object state. Examples of these
+/// objects include: Process, Thread, RegisterContext and StackFrame.
+///
+/// Bbjects can contain a valid pointer to an instance of this so they
+/// can reconstruct the execution context.
+///
+/// Objects that adhere to this protocol can reconstruct enough of a
+/// execution context to allow functions that take a execution contexts
+/// to be called.
+//----------------------------------------------------------------------
+class ExecutionContextScope
+{
+public:
+ virtual
+ ~ExecutionContextScope () {}
+
+ virtual lldb::TargetSP
+ CalculateTarget () = 0;
+
+ virtual lldb::ProcessSP
+ CalculateProcess () = 0;
+
+ virtual lldb::ThreadSP
+ CalculateThread () = 0;
+
+ virtual lldb::StackFrameSP
+ CalculateStackFrame () = 0;
+
+ //------------------------------------------------------------------
+ /// Reconstruct the object's execution context into \a sc.
+ ///
+ /// The object should fill in as much of the ExecutionContextScope as it
+ /// can so function calls that require a execution context can be made
+ /// for the given object.
+ ///
+ /// @param[out] exe_ctx
+ /// A reference to an execution context object that gets filled
+ /// in.
+ //------------------------------------------------------------------
+ virtual void
+ CalculateExecutionContext (ExecutionContext &exe_ctx) = 0;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ExecutionContextScope_h_
diff --git a/include/lldb/Target/LanguageRuntime.h b/include/lldb/Target/LanguageRuntime.h
new file mode 100644
index 000000000000..93c0437da75d
--- /dev/null
+++ b/include/lldb/Target/LanguageRuntime.h
@@ -0,0 +1,113 @@
+//===-- LanguageRuntime.h ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LanguageRuntime_h_
+#define liblldb_LanguageRuntime_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Breakpoint/BreakpointResolverName.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Target/ExecutionContextScope.h"
+
+namespace lldb_private {
+
+class LanguageRuntime :
+ public PluginInterface
+{
+public:
+ virtual
+ ~LanguageRuntime();
+
+ static LanguageRuntime*
+ FindPlugin (Process *process, lldb::LanguageType language);
+
+ virtual lldb::LanguageType
+ GetLanguageType () const = 0;
+
+ virtual bool
+ GetObjectDescription (Stream &str, ValueObject &object) = 0;
+
+ virtual bool
+ GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope) = 0;
+
+ // this call should return true if it could set the name and/or the type
+ virtual bool
+ GetDynamicTypeAndAddress (ValueObject &in_value,
+ lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name,
+ Address &address) = 0;
+
+ // This should be a fast test to determine whether it is likely that this value would
+ // have a dynamic type.
+ virtual bool
+ CouldHaveDynamicValue (ValueObject &in_value) = 0;
+
+ virtual void
+ SetExceptionBreakpoints ()
+ {
+ }
+
+ virtual void
+ ClearExceptionBreakpoints ()
+ {
+ }
+
+ virtual bool
+ ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason)
+ {
+ return false;
+ }
+
+ static lldb::BreakpointSP
+ CreateExceptionBreakpoint (Target &target,
+ lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp,
+ bool is_internal = false);
+
+ static lldb::LanguageType
+ GetLanguageTypeFromString (const char *string);
+
+ static const char *
+ GetNameForLanguageType (lldb::LanguageType language);
+
+ Process *
+ GetProcess()
+ {
+ return m_process;
+ }
+
+ virtual lldb::BreakpointResolverSP
+ CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp) = 0;
+
+ virtual lldb::SearchFilterSP
+ CreateExceptionSearchFilter ();
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from LanguageRuntime can see and modify these
+ //------------------------------------------------------------------
+
+ LanguageRuntime(Process *process);
+ Process *m_process;
+private:
+ DISALLOW_COPY_AND_ASSIGN (LanguageRuntime);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_LanguageRuntime_h_
diff --git a/include/lldb/Target/Memory.h b/include/lldb/Target/Memory.h
new file mode 100644
index 000000000000..568bbcdf2f7c
--- /dev/null
+++ b/include/lldb/Target/Memory.h
@@ -0,0 +1,196 @@
+//===-- Memory.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Memory_h_
+#define liblldb_Memory_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+ //----------------------------------------------------------------------
+ // A class to track memory that was read from a live process between
+ // runs.
+ //----------------------------------------------------------------------
+ class MemoryCache
+ {
+ public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ MemoryCache (Process &process);
+
+ ~MemoryCache ();
+
+ void
+ Clear(bool clear_invalid_ranges = false);
+
+ void
+ Flush (lldb::addr_t addr, size_t size);
+
+ size_t
+ Read (lldb::addr_t addr,
+ void *dst,
+ size_t dst_len,
+ Error &error);
+
+ uint32_t
+ GetMemoryCacheLineSize() const
+ {
+ return m_cache_line_byte_size ;
+ }
+
+ void
+ AddInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
+
+ bool
+ RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
+
+ protected:
+ typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
+ typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
+ //------------------------------------------------------------------
+ // Classes that inherit from MemoryCache can see and modify these
+ //------------------------------------------------------------------
+ Process &m_process;
+ uint32_t m_cache_line_byte_size;
+ Mutex m_mutex;
+ BlockMap m_cache;
+ InvalidRanges m_invalid_ranges;
+ private:
+ DISALLOW_COPY_AND_ASSIGN (MemoryCache);
+ };
+
+
+ class AllocatedBlock
+ {
+ public:
+ AllocatedBlock (lldb::addr_t addr,
+ uint32_t byte_size,
+ uint32_t permissions,
+ uint32_t chunk_size);
+
+ ~AllocatedBlock ();
+
+ lldb::addr_t
+ ReserveBlock (uint32_t size);
+
+ bool
+ FreeBlock (lldb::addr_t addr);
+
+ lldb::addr_t
+ GetBaseAddress () const
+ {
+ return m_addr;
+ }
+
+ uint32_t
+ GetByteSize () const
+ {
+ return m_byte_size;
+ }
+
+ uint32_t
+ GetPermissions () const
+ {
+ return m_permissions;
+ }
+
+ uint32_t
+ GetChunkSize () const
+ {
+ return m_chunk_size;
+ }
+
+ bool
+ Contains (lldb::addr_t addr) const
+ {
+ return ((addr >= m_addr) && addr < (m_addr + m_byte_size));
+ }
+ protected:
+ uint32_t
+ TotalChunks () const
+ {
+ return m_byte_size / m_chunk_size;
+ }
+
+ uint32_t
+ CalculateChunksNeededForSize (uint32_t size) const
+ {
+ return (size + m_chunk_size - 1) / m_chunk_size;
+ }
+ const lldb::addr_t m_addr; // Base address of this block of memory
+ const uint32_t m_byte_size; // 4GB of chunk should be enough...
+ const uint32_t m_permissions; // Permissions for this memory (logical OR of lldb::Permissions bits)
+ const uint32_t m_chunk_size; // The size of chunks that the memory at m_addr is divied up into
+ typedef std::map<uint32_t, uint32_t> OffsetToChunkSize;
+ OffsetToChunkSize m_offset_to_chunk_size;
+ };
+
+
+ //----------------------------------------------------------------------
+ // A class that can track allocated memory and give out allocated memory
+ // without us having to make an allocate/deallocate call every time we
+ // need some memory in a process that is being debugged.
+ //----------------------------------------------------------------------
+ class AllocatedMemoryCache
+ {
+ public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ AllocatedMemoryCache (Process &process);
+
+ ~AllocatedMemoryCache ();
+
+ void
+ Clear();
+
+ lldb::addr_t
+ AllocateMemory (size_t byte_size,
+ uint32_t permissions,
+ Error &error);
+
+ bool
+ DeallocateMemory (lldb::addr_t ptr);
+
+ protected:
+ typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP;
+
+ AllocatedBlockSP
+ AllocatePage (uint32_t byte_size,
+ uint32_t permissions,
+ uint32_t chunk_size,
+ Error &error);
+
+
+ //------------------------------------------------------------------
+ // Classes that inherit from MemoryCache can see and modify these
+ //------------------------------------------------------------------
+ Process &m_process;
+ Mutex m_mutex;
+ typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
+ PermissionsToBlockMap m_memory_map;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN (AllocatedMemoryCache);
+ };
+
+} // namespace lldb_private
+
+#endif // liblldb_Memory_h_
diff --git a/include/lldb/Target/ObjCLanguageRuntime.h b/include/lldb/Target/ObjCLanguageRuntime.h
new file mode 100644
index 000000000000..7bac57256444
--- /dev/null
+++ b/include/lldb/Target/ObjCLanguageRuntime.h
@@ -0,0 +1,604 @@
+//===-- ObjCLanguageRuntime.h ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ObjCLanguageRuntime_h_
+#define liblldb_ObjCLanguageRuntime_h_
+
+// C Includes
+// C++ Includes
+#include <functional>
+#include <map>
+#include <unordered_set>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/TypeVendor.h"
+#include "lldb/Target/LanguageRuntime.h"
+
+namespace lldb_private {
+
+class ClangUtilityFunction;
+
+class ObjCLanguageRuntime :
+ public LanguageRuntime
+{
+public:
+ class MethodName
+ {
+ public:
+ enum Type
+ {
+ eTypeUnspecified,
+ eTypeClassMethod,
+ eTypeInstanceMethod
+ };
+
+ MethodName () :
+ m_full(),
+ m_class(),
+ m_category(),
+ m_selector(),
+ m_type (eTypeUnspecified),
+ m_category_is_valid (false)
+ {
+ }
+
+ MethodName (const char *name, bool strict) :
+ m_full(),
+ m_class(),
+ m_category(),
+ m_selector(),
+ m_type (eTypeUnspecified),
+ m_category_is_valid (false)
+ {
+ SetName (name, strict);
+ }
+
+ void
+ Clear();
+
+ bool
+ IsValid (bool strict) const
+ {
+ // If "strict" is true, the name must have everything specified including
+ // the leading "+" or "-" on the method name
+ if (strict && m_type == eTypeUnspecified)
+ return false;
+ // Other than that, m_full will only be filled in if the objective C
+ // name is valid.
+ return (bool)m_full;
+ }
+
+ bool
+ HasCategory()
+ {
+ return (bool)GetCategory();
+ }
+
+ Type
+ GetType () const
+ {
+ return m_type;
+ }
+
+ const ConstString &
+ GetFullName () const
+ {
+ return m_full;
+ }
+
+ ConstString
+ GetFullNameWithoutCategory (bool empty_if_no_category);
+
+ bool
+ SetName (const char *name, bool strict);
+
+ const ConstString &
+ GetClassName ();
+
+ const ConstString &
+ GetClassNameWithCategory ();
+
+ const ConstString &
+ GetCategory ();
+
+ const ConstString &
+ GetSelector ();
+
+ // Get all possible names for a method. Examples:
+ // If name is "+[NSString(my_additions) myStringWithCString:]"
+ // names[0] => "+[NSString(my_additions) myStringWithCString:]"
+ // names[1] => "+[NSString myStringWithCString:]"
+ // If name is specified without the leading '+' or '-' like "[NSString(my_additions) myStringWithCString:]"
+ // names[0] => "+[NSString(my_additions) myStringWithCString:]"
+ // names[1] => "-[NSString(my_additions) myStringWithCString:]"
+ // names[2] => "+[NSString myStringWithCString:]"
+ // names[3] => "-[NSString myStringWithCString:]"
+ size_t
+ GetFullNames (std::vector<ConstString> &names, bool append);
+ protected:
+ ConstString m_full; // Full name: "+[NSString(my_additions) myStringWithCString:]"
+ ConstString m_class; // Class name: "NSString"
+ ConstString m_class_category; // Class with category: "NSString(my_additions)"
+ ConstString m_category; // Category: "my_additions"
+ ConstString m_selector; // Selector: "myStringWithCString:"
+ Type m_type;
+ bool m_category_is_valid;
+
+ };
+ typedef lldb::addr_t ObjCISA;
+
+ class ClassDescriptor;
+ typedef std::shared_ptr<ClassDescriptor> ClassDescriptorSP;
+
+ // the information that we want to support retrieving from an ObjC class
+ // this needs to be pure virtual since there are at least 2 different implementations
+ // of the runtime, and more might come
+ class ClassDescriptor
+ {
+ public:
+
+ ClassDescriptor() :
+ m_is_kvo (eLazyBoolCalculate),
+ m_is_cf (eLazyBoolCalculate),
+ m_type_wp ()
+ {
+ }
+
+ virtual
+ ~ClassDescriptor ()
+ {
+ }
+
+ virtual ConstString
+ GetClassName () = 0;
+
+ virtual ClassDescriptorSP
+ GetSuperclass () = 0;
+
+ // virtual if any implementation has some other version-specific rules
+ // but for the known v1/v2 this is all that needs to be done
+ virtual bool
+ IsKVO ()
+ {
+ if (m_is_kvo == eLazyBoolCalculate)
+ {
+ const char* class_name = GetClassName().AsCString();
+ if (class_name && *class_name)
+ m_is_kvo = (LazyBool)(strstr(class_name,"NSKVONotifying_") == class_name);
+ }
+ return (m_is_kvo == eLazyBoolYes);
+ }
+
+ // virtual if any implementation has some other version-specific rules
+ // but for the known v1/v2 this is all that needs to be done
+ virtual bool
+ IsCFType ()
+ {
+ if (m_is_cf == eLazyBoolCalculate)
+ {
+ const char* class_name = GetClassName().AsCString();
+ if (class_name && *class_name)
+ m_is_cf = (LazyBool)(strcmp(class_name,"__NSCFType") == 0 ||
+ strcmp(class_name,"NSCFType") == 0);
+ }
+ return (m_is_cf == eLazyBoolYes);
+ }
+
+ virtual bool
+ IsValid () = 0;
+
+ virtual bool
+ GetTaggedPointerInfo (uint64_t* info_bits = NULL,
+ uint64_t* value_bits = NULL,
+ uint64_t* payload = NULL) = 0;
+
+ virtual uint64_t
+ GetInstanceSize () = 0;
+
+ // use to implement version-specific additional constraints on pointers
+ virtual bool
+ CheckPointer (lldb::addr_t value,
+ uint32_t ptr_size) const
+ {
+ return true;
+ }
+
+ virtual ObjCISA
+ GetISA () = 0;
+
+ // This should return true iff the interface could be completed
+ virtual bool
+ Describe (std::function <void (ObjCISA)> const &superclass_func,
+ std::function <bool (const char*, const char*)> const &instance_method_func,
+ std::function <bool (const char*, const char*)> const &class_method_func,
+ std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func)
+ {
+ return false;
+ }
+
+ lldb::TypeSP
+ GetType ()
+ {
+ return m_type_wp.lock();
+ }
+
+ void
+ SetType (const lldb::TypeSP &type_sp)
+ {
+ m_type_wp = type_sp;
+ }
+
+ protected:
+ bool
+ IsPointerValid (lldb::addr_t value,
+ uint32_t ptr_size,
+ bool allow_NULLs = false,
+ bool allow_tagged = false,
+ bool check_version_specific = false) const;
+
+ private:
+ LazyBool m_is_kvo;
+ LazyBool m_is_cf;
+ lldb::TypeWP m_type_wp;
+ };
+
+ virtual ClassDescriptorSP
+ GetClassDescriptor (ValueObject& in_value);
+
+ ClassDescriptorSP
+ GetNonKVOClassDescriptor (ValueObject& in_value);
+
+ virtual ClassDescriptorSP
+ GetClassDescriptorFromClassName (const ConstString &class_name);
+
+ virtual ClassDescriptorSP
+ GetClassDescriptorFromISA (ObjCISA isa);
+
+ ClassDescriptorSP
+ GetNonKVOClassDescriptor (ObjCISA isa);
+
+ virtual
+ ~ObjCLanguageRuntime();
+
+ virtual lldb::LanguageType
+ GetLanguageType () const
+ {
+ return lldb::eLanguageTypeObjC;
+ }
+
+ virtual bool
+ IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) = 0;
+
+ virtual bool
+ ReadObjCLibrary (const lldb::ModuleSP &module_sp) = 0;
+
+ virtual bool
+ HasReadObjCLibrary () = 0;
+
+ virtual lldb::ThreadPlanSP
+ GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0;
+
+ lldb::addr_t
+ LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t sel);
+
+ void
+ AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr);
+
+ TypeAndOrName
+ LookupInClassNameCache (lldb::addr_t class_addr);
+
+ void
+ AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp);
+
+ void
+ AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name);
+
+ lldb::TypeSP
+ LookupInCompleteClassCache (ConstString &name);
+
+ virtual ClangUtilityFunction *
+ CreateObjectChecker (const char *) = 0;
+
+ virtual ObjCRuntimeVersions
+ GetRuntimeVersion ()
+ {
+ return eObjC_VersionUnknown;
+ }
+
+ bool
+ IsValidISA(ObjCISA isa)
+ {
+ UpdateISAToDescriptorMap();
+ return m_isa_to_descriptor.count(isa) > 0;
+ }
+
+ virtual void
+ UpdateISAToDescriptorMapIfNeeded() = 0;
+
+ void
+ UpdateISAToDescriptorMap()
+ {
+ if (m_process && m_process->GetStopID() != m_isa_to_descriptor_stop_id)
+ {
+ UpdateISAToDescriptorMapIfNeeded ();
+ }
+ }
+
+ virtual ObjCISA
+ GetISA(const ConstString &name);
+
+ virtual ConstString
+ GetActualTypeName(ObjCISA isa);
+
+ virtual ObjCISA
+ GetParentClass(ObjCISA isa);
+
+ virtual TypeVendor *
+ GetTypeVendor()
+ {
+ return NULL;
+ }
+
+ // Finds the byte offset of the child_type ivar in parent_type. If it can't find the
+ // offset, returns LLDB_INVALID_IVAR_OFFSET.
+
+ virtual size_t
+ GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name);
+
+ // Given the name of an Objective-C runtime symbol (e.g., ivar offset symbol),
+ // try to determine from the runtime what the value of that symbol would be.
+ // Useful when the underlying binary is stripped.
+ virtual lldb::addr_t
+ LookupRuntimeSymbol (const ConstString &name)
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ //------------------------------------------------------------------
+ /// Chop up an objective C function prototype.
+ ///
+ /// Chop up an objective C function fullname and optionally fill in
+ /// any non-NULL ConstString objects. If a ConstString * is NULL,
+ /// then this name doesn't get filled in
+ ///
+ /// @param[in] name
+ /// A fully specified objective C function name. The string might
+ /// contain a category and it includes the leading "+" or "-" and
+ /// the square brackets, no types for the arguments, just the plain
+ /// selector. A few examples:
+ /// "-[NSStringDrawingContext init]"
+ /// "-[NSStringDrawingContext addString:inRect:]"
+ /// "-[NSString(NSStringDrawing) sizeWithAttributes:]"
+ /// "+[NSString(NSStringDrawing) usesFontLeading]"
+ ///
+ /// @param[out] class_name
+ /// If non-NULL, this string will be filled in with the class
+ /// name including the category. The examples above would return:
+ /// "NSStringDrawingContext"
+ /// "NSStringDrawingContext"
+ /// "NSString(NSStringDrawing)"
+ /// "NSString(NSStringDrawing)"
+ ///
+ /// @param[out] selector_name
+ /// If non-NULL, this string will be filled in with the selector
+ /// name. The examples above would return:
+ /// "init"
+ /// "addString:inRect:"
+ /// "sizeWithAttributes:"
+ /// "usesFontLeading"
+ ///
+ /// @param[out] name_sans_category
+ /// If non-NULL, this string will be filled in with the class
+ /// name _without_ the category. If there is no category, and empty
+ /// string will be returned (as the result would be normally returned
+ /// in the "class_name" argument). The examples above would return:
+ /// <empty>
+ /// <empty>
+ /// "-[NSString sizeWithAttributes:]"
+ /// "+[NSString usesFontLeading]"
+ ///
+ /// @param[out] class_name_sans_category
+ /// If non-NULL, this string will be filled in with the prototype
+ /// name _without_ the category. If there is no category, and empty
+ /// string will be returned (as this is already the value that was
+ /// passed in). The examples above would return:
+ /// <empty>
+ /// <empty>
+ /// "NSString"
+ /// "NSString"
+ ///
+ /// @return
+ /// Returns the number of strings that were successfully filled
+ /// in.
+ //------------------------------------------------------------------
+// static uint32_t
+// ParseMethodName (const char *name,
+// ConstString *class_name, // Class name (with category if there is one)
+// ConstString *selector_name, // selector only
+// ConstString *name_sans_category, // full function name with no category (empty if no category)
+// ConstString *class_name_sans_category);// Class name without category (empty if no category)
+
+ static bool
+ IsPossibleObjCMethodName (const char *name)
+ {
+ if (!name)
+ return false;
+ bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '[';
+ bool ends_right = (name[strlen(name) - 1] == ']');
+ return (starts_right && ends_right);
+ }
+
+ static bool
+ IsPossibleObjCSelector (const char *name)
+ {
+ if (!name)
+ return false;
+
+ if (strchr(name, ':') == NULL)
+ return true;
+ else if (name[strlen(name) - 1] == ':')
+ return true;
+ else
+ return false;
+ }
+
+ bool
+ HasNewLiteralsAndIndexing ()
+ {
+ if (m_has_new_literals_and_indexing == eLazyBoolCalculate)
+ {
+ if (CalculateHasNewLiteralsAndIndexing())
+ m_has_new_literals_and_indexing = eLazyBoolYes;
+ else
+ m_has_new_literals_and_indexing = eLazyBoolNo;
+ }
+
+ return (m_has_new_literals_and_indexing == eLazyBoolYes);
+ }
+
+ virtual void
+ SymbolsDidLoad (const ModuleList& module_list)
+ {
+ m_negative_complete_class_cache.clear();
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from ObjCLanguageRuntime can see and modify these
+ //------------------------------------------------------------------
+ ObjCLanguageRuntime(Process *process);
+
+ virtual bool CalculateHasNewLiteralsAndIndexing()
+ {
+ return false;
+ }
+
+
+ bool
+ ISAIsCached (ObjCISA isa) const
+ {
+ return m_isa_to_descriptor.find(isa) != m_isa_to_descriptor.end();
+ }
+
+ bool
+ AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp)
+ {
+ if (isa != 0)
+ {
+ m_isa_to_descriptor[isa] = descriptor_sp;
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name);
+
+ bool
+ AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, uint32_t class_name_hash)
+ {
+ if (isa != 0)
+ {
+ m_isa_to_descriptor[isa] = descriptor_sp;
+ m_hash_to_isa_map.insert(std::make_pair(class_name_hash, isa));
+ return true;
+ }
+ return false;
+ }
+
+private:
+ // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver
+ // function over and over.
+
+ // FIXME: We need to watch for the loading of Protocols, and flush the cache for any
+ // class that we see so changed.
+
+ struct ClassAndSel
+ {
+ ClassAndSel()
+ {
+ sel_addr = LLDB_INVALID_ADDRESS;
+ class_addr = LLDB_INVALID_ADDRESS;
+ }
+ ClassAndSel (lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) :
+ class_addr (in_class_addr),
+ sel_addr(in_sel_addr)
+ {
+ }
+ bool operator== (const ClassAndSel &rhs)
+ {
+ if (class_addr == rhs.class_addr
+ && sel_addr == rhs.sel_addr)
+ return true;
+ else
+ return false;
+ }
+
+ bool operator< (const ClassAndSel &rhs) const
+ {
+ if (class_addr < rhs.class_addr)
+ return true;
+ else if (class_addr > rhs.class_addr)
+ return false;
+ else
+ {
+ if (sel_addr < rhs.sel_addr)
+ return true;
+ else
+ return false;
+ }
+ }
+
+ lldb::addr_t class_addr;
+ lldb::addr_t sel_addr;
+ };
+
+ typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap;
+ typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap;
+ typedef std::multimap<uint32_t, ObjCISA> HashToISAMap;
+ typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
+ typedef HashToISAMap::iterator HashToISAIterator;
+
+ MsgImplMap m_impl_cache;
+ LazyBool m_has_new_literals_and_indexing;
+ ISAToDescriptorMap m_isa_to_descriptor;
+ HashToISAMap m_hash_to_isa_map;
+
+protected:
+ uint32_t m_isa_to_descriptor_stop_id;
+
+ typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap;
+ CompleteClassMap m_complete_class_cache;
+
+ struct ConstStringSetHelpers {
+ size_t operator () (const ConstString& arg) const // for hashing
+ {
+ return (size_t)arg.GetCString();
+ }
+ bool operator () (const ConstString& arg1, const ConstString& arg2) const // for equality
+ {
+ return arg1.operator==(arg2);
+ }
+ };
+ typedef std::unordered_set<ConstString, ConstStringSetHelpers, ConstStringSetHelpers> CompleteClassSet;
+ CompleteClassSet m_negative_complete_class_cache;
+
+ ISAToDescriptorIterator
+ GetDescriptorIterator (const ConstString &name);
+
+ DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ObjCLanguageRuntime_h_
diff --git a/include/lldb/Target/OperatingSystem.h b/include/lldb/Target/OperatingSystem.h
new file mode 100644
index 000000000000..f1c0eb06026f
--- /dev/null
+++ b/include/lldb/Target/OperatingSystem.h
@@ -0,0 +1,101 @@
+//===-- OperatingSystem.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OperatingSystem_h_
+#define liblldb_OperatingSystem_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/PluginInterface.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class OperatingSystem OperatingSystem.h "lldb/Target/OperatingSystem.h"
+/// @brief A plug-in interface definition class for halted OS helpers.
+///
+/// Halted OS plug-ins can be used by any process to locate and create
+/// OS objects, like threads, during the lifetime of a debug session.
+/// This is commonly used when attaching to an operating system that is
+/// halted, such as when debugging over JTAG or connecting to low level
+/// kernel debug services.
+//----------------------------------------------------------------------
+
+class OperatingSystem :
+ public PluginInterface
+
+{
+public:
+ //------------------------------------------------------------------
+ /// Find a halted OS plugin for a given process.
+ ///
+ /// Scans the installed OperatingSystem plug-ins and tries to find
+ /// an instance that matches the current target triple and
+ /// executable.
+ ///
+ /// @param[in] process
+ /// The process for which to try and locate a halted OS
+ /// plug-in instance.
+ ///
+ /// @param[in] plugin_name
+ /// An optional name of a specific halted OS plug-in that
+ /// should be used. If NULL, pick the best plug-in.
+ //------------------------------------------------------------------
+ static OperatingSystem*
+ FindPlugin (Process *process, const char *plugin_name);
+
+ //------------------------------------------------------------------
+ // Class Methods
+ //------------------------------------------------------------------
+ OperatingSystem (Process *process);
+
+ virtual
+ ~OperatingSystem();
+
+ //------------------------------------------------------------------
+ // Plug-in Methods
+ //------------------------------------------------------------------
+ virtual bool
+ UpdateThreadList (ThreadList &old_thread_list,
+ ThreadList &real_thread_list,
+ ThreadList &new_thread_list) = 0;
+
+ virtual void
+ ThreadWasSelected (Thread *thread) = 0;
+
+ virtual lldb::RegisterContextSP
+ CreateRegisterContextForThread (Thread *thread, lldb::addr_t reg_data_addr) = 0;
+
+ virtual lldb::StopInfoSP
+ CreateThreadStopReason (Thread *thread) = 0;
+
+ virtual lldb::ThreadSP
+ CreateThread (lldb::tid_t tid, lldb::addr_t context)
+ {
+ return lldb::ThreadSP();
+ }
+
+ virtual bool
+ IsOperatingSystemPluginThread (const lldb::ThreadSP &thread_sp);
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ Process* m_process; ///< The process that this dynamic loader plug-in is tracking.
+private:
+ DISALLOW_COPY_AND_ASSIGN (OperatingSystem);
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_OperatingSystem_h_
diff --git a/include/lldb/Target/PathMappingList.h b/include/lldb/Target/PathMappingList.h
new file mode 100644
index 000000000000..b5bcbbfd768f
--- /dev/null
+++ b/include/lldb/Target/PathMappingList.h
@@ -0,0 +1,171 @@
+//===-- PathMappingList.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_PathMappingList_h_
+#define liblldb_PathMappingList_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <vector>
+// Other libraries and framework includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Error.h"
+// Project includes
+
+namespace lldb_private {
+
+class PathMappingList
+{
+public:
+
+ typedef void (*ChangedCallback) (const PathMappingList &path_list,
+ void *baton);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ PathMappingList ();
+
+ PathMappingList (ChangedCallback callback,
+ void *callback_baton);
+
+ PathMappingList (const PathMappingList &rhs);
+
+ ~PathMappingList ();
+
+ const PathMappingList &
+ operator =(const PathMappingList &rhs);
+
+ void
+ Append (const ConstString &path, const ConstString &replacement, bool notify);
+
+ void
+ Append (const PathMappingList &rhs, bool notify);
+
+ void
+ Clear (bool notify);
+
+ // By default, dump all pairs.
+ void
+ Dump (Stream *s, int pair_index=-1);
+
+ bool
+ IsEmpty() const
+ {
+ return m_pairs.empty();
+ }
+
+ size_t
+ GetSize () const
+ {
+ return m_pairs.size();
+ }
+
+ bool
+ GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const;
+
+ void
+ Insert (const ConstString &path,
+ const ConstString &replacement,
+ uint32_t insert_idx,
+ bool notify);
+
+ bool
+ Remove (off_t index, bool notify);
+
+ bool
+ Remove (const ConstString &path, bool notify);
+
+ bool
+ Replace (const ConstString &path,
+ const ConstString &replacement,
+ bool notify);
+
+ bool
+ Replace (const ConstString &path,
+ const ConstString &replacement,
+ uint32_t index,
+ bool notify);
+ bool
+ RemapPath (const ConstString &path, ConstString &new_path) const;
+
+ //------------------------------------------------------------------
+ /// Remaps a source file given \a path into \a new_path.
+ ///
+ /// Remaps \a path if any source remappings match. This function
+ /// does NOT stat the file system so it can be used in tight loops
+ /// where debug info is being parsed.
+ ///
+ /// @param[in] path
+ /// The original source file path to try and remap.
+ ///
+ /// @param[out] new_path
+ /// The newly remapped filespec that is may or may not exist.
+ ///
+ /// @return
+ /// /b true if \a path was successfully located and \a new_path
+ /// is filled in with a new source path, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ RemapPath (const char *path, std::string &new_path) const;
+
+
+ //------------------------------------------------------------------
+ /// Finds a source file given a file spec using the path remappings.
+ ///
+ /// Tries to resolve \a orig_spec by checking the path remappings.
+ /// It makes sure the file exists by checking with the file system,
+ /// so this call can be expensive if the remappings are on a network
+ /// or are even on the local file system, so use this function
+ /// sparingly (not in a tight debug info parsing loop).
+ ///
+ /// @param[in] orig_spec
+ /// The original source file path to try and remap.
+ ///
+ /// @param[out] new_spec
+ /// The newly remapped filespec that is guaranteed to exist.
+ ///
+ /// @return
+ /// /b true if \a orig_spec was successfully located and
+ /// \a new_spec is filled in with an existing file spec,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const;
+
+ uint32_t
+ FindIndexForPath (const ConstString &path) const;
+
+ uint32_t
+ GetModificationID() const
+ {
+ return m_mod_id;
+ }
+protected:
+ typedef std::pair <ConstString, ConstString> pair;
+ typedef std::vector <pair> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ iterator
+ FindIteratorForPath (const ConstString &path);
+
+ const_iterator
+ FindIteratorForPath (const ConstString &path) const;
+
+ collection m_pairs;
+ ChangedCallback m_callback;
+ void * m_callback_baton;
+ uint32_t m_mod_id; // Incremented anytime anything is added or removed.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_PathMappingList_h_
diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h
new file mode 100644
index 000000000000..b0a07946e74e
--- /dev/null
+++ b/include/lldb/Target/Platform.h
@@ -0,0 +1,755 @@
+//===-- Platform.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Platform_h_
+#define liblldb_Platform_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+ //----------------------------------------------------------------------
+ /// @class Platform Platform.h "lldb/Target/Platform.h"
+ /// @brief A plug-in interface definition class for debug platform that
+ /// includes many platform abilities such as:
+ /// @li getting platform information such as supported architectures,
+ /// supported binary file formats and more
+ /// @li launching new processes
+ /// @li attaching to existing processes
+ /// @li download/upload files
+ /// @li execute shell commands
+ /// @li listing and getting info for existing processes
+ /// @li attaching and possibly debugging the platform's kernel
+ //----------------------------------------------------------------------
+ class Platform : public PluginInterface
+ {
+ public:
+
+ //------------------------------------------------------------------
+ /// Get the native host platform plug-in.
+ ///
+ /// There should only be one of these for each host that LLDB runs
+ /// upon that should be statically compiled in and registered using
+ /// preprocessor macros or other similar build mechanisms in a
+ /// PlatformSubclass::Initialize() function.
+ ///
+ /// This platform will be used as the default platform when launching
+ /// or attaching to processes unless another platform is specified.
+ //------------------------------------------------------------------
+ static lldb::PlatformSP
+ GetDefaultPlatform ();
+
+ static lldb::PlatformSP
+ GetPlatformForArchitecture (const ArchSpec &arch,
+ ArchSpec *platform_arch_ptr);
+
+ static const char *
+ GetHostPlatformName ();
+
+ static void
+ SetDefaultPlatform (const lldb::PlatformSP &platform_sp);
+
+ static lldb::PlatformSP
+ Create (const char *platform_name, Error &error);
+
+ static lldb::PlatformSP
+ Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error);
+
+ static uint32_t
+ GetNumConnectedRemotePlatforms ();
+
+ static lldb::PlatformSP
+ GetConnectedRemotePlatformAtIndex (uint32_t idx);
+
+ //------------------------------------------------------------------
+ /// Default Constructor
+ //------------------------------------------------------------------
+ Platform (bool is_host_platform);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be
+ /// inherited from by the plug-in instance.
+ //------------------------------------------------------------------
+ virtual
+ ~Platform();
+
+ //------------------------------------------------------------------
+ /// Find a platform plugin for a given process.
+ ///
+ /// Scans the installed Platform plug-ins and tries to find
+ /// an instance that can be used for \a process
+ ///
+ /// @param[in] process
+ /// The process for which to try and locate a platform
+ /// plug-in instance.
+ ///
+ /// @param[in] plugin_name
+ /// An optional name of a specific platform plug-in that
+ /// should be used. If NULL, pick the best plug-in.
+ //------------------------------------------------------------------
+ static Platform*
+ FindPlugin (Process *process, const ConstString &plugin_name);
+
+ //------------------------------------------------------------------
+ /// Set the target's executable based off of the existing
+ /// architecture information in \a target given a path to an
+ /// executable \a exe_file.
+ ///
+ /// Each platform knows the architectures that it supports and can
+ /// select the correct architecture slice within \a exe_file by
+ /// inspecting the architecture in \a target. If the target had an
+ /// architecture specified, then in can try and obey that request
+ /// and optionally fail if the architecture doesn't match up.
+ /// If no architecture is specified, the platform should select the
+ /// default architecture from \a exe_file. Any application bundles
+ /// or executable wrappers can also be inspected for the actual
+ /// application binary within the bundle that should be used.
+ ///
+ /// @return
+ /// Returns \b true if this Platform plug-in was able to find
+ /// a suitable executable, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual Error
+ ResolveExecutable (const FileSpec &exe_file,
+ const ArchSpec &arch,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr);
+
+
+ //------------------------------------------------------------------
+ /// Find a symbol file given a symbol file module specification.
+ ///
+ /// Each platform might have tricks to find symbol files for an
+ /// executable given information in a symbol file ModuleSpec. Some
+ /// platforms might also support symbol files that are bundles and
+ /// know how to extract the right symbol file given a bundle.
+ ///
+ /// @param[in] target
+ /// The target in which we are trying to resolve the symbol file.
+ /// The target has a list of modules that we might be able to
+ /// use in order to help find the right symbol file. If the
+ /// "m_file" or "m_platform_file" entries in the \a sym_spec
+ /// are filled in, then we might be able to locate a module in
+ /// the target, extract its UUID and locate a symbol file.
+ /// If just the "m_uuid" is specified, then we might be able
+ /// to find the module in the target that matches that UUID
+ /// and pair the symbol file along with it. If just "m_symbol_file"
+ /// is specified, we can use a variety of tricks to locate the
+ /// symbols in an SDK, PDK, or other development kit location.
+ ///
+ /// @param[in] sym_spec
+ /// A module spec that describes some information about the
+ /// symbol file we are trying to resolve. The ModuleSpec might
+ /// contain the following:
+ /// m_file - A full or partial path to an executable from the
+ /// target (might be empty).
+ /// m_platform_file - Another executable hint that contains
+ /// the path to the file as known on the
+ /// local/remote platform.
+ /// m_symbol_file - A full or partial path to a symbol file
+ /// or symbol bundle that should be used when
+ /// trying to resolve the symbol file.
+ /// m_arch - The architecture we are looking for when resolving
+ /// the symbol file.
+ /// m_uuid - The UUID of the executable and symbol file. This
+ /// can often be used to match up an exectuable with
+ /// a symbol file, or resolve an symbol file in a
+ /// symbol file bundle.
+ ///
+ /// @param[out] sym_file
+ /// The resolved symbol file spec if the returned error
+ /// indicates succes.
+ ///
+ /// @return
+ /// Returns an error that describes success or failure.
+ //------------------------------------------------------------------
+ virtual Error
+ ResolveSymbolFile (Target &target,
+ const ModuleSpec &sym_spec,
+ FileSpec &sym_file);
+
+ //------------------------------------------------------------------
+ /// Resolves the FileSpec to a (possibly) remote path. Remote
+ /// platforms must override this to resolve to a path on the remote
+ /// side.
+ //------------------------------------------------------------------
+ virtual bool
+ ResolveRemotePath (const FileSpec &platform_path,
+ FileSpec &resolved_platform_path);
+
+ bool
+ GetOSVersion (uint32_t &major,
+ uint32_t &minor,
+ uint32_t &update);
+
+ bool
+ SetOSVersion (uint32_t major,
+ uint32_t minor,
+ uint32_t update);
+
+ bool
+ GetOSBuildString (std::string &s);
+
+ bool
+ GetOSKernelDescription (std::string &s);
+
+ // Returns the the hostname if we are connected, else the short plugin
+ // name.
+ ConstString
+ GetName ();
+
+ virtual const char *
+ GetHostname ();
+
+ virtual const char *
+ GetDescription () = 0;
+
+ //------------------------------------------------------------------
+ /// Report the current status for this platform.
+ ///
+ /// The returned string usually involves returning the OS version
+ /// (if available), and any SDK directory that might be being used
+ /// for local file caching, and if connected a quick blurb about
+ /// what this platform is connected to.
+ //------------------------------------------------------------------
+ virtual void
+ GetStatus (Stream &strm);
+
+ //------------------------------------------------------------------
+ // Subclasses must be able to fetch the current OS version
+ //
+ // Remote classes must be connected for this to succeed. Local
+ // subclasses don't need to override this function as it will just
+ // call the Host::GetOSVersion().
+ //------------------------------------------------------------------
+ virtual bool
+ GetRemoteOSVersion ()
+ {
+ return false;
+ }
+
+ virtual bool
+ GetRemoteOSBuildString (std::string &s)
+ {
+ s.clear();
+ return false;
+ }
+
+ virtual bool
+ GetRemoteOSKernelDescription (std::string &s)
+ {
+ s.clear();
+ return false;
+ }
+
+ // Remote Platform subclasses need to override this function
+ virtual ArchSpec
+ GetRemoteSystemArchitecture ()
+ {
+ return ArchSpec(); // Return an invalid architecture
+ }
+
+ virtual const char *
+ GetUserName (uint32_t uid);
+
+ virtual const char *
+ GetGroupName (uint32_t gid);
+
+ //------------------------------------------------------------------
+ /// Locate a file for a platform.
+ ///
+ /// The default implementation of this function will return the same
+ /// file patch in \a local_file as was in \a platform_file.
+ ///
+ /// @param[in] platform_file
+ /// The platform file path to locate and cache locally.
+ ///
+ /// @param[in] uuid_ptr
+ /// If we know the exact UUID of the file we are looking for, it
+ /// can be specified. If it is not specified, we might now know
+ /// the exact file. The UUID is usually some sort of MD5 checksum
+ /// for the file and is sometimes known by dynamic linkers/loaders.
+ /// If the UUID is known, it is best to supply it to platform
+ /// file queries to ensure we are finding the correct file, not
+ /// just a file at the correct path.
+ ///
+ /// @param[out] local_file
+ /// A locally cached version of the platform file. For platforms
+ /// that describe the current host computer, this will just be
+ /// the same file. For remote platforms, this file might come from
+ /// and SDK directory, or might need to be sync'ed over to the
+ /// current machine for efficient debugging access.
+ ///
+ /// @return
+ /// An error object.
+ //------------------------------------------------------------------
+ virtual Error
+ GetFile (const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file);
+
+ //----------------------------------------------------------------------
+ // Locate the scripting resource given a module specification.
+ //
+ // Locating the file should happen only on the local computer or using
+ // the current computers global settings.
+ //----------------------------------------------------------------------
+ virtual FileSpecList
+ LocateExecutableScriptingResources (Target *target,
+ Module &module);
+
+ virtual Error
+ GetSharedModule (const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr);
+
+ virtual Error
+ ConnectRemote (Args& args);
+
+ virtual Error
+ DisconnectRemote ();
+
+ //------------------------------------------------------------------
+ /// Get the platform's supported architectures in the order in which
+ /// they should be searched.
+ ///
+ /// @param[in] idx
+ /// A zero based architecture index
+ ///
+ /// @param[out] arch
+ /// A copy of the archgitecture at index if the return value is
+ /// \b true.
+ ///
+ /// @return
+ /// \b true if \a arch was filled in and is valid, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) = 0;
+
+ virtual size_t
+ GetSoftwareBreakpointTrapOpcode (Target &target,
+ BreakpointSite *bp_site) = 0;
+
+ //------------------------------------------------------------------
+ /// Launch a new process on a platform, not necessarily for
+ /// debugging, it could be just for running the process.
+ //------------------------------------------------------------------
+ virtual Error
+ LaunchProcess (ProcessLaunchInfo &launch_info);
+
+ //------------------------------------------------------------------
+ /// Lets a platform answer if it is compatible with a given
+ /// architecture and the target triple contained within.
+ //------------------------------------------------------------------
+ virtual bool
+ IsCompatibleArchitecture (const ArchSpec &arch,
+ bool exact_arch_match,
+ ArchSpec *compatible_arch_ptr);
+
+ //------------------------------------------------------------------
+ /// Not all platforms will support debugging a process by spawning
+ /// somehow halted for a debugger (specified using the
+ /// "eLaunchFlagDebug" launch flag) and then attaching. If your
+ /// platform doesn't support this, override this function and return
+ /// false.
+ //------------------------------------------------------------------
+ virtual bool
+ CanDebugProcess ()
+ {
+ return true;
+ }
+
+ //------------------------------------------------------------------
+ /// Subclasses should NOT need to implement this function as it uses
+ /// the Platform::LaunchProcess() followed by Platform::Attach ()
+ //------------------------------------------------------------------
+ lldb::ProcessSP
+ DebugProcess (ProcessLaunchInfo &launch_info,
+ Debugger &debugger,
+ Target *target, // Can be NULL, if NULL create a new target, else use existing one
+ Listener &listener,
+ Error &error);
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process using a process ID.
+ ///
+ /// Each platform subclass needs to implement this function and
+ /// attempt to attach to the process with the process ID of \a pid.
+ /// The platform subclass should return an appropriate ProcessSP
+ /// subclass that is attached to the process, or an empty shared
+ /// pointer with an appriopriate error.
+ ///
+ /// @param[in] pid
+ /// The process ID that we should attempt to attach to.
+ ///
+ /// @return
+ /// An appropriate ProcessSP containing a valid shared pointer
+ /// to the default Process subclass for the platform that is
+ /// attached to the process, or an empty shared pointer with an
+ /// appriopriate error fill into the \a error object.
+ //------------------------------------------------------------------
+ virtual lldb::ProcessSP
+ Attach (ProcessAttachInfo &attach_info,
+ Debugger &debugger,
+ Target *target, // Can be NULL, if NULL create a new target, else use existing one
+ Listener &listener,
+ Error &error) = 0;
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process by process name.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses. It will first call
+ /// Process::WillAttach (const char *) and if that returns \b
+ /// true, Process::DoAttach (const char *) will be called to
+ /// actually do the attach. If DoAttach returns \b true, then
+ /// Process::DidAttach() will be called.
+ ///
+ /// @param[in] process_name
+ /// A process name to match against the current process list.
+ ///
+ /// @return
+ /// Returns \a pid if attaching was successful, or
+ /// LLDB_INVALID_PROCESS_ID if attaching fails.
+ //------------------------------------------------------------------
+// virtual lldb::ProcessSP
+// Attach (const char *process_name,
+// bool wait_for_launch,
+// Error &error) = 0;
+
+ //------------------------------------------------------------------
+ // The base class Platform will take care of the host platform.
+ // Subclasses will need to fill in the remote case.
+ //------------------------------------------------------------------
+ virtual uint32_t
+ FindProcesses (const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &proc_infos);
+
+ virtual bool
+ GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
+
+ //------------------------------------------------------------------
+ // Set a breakpoint on all functions that can end up creating a thread
+ // for this platform. This is needed when running expressions and
+ // also for process control.
+ //------------------------------------------------------------------
+ virtual lldb::BreakpointSP
+ SetThreadCreationBreakpoint (Target &target);
+
+
+ const std::string &
+ GetRemoteURL () const
+ {
+ return m_remote_url;
+ }
+
+ bool
+ IsHost () const
+ {
+ return m_is_host; // Is this the default host platform?
+ }
+
+ bool
+ IsRemote () const
+ {
+ return !m_is_host;
+ }
+
+ virtual bool
+ IsConnected () const
+ {
+ // Remote subclasses should override this function
+ return IsHost();
+ }
+
+ const ArchSpec &
+ GetSystemArchitecture();
+
+ void
+ SetSystemArchitecture (const ArchSpec &arch)
+ {
+ m_system_arch = arch;
+ if (IsHost())
+ m_os_version_set_while_connected = m_system_arch.IsValid();
+ }
+
+ // Used for column widths
+ size_t
+ GetMaxUserIDNameLength() const
+ {
+ return m_max_uid_name_len;
+ }
+ // Used for column widths
+ size_t
+ GetMaxGroupIDNameLength() const
+ {
+ return m_max_gid_name_len;
+ }
+
+ const ConstString &
+ GetSDKRootDirectory () const
+ {
+ return m_sdk_sysroot;
+ }
+
+ void
+ SetSDKRootDirectory (const ConstString &dir)
+ {
+ m_sdk_sysroot = dir;
+ }
+
+ const ConstString &
+ GetSDKBuild () const
+ {
+ return m_sdk_build;
+ }
+
+ void
+ SetSDKBuild (const ConstString &sdk_build)
+ {
+ m_sdk_build = sdk_build;
+ }
+
+ // There may be modules that we don't want to find by default for operations like "setting breakpoint by name".
+ // The platform will return "true" from this call if the passed in module happens to be one of these.
+
+ virtual bool
+ ModuleIsExcludedForNonModuleSpecificSearches (Target &target, const lldb::ModuleSP &module_sp)
+ {
+ return false;
+ }
+
+ virtual size_t
+ GetEnvironment (StringList &environment);
+
+ protected:
+ bool m_is_host;
+ // Set to true when we are able to actually set the OS version while
+ // being connected. For remote platforms, we might set the version ahead
+ // of time before we actually connect and this version might change when
+ // we actually connect to a remote platform. For the host platform this
+ // will be set to the once we call Host::GetOSVersion().
+ bool m_os_version_set_while_connected;
+ bool m_system_arch_set_while_connected;
+ ConstString m_sdk_sysroot; // the root location of where the SDK files are all located
+ ConstString m_sdk_build;
+ std::string m_remote_url;
+ std::string m_name;
+ uint32_t m_major_os_version;
+ uint32_t m_minor_os_version;
+ uint32_t m_update_os_version;
+ ArchSpec m_system_arch; // The architecture of the kernel or the remote platform
+ typedef std::map<uint32_t, ConstString> IDToNameMap;
+ Mutex m_uid_map_mutex;
+ Mutex m_gid_map_mutex;
+ IDToNameMap m_uid_map;
+ IDToNameMap m_gid_map;
+ size_t m_max_uid_name_len;
+ size_t m_max_gid_name_len;
+
+ const char *
+ GetCachedUserName (uint32_t uid)
+ {
+ Mutex::Locker locker (m_uid_map_mutex);
+ IDToNameMap::iterator pos = m_uid_map.find (uid);
+ if (pos != m_uid_map.end())
+ {
+ // return the empty string if our string is NULL
+ // so we can tell when things were in the negative
+ // cached (didn't find a valid user name, don't keep
+ // trying)
+ return pos->second.AsCString("");
+ }
+ return NULL;
+ }
+
+ const char *
+ SetCachedUserName (uint32_t uid, const char *name, size_t name_len)
+ {
+ Mutex::Locker locker (m_uid_map_mutex);
+ ConstString const_name (name);
+ m_uid_map[uid] = const_name;
+ if (m_max_uid_name_len < name_len)
+ m_max_uid_name_len = name_len;
+ // Const strings lives forever in our const string pool, so we can return the const char *
+ return const_name.GetCString();
+ }
+
+ void
+ SetUserNameNotFound (uint32_t uid)
+ {
+ Mutex::Locker locker (m_uid_map_mutex);
+ m_uid_map[uid] = ConstString();
+ }
+
+
+ void
+ ClearCachedUserNames ()
+ {
+ Mutex::Locker locker (m_uid_map_mutex);
+ m_uid_map.clear();
+ }
+
+ const char *
+ GetCachedGroupName (uint32_t gid)
+ {
+ Mutex::Locker locker (m_gid_map_mutex);
+ IDToNameMap::iterator pos = m_gid_map.find (gid);
+ if (pos != m_gid_map.end())
+ {
+ // return the empty string if our string is NULL
+ // so we can tell when things were in the negative
+ // cached (didn't find a valid group name, don't keep
+ // trying)
+ return pos->second.AsCString("");
+ }
+ return NULL;
+ }
+
+ const char *
+ SetCachedGroupName (uint32_t gid, const char *name, size_t name_len)
+ {
+ Mutex::Locker locker (m_gid_map_mutex);
+ ConstString const_name (name);
+ m_gid_map[gid] = const_name;
+ if (m_max_gid_name_len < name_len)
+ m_max_gid_name_len = name_len;
+ // Const strings lives forever in our const string pool, so we can return the const char *
+ return const_name.GetCString();
+ }
+
+ void
+ SetGroupNameNotFound (uint32_t gid)
+ {
+ Mutex::Locker locker (m_gid_map_mutex);
+ m_gid_map[gid] = ConstString();
+ }
+
+ void
+ ClearCachedGroupNames ()
+ {
+ Mutex::Locker locker (m_gid_map_mutex);
+ m_gid_map.clear();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN (Platform);
+ };
+
+
+ class PlatformList
+ {
+ public:
+ PlatformList() :
+ m_mutex (Mutex::eMutexTypeRecursive),
+ m_platforms (),
+ m_selected_platform_sp()
+ {
+ }
+
+ ~PlatformList()
+ {
+ }
+
+ void
+ Append (const lldb::PlatformSP &platform_sp, bool set_selected)
+ {
+ Mutex::Locker locker (m_mutex);
+ m_platforms.push_back (platform_sp);
+ if (set_selected)
+ m_selected_platform_sp = m_platforms.back();
+ }
+
+ size_t
+ GetSize()
+ {
+ Mutex::Locker locker (m_mutex);
+ return m_platforms.size();
+ }
+
+ lldb::PlatformSP
+ GetAtIndex (uint32_t idx)
+ {
+ lldb::PlatformSP platform_sp;
+ {
+ Mutex::Locker locker (m_mutex);
+ if (idx < m_platforms.size())
+ platform_sp = m_platforms[idx];
+ }
+ return platform_sp;
+ }
+
+ //------------------------------------------------------------------
+ /// Select the active platform.
+ ///
+ /// In order to debug remotely, other platform's can be remotely
+ /// connected to and set as the selected platform for any subsequent
+ /// debugging. This allows connection to remote targets and allows
+ /// the ability to discover process info, launch and attach to remote
+ /// processes.
+ //------------------------------------------------------------------
+ lldb::PlatformSP
+ GetSelectedPlatform ()
+ {
+ Mutex::Locker locker (m_mutex);
+ if (!m_selected_platform_sp && !m_platforms.empty())
+ m_selected_platform_sp = m_platforms.front();
+
+ return m_selected_platform_sp;
+ }
+
+ void
+ SetSelectedPlatform (const lldb::PlatformSP &platform_sp)
+ {
+ if (platform_sp)
+ {
+ Mutex::Locker locker (m_mutex);
+ const size_t num_platforms = m_platforms.size();
+ for (size_t idx=0; idx<num_platforms; ++idx)
+ {
+ if (m_platforms[idx].get() == platform_sp.get())
+ {
+ m_selected_platform_sp = m_platforms[idx];
+ return;
+ }
+ }
+ m_platforms.push_back (platform_sp);
+ m_selected_platform_sp = m_platforms.back();
+ }
+ }
+
+ protected:
+ typedef std::vector<lldb::PlatformSP> collection;
+ mutable Mutex m_mutex;
+ collection m_platforms;
+ lldb::PlatformSP m_selected_platform_sp;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN (PlatformList);
+ };
+} // namespace lldb_private
+
+#endif // liblldb_Platform_h_
diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h
new file mode 100644
index 000000000000..ef89a1eb1418
--- /dev/null
+++ b/include/lldb/Target/Process.h
@@ -0,0 +1,3786 @@
+//===-- Process.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Process_h_
+#define liblldb_Process_h_
+
+// C Includes
+#include <limits.h>
+#include <spawn.h>
+
+// C++ Includes
+#include <list>
+#include <iosfwd>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Communication.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Event.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Core/ThreadSafeValue.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Breakpoint/BreakpointSiteList.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
+#include "lldb/Expression/IRDynamicChecks.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/ProcessRunLock.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/Memory.h"
+#include "lldb/Target/ThreadList.h"
+#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/PseudoTerminal.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// ProcessProperties
+//----------------------------------------------------------------------
+class ProcessProperties : public Properties
+{
+public:
+ ProcessProperties(bool is_global);
+
+ virtual
+ ~ProcessProperties();
+
+ bool
+ GetDisableMemoryCache() const;
+
+ Args
+ GetExtraStartupCommands () const;
+
+ void
+ SetExtraStartupCommands (const Args &args);
+
+ FileSpec
+ GetPythonOSPluginPath () const;
+
+ void
+ SetPythonOSPluginPath (const FileSpec &file);
+
+ bool
+ GetIgnoreBreakpointsInExpressions () const;
+
+ void
+ SetIgnoreBreakpointsInExpressions (bool ignore);
+
+ bool
+ GetUnwindOnErrorInExpressions () const;
+
+ void
+ SetUnwindOnErrorInExpressions (bool ignore);
+
+ bool
+ GetStopOnSharedLibraryEvents () const;
+
+ void
+ SetStopOnSharedLibraryEvents (bool stop);
+
+ bool
+ GetDetachKeepsStopped () const;
+
+ void
+ SetDetachKeepsStopped (bool keep_stopped);
+};
+
+typedef std::shared_ptr<ProcessProperties> ProcessPropertiesSP;
+
+//----------------------------------------------------------------------
+// ProcessInfo
+//
+// A base class for information for a process. This can be used to fill
+// out information for a process prior to launching it, or it can be
+// used for an instance of a process and can be filled in with the
+// existing values for that process.
+//----------------------------------------------------------------------
+class ProcessInfo
+{
+public:
+ ProcessInfo () :
+ m_executable (),
+ m_arguments (),
+ m_environment (),
+ m_uid (UINT32_MAX),
+ m_gid (UINT32_MAX),
+ m_arch(),
+ m_pid (LLDB_INVALID_PROCESS_ID)
+ {
+ }
+
+ ProcessInfo (const char *name,
+ const ArchSpec &arch,
+ lldb::pid_t pid) :
+ m_executable (name, false),
+ m_arguments (),
+ m_environment(),
+ m_uid (UINT32_MAX),
+ m_gid (UINT32_MAX),
+ m_arch (arch),
+ m_pid (pid)
+ {
+ }
+
+ void
+ Clear ()
+ {
+ m_executable.Clear();
+ m_arguments.Clear();
+ m_environment.Clear();
+ m_uid = UINT32_MAX;
+ m_gid = UINT32_MAX;
+ m_arch.Clear();
+ m_pid = LLDB_INVALID_PROCESS_ID;
+ }
+
+ const char *
+ GetName() const
+ {
+ return m_executable.GetFilename().GetCString();
+ }
+
+ size_t
+ GetNameLength() const
+ {
+ return m_executable.GetFilename().GetLength();
+ }
+
+ FileSpec &
+ GetExecutableFile ()
+ {
+ return m_executable;
+ }
+
+ void
+ SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg)
+ {
+ if (exe_file)
+ {
+ m_executable = exe_file;
+ if (add_exe_file_as_first_arg)
+ {
+ char filename[PATH_MAX];
+ if (exe_file.GetPath(filename, sizeof(filename)))
+ m_arguments.InsertArgumentAtIndex (0, filename);
+ }
+ }
+ else
+ {
+ m_executable.Clear();
+ }
+ }
+
+ const FileSpec &
+ GetExecutableFile () const
+ {
+ return m_executable;
+ }
+
+ uint32_t
+ GetUserID() const
+ {
+ return m_uid;
+ }
+
+ uint32_t
+ GetGroupID() const
+ {
+ return m_gid;
+ }
+
+ bool
+ UserIDIsValid () const
+ {
+ return m_uid != UINT32_MAX;
+ }
+
+ bool
+ GroupIDIsValid () const
+ {
+ return m_gid != UINT32_MAX;
+ }
+
+ void
+ SetUserID (uint32_t uid)
+ {
+ m_uid = uid;
+ }
+
+ void
+ SetGroupID (uint32_t gid)
+ {
+ m_gid = gid;
+ }
+
+ ArchSpec &
+ GetArchitecture ()
+ {
+ return m_arch;
+ }
+
+ const ArchSpec &
+ GetArchitecture () const
+ {
+ return m_arch;
+ }
+
+ lldb::pid_t
+ GetProcessID () const
+ {
+ return m_pid;
+ }
+
+ void
+ SetProcessID (lldb::pid_t pid)
+ {
+ m_pid = pid;
+ }
+
+ bool
+ ProcessIDIsValid() const
+ {
+ return m_pid != LLDB_INVALID_PROCESS_ID;
+ }
+
+ void
+ Dump (Stream &s, Platform *platform) const;
+
+ Args &
+ GetArguments ()
+ {
+ return m_arguments;
+ }
+
+ const Args &
+ GetArguments () const
+ {
+ return m_arguments;
+ }
+
+ const char *
+ GetArg0 () const
+ {
+ if (m_arg0.empty())
+ return NULL;
+ return m_arg0.c_str();
+ }
+
+ void
+ SetArg0 (const char *arg)
+ {
+ if (arg && arg[0])
+ m_arg0 = arg;
+ else
+ m_arg0.clear();
+ }
+
+ void
+ SetArguments (const Args& args, bool first_arg_is_executable);
+
+ void
+ SetArguments (char const **argv, bool first_arg_is_executable);
+
+ Args &
+ GetEnvironmentEntries ()
+ {
+ return m_environment;
+ }
+
+ const Args &
+ GetEnvironmentEntries () const
+ {
+ return m_environment;
+ }
+
+protected:
+ FileSpec m_executable;
+ std::string m_arg0; // argv[0] if supported. If empty, then use m_executable.
+ // Not all process plug-ins support specifying an argv[0]
+ // that differs from the resolved platform executable
+ // (which is in m_executable)
+ Args m_arguments; // All program arguments except argv[0]
+ Args m_environment;
+ uint32_t m_uid;
+ uint32_t m_gid;
+ ArchSpec m_arch;
+ lldb::pid_t m_pid;
+};
+
+//----------------------------------------------------------------------
+// ProcessInstanceInfo
+//
+// Describes an existing process and any discoverable information that
+// pertains to that process.
+//----------------------------------------------------------------------
+class ProcessInstanceInfo : public ProcessInfo
+{
+public:
+ ProcessInstanceInfo () :
+ ProcessInfo (),
+ m_euid (UINT32_MAX),
+ m_egid (UINT32_MAX),
+ m_parent_pid (LLDB_INVALID_PROCESS_ID)
+ {
+ }
+
+ ProcessInstanceInfo (const char *name,
+ const ArchSpec &arch,
+ lldb::pid_t pid) :
+ ProcessInfo (name, arch, pid),
+ m_euid (UINT32_MAX),
+ m_egid (UINT32_MAX),
+ m_parent_pid (LLDB_INVALID_PROCESS_ID)
+ {
+ }
+
+ void
+ Clear ()
+ {
+ ProcessInfo::Clear();
+ m_euid = UINT32_MAX;
+ m_egid = UINT32_MAX;
+ m_parent_pid = LLDB_INVALID_PROCESS_ID;
+ }
+
+ uint32_t
+ GetEffectiveUserID() const
+ {
+ return m_euid;
+ }
+
+ uint32_t
+ GetEffectiveGroupID() const
+ {
+ return m_egid;
+ }
+
+ bool
+ EffectiveUserIDIsValid () const
+ {
+ return m_euid != UINT32_MAX;
+ }
+
+ bool
+ EffectiveGroupIDIsValid () const
+ {
+ return m_egid != UINT32_MAX;
+ }
+
+ void
+ SetEffectiveUserID (uint32_t uid)
+ {
+ m_euid = uid;
+ }
+
+ void
+ SetEffectiveGroupID (uint32_t gid)
+ {
+ m_egid = gid;
+ }
+
+ lldb::pid_t
+ GetParentProcessID () const
+ {
+ return m_parent_pid;
+ }
+
+ void
+ SetParentProcessID (lldb::pid_t pid)
+ {
+ m_parent_pid = pid;
+ }
+
+ bool
+ ParentProcessIDIsValid() const
+ {
+ return m_parent_pid != LLDB_INVALID_PROCESS_ID;
+ }
+
+ void
+ Dump (Stream &s, Platform *platform) const;
+
+ static void
+ DumpTableHeader (Stream &s, Platform *platform, bool show_args, bool verbose);
+
+ void
+ DumpAsTableRow (Stream &s, Platform *platform, bool show_args, bool verbose) const;
+
+protected:
+ uint32_t m_euid;
+ uint32_t m_egid;
+ lldb::pid_t m_parent_pid;
+};
+
+
+//----------------------------------------------------------------------
+// ProcessLaunchInfo
+//
+// Describes any information that is required to launch a process.
+//----------------------------------------------------------------------
+
+class ProcessLaunchInfo : public ProcessInfo
+{
+public:
+
+ class FileAction
+ {
+ public:
+ enum Action
+ {
+ eFileActionNone,
+ eFileActionClose,
+ eFileActionDuplicate,
+ eFileActionOpen
+ };
+
+
+ FileAction () :
+ m_action (eFileActionNone),
+ m_fd (-1),
+ m_arg (-1),
+ m_path ()
+ {
+ }
+
+ void
+ Clear()
+ {
+ m_action = eFileActionNone;
+ m_fd = -1;
+ m_arg = -1;
+ m_path.clear();
+ }
+
+ bool
+ Close (int fd);
+
+ bool
+ Duplicate (int fd, int dup_fd);
+
+ bool
+ Open (int fd, const char *path, bool read, bool write);
+
+ static bool
+ AddPosixSpawnFileAction (posix_spawn_file_actions_t *file_actions,
+ const FileAction *info,
+ Log *log,
+ Error& error);
+
+ int
+ GetFD () const
+ {
+ return m_fd;
+ }
+
+ Action
+ GetAction () const
+ {
+ return m_action;
+ }
+
+ int
+ GetActionArgument () const
+ {
+ return m_arg;
+ }
+
+ const char *
+ GetPath () const
+ {
+ if (m_path.empty())
+ return NULL;
+ return m_path.c_str();
+ }
+
+ protected:
+ Action m_action; // The action for this file
+ int m_fd; // An existing file descriptor
+ int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate
+ std::string m_path; // A file path to use for opening after fork or posix_spawn
+ };
+
+ ProcessLaunchInfo () :
+ ProcessInfo(),
+ m_working_dir (),
+ m_plugin_name (),
+ m_shell (),
+ m_flags (0),
+ m_file_actions (),
+ m_pty (),
+ m_resume_count (0),
+ m_monitor_callback (NULL),
+ m_monitor_callback_baton (NULL),
+ m_monitor_signals (false)
+ {
+ }
+
+ ProcessLaunchInfo (const char *stdin_path,
+ const char *stdout_path,
+ const char *stderr_path,
+ const char *working_directory,
+ uint32_t launch_flags) :
+ ProcessInfo(),
+ m_working_dir (),
+ m_plugin_name (),
+ m_shell (),
+ m_flags (launch_flags),
+ m_file_actions (),
+ m_pty (),
+ m_resume_count (0),
+ m_monitor_callback (NULL),
+ m_monitor_callback_baton (NULL),
+ m_monitor_signals (false)
+ {
+ if (stdin_path)
+ {
+ ProcessLaunchInfo::FileAction file_action;
+ const bool read = true;
+ const bool write = false;
+ if (file_action.Open(STDIN_FILENO, stdin_path, read, write))
+ AppendFileAction (file_action);
+ }
+ if (stdout_path)
+ {
+ ProcessLaunchInfo::FileAction file_action;
+ const bool read = false;
+ const bool write = true;
+ if (file_action.Open(STDOUT_FILENO, stdout_path, read, write))
+ AppendFileAction (file_action);
+ }
+ if (stderr_path)
+ {
+ ProcessLaunchInfo::FileAction file_action;
+ const bool read = false;
+ const bool write = true;
+ if (file_action.Open(STDERR_FILENO, stderr_path, read, write))
+ AppendFileAction (file_action);
+ }
+ if (working_directory)
+ SetWorkingDirectory(working_directory);
+ }
+
+ void
+ AppendFileAction (const FileAction &info)
+ {
+ m_file_actions.push_back(info);
+ }
+
+ bool
+ AppendCloseFileAction (int fd)
+ {
+ FileAction file_action;
+ if (file_action.Close (fd))
+ {
+ AppendFileAction (file_action);
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ AppendDuplicateFileAction (int fd, int dup_fd)
+ {
+ FileAction file_action;
+ if (file_action.Duplicate (fd, dup_fd))
+ {
+ AppendFileAction (file_action);
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ AppendOpenFileAction (int fd, const char *path, bool read, bool write)
+ {
+ FileAction file_action;
+ if (file_action.Open (fd, path, read, write))
+ {
+ AppendFileAction (file_action);
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ AppendSuppressFileAction (int fd, bool read, bool write)
+ {
+ FileAction file_action;
+ if (file_action.Open (fd, "/dev/null", read, write))
+ {
+ AppendFileAction (file_action);
+ return true;
+ }
+ return false;
+ }
+
+ void
+ FinalizeFileActions (Target *target,
+ bool default_to_use_pty);
+
+ size_t
+ GetNumFileActions () const
+ {
+ return m_file_actions.size();
+ }
+
+ const FileAction *
+ GetFileActionAtIndex (size_t idx) const
+ {
+ if (idx < m_file_actions.size())
+ return &m_file_actions[idx];
+ return NULL;
+ }
+
+ const FileAction *
+ GetFileActionForFD (int fd) const
+ {
+ for (size_t idx=0, count=m_file_actions.size(); idx < count; ++idx)
+ {
+ if (m_file_actions[idx].GetFD () == fd)
+ return &m_file_actions[idx];
+ }
+ return NULL;
+ }
+
+ Flags &
+ GetFlags ()
+ {
+ return m_flags;
+ }
+
+ const Flags &
+ GetFlags () const
+ {
+ return m_flags;
+ }
+
+ const char *
+ GetWorkingDirectory () const
+ {
+ if (m_working_dir.empty())
+ return NULL;
+ return m_working_dir.c_str();
+ }
+
+ void
+ SetWorkingDirectory (const char *working_dir)
+ {
+ if (working_dir && working_dir[0])
+ m_working_dir.assign (working_dir);
+ else
+ m_working_dir.clear();
+ }
+
+ void
+ SwapWorkingDirectory (std::string &working_dir)
+ {
+ m_working_dir.swap (working_dir);
+ }
+
+
+ const char *
+ GetProcessPluginName () const
+ {
+ if (m_plugin_name.empty())
+ return NULL;
+ return m_plugin_name.c_str();
+ }
+
+ void
+ SetProcessPluginName (const char *plugin)
+ {
+ if (plugin && plugin[0])
+ m_plugin_name.assign (plugin);
+ else
+ m_plugin_name.clear();
+ }
+
+ const char *
+ GetShell () const
+ {
+ if (m_shell.empty())
+ return NULL;
+ return m_shell.c_str();
+ }
+
+ void
+ SetShell (const char * path)
+ {
+ if (path && path[0])
+ {
+ m_shell.assign (path);
+ m_flags.Set (lldb::eLaunchFlagLaunchInShell);
+ }
+ else
+ {
+ m_shell.clear();
+ m_flags.Clear (lldb::eLaunchFlagLaunchInShell);
+ }
+ }
+
+ uint32_t
+ GetResumeCount () const
+ {
+ return m_resume_count;
+ }
+
+ void
+ SetResumeCount (uint32_t c)
+ {
+ m_resume_count = c;
+ }
+
+ bool
+ GetLaunchInSeparateProcessGroup ()
+ {
+ return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
+ }
+
+ void
+ SetLaunchInSeparateProcessGroup (bool separate)
+ {
+ if (separate)
+ m_flags.Set(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
+ else
+ m_flags.Clear (lldb::eLaunchFlagLaunchInSeparateProcessGroup);
+
+ }
+
+ void
+ Clear ()
+ {
+ ProcessInfo::Clear();
+ m_working_dir.clear();
+ m_plugin_name.clear();
+ m_shell.clear();
+ m_flags.Clear();
+ m_file_actions.clear();
+ m_resume_count = 0;
+ }
+
+ bool
+ ConvertArgumentsForLaunchingInShell (Error &error,
+ bool localhost,
+ bool will_debug,
+ bool first_arg_is_full_shell_command);
+
+ void
+ SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback,
+ void *baton,
+ bool monitor_signals)
+ {
+ m_monitor_callback = callback;
+ m_monitor_callback_baton = baton;
+ m_monitor_signals = monitor_signals;
+ }
+
+ bool
+ MonitorProcess () const
+ {
+ if (m_monitor_callback && ProcessIDIsValid())
+ {
+ Host::StartMonitoringChildProcess (m_monitor_callback,
+ m_monitor_callback_baton,
+ GetProcessID(),
+ m_monitor_signals);
+ return true;
+ }
+ return false;
+ }
+
+ lldb_utility::PseudoTerminal &
+ GetPTY ()
+ {
+ return m_pty;
+ }
+
+protected:
+ std::string m_working_dir;
+ std::string m_plugin_name;
+ std::string m_shell;
+ Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags
+ std::vector<FileAction> m_file_actions; // File actions for any other files
+ lldb_utility::PseudoTerminal m_pty;
+ uint32_t m_resume_count; // How many times do we resume after launching
+ Host::MonitorChildProcessCallback m_monitor_callback;
+ void *m_monitor_callback_baton;
+ bool m_monitor_signals;
+
+};
+
+//----------------------------------------------------------------------
+// ProcessLaunchInfo
+//
+// Describes any information that is required to launch a process.
+//----------------------------------------------------------------------
+
+class ProcessAttachInfo : public ProcessInstanceInfo
+{
+public:
+ ProcessAttachInfo() :
+ ProcessInstanceInfo(),
+ m_plugin_name (),
+ m_resume_count (0),
+ m_wait_for_launch (false),
+ m_ignore_existing (true),
+ m_continue_once_attached (false)
+ {
+ }
+
+ ProcessAttachInfo (const ProcessLaunchInfo &launch_info) :
+ ProcessInstanceInfo(),
+ m_plugin_name (),
+ m_resume_count (0),
+ m_wait_for_launch (false),
+ m_ignore_existing (true),
+ m_continue_once_attached (false)
+ {
+ ProcessInfo::operator= (launch_info);
+ SetProcessPluginName (launch_info.GetProcessPluginName());
+ SetResumeCount (launch_info.GetResumeCount());
+ }
+
+ bool
+ GetWaitForLaunch () const
+ {
+ return m_wait_for_launch;
+ }
+
+ void
+ SetWaitForLaunch (bool b)
+ {
+ m_wait_for_launch = b;
+ }
+
+ bool
+ GetIgnoreExisting () const
+ {
+ return m_ignore_existing;
+ }
+
+ void
+ SetIgnoreExisting (bool b)
+ {
+ m_ignore_existing = b;
+ }
+
+ bool
+ GetContinueOnceAttached () const
+ {
+ return m_continue_once_attached;
+ }
+
+ void
+ SetContinueOnceAttached (bool b)
+ {
+ m_continue_once_attached = b;
+ }
+
+ uint32_t
+ GetResumeCount () const
+ {
+ return m_resume_count;
+ }
+
+ void
+ SetResumeCount (uint32_t c)
+ {
+ m_resume_count = c;
+ }
+
+ const char *
+ GetProcessPluginName () const
+ {
+ if (m_plugin_name.empty())
+ return NULL;
+ return m_plugin_name.c_str();
+ }
+
+ void
+ SetProcessPluginName (const char *plugin)
+ {
+ if (plugin && plugin[0])
+ m_plugin_name.assign (plugin);
+ else
+ m_plugin_name.clear();
+ }
+
+ void
+ Clear ()
+ {
+ ProcessInstanceInfo::Clear();
+ m_plugin_name.clear();
+ m_resume_count = 0;
+ m_wait_for_launch = false;
+ m_ignore_existing = true;
+ m_continue_once_attached = false;
+ }
+
+ bool
+ ProcessInfoSpecified () const
+ {
+ if (GetExecutableFile())
+ return true;
+ if (GetProcessID() != LLDB_INVALID_PROCESS_ID)
+ return true;
+ if (GetParentProcessID() != LLDB_INVALID_PROCESS_ID)
+ return true;
+ return false;
+ }
+protected:
+ std::string m_plugin_name;
+ uint32_t m_resume_count; // How many times do we resume after launching
+ bool m_wait_for_launch;
+ bool m_ignore_existing;
+ bool m_continue_once_attached; // Supports the use-case scenario of immediately continuing the process once attached.
+};
+
+class ProcessLaunchCommandOptions : public Options
+{
+public:
+
+ ProcessLaunchCommandOptions (CommandInterpreter &interpreter) :
+ Options(interpreter)
+ {
+ // Keep default values of all options in one place: OptionParsingStarting ()
+ OptionParsingStarting ();
+ }
+
+ ~ProcessLaunchCommandOptions ()
+ {
+ }
+
+ Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg);
+
+ void
+ OptionParsingStarting ()
+ {
+ launch_info.Clear();
+ }
+
+ 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.
+
+ ProcessLaunchInfo launch_info;
+};
+
+//----------------------------------------------------------------------
+// ProcessInstanceInfoMatch
+//
+// A class to help matching one ProcessInstanceInfo to another.
+//----------------------------------------------------------------------
+
+class ProcessInstanceInfoMatch
+{
+public:
+ ProcessInstanceInfoMatch () :
+ m_match_info (),
+ m_name_match_type (eNameMatchIgnore),
+ m_match_all_users (false)
+ {
+ }
+
+ ProcessInstanceInfoMatch (const char *process_name,
+ NameMatchType process_name_match_type) :
+ m_match_info (),
+ m_name_match_type (process_name_match_type),
+ m_match_all_users (false)
+ {
+ m_match_info.GetExecutableFile().SetFile(process_name, false);
+ }
+
+ ProcessInstanceInfo &
+ GetProcessInfo ()
+ {
+ return m_match_info;
+ }
+
+ const ProcessInstanceInfo &
+ GetProcessInfo () const
+ {
+ return m_match_info;
+ }
+
+ bool
+ GetMatchAllUsers () const
+ {
+ return m_match_all_users;
+ }
+
+ void
+ SetMatchAllUsers (bool b)
+ {
+ m_match_all_users = b;
+ }
+
+ NameMatchType
+ GetNameMatchType () const
+ {
+ return m_name_match_type;
+ }
+
+ void
+ SetNameMatchType (NameMatchType name_match_type)
+ {
+ m_name_match_type = name_match_type;
+ }
+
+ bool
+ NameMatches (const char *process_name) const;
+
+ bool
+ Matches (const ProcessInstanceInfo &proc_info) const;
+
+ bool
+ MatchAllProcesses () const;
+ void
+ Clear ();
+
+protected:
+ ProcessInstanceInfo m_match_info;
+ NameMatchType m_name_match_type;
+ bool m_match_all_users;
+};
+
+class ProcessInstanceInfoList
+{
+public:
+ ProcessInstanceInfoList () :
+ m_infos()
+ {
+ }
+
+ void
+ Clear()
+ {
+ m_infos.clear();
+ }
+
+ size_t
+ GetSize()
+ {
+ return m_infos.size();
+ }
+
+ void
+ Append (const ProcessInstanceInfo &info)
+ {
+ m_infos.push_back (info);
+ }
+
+ const char *
+ GetProcessNameAtIndex (size_t idx)
+ {
+ if (idx < m_infos.size())
+ return m_infos[idx].GetName();
+ return NULL;
+ }
+
+ size_t
+ GetProcessNameLengthAtIndex (size_t idx)
+ {
+ if (idx < m_infos.size())
+ return m_infos[idx].GetNameLength();
+ return 0;
+ }
+
+ lldb::pid_t
+ GetProcessIDAtIndex (size_t idx)
+ {
+ if (idx < m_infos.size())
+ return m_infos[idx].GetProcessID();
+ return 0;
+ }
+
+ bool
+ GetInfoAtIndex (size_t idx, ProcessInstanceInfo &info)
+ {
+ if (idx < m_infos.size())
+ {
+ info = m_infos[idx];
+ return true;
+ }
+ return false;
+ }
+
+ // You must ensure "idx" is valid before calling this function
+ const ProcessInstanceInfo &
+ GetProcessInfoAtIndex (size_t idx) const
+ {
+ assert (idx < m_infos.size());
+ return m_infos[idx];
+ }
+
+protected:
+ typedef std::vector<ProcessInstanceInfo> collection;
+ collection m_infos;
+};
+
+
+// This class tracks the Modification state of the process. Things that can currently modify
+// the program are running the program (which will up the StopID) and writing memory (which
+// will up the MemoryID.)
+// FIXME: Should we also include modification of register states?
+
+class ProcessModID
+{
+friend bool operator== (const ProcessModID &lhs, const ProcessModID &rhs);
+public:
+ ProcessModID () :
+ m_stop_id (0),
+ m_last_natural_stop_id(0),
+ m_resume_id (0),
+ m_memory_id (0),
+ m_last_user_expression_resume (0),
+ m_running_user_expression (false)
+ {}
+
+ ProcessModID (const ProcessModID &rhs) :
+ m_stop_id (rhs.m_stop_id),
+ m_memory_id (rhs.m_memory_id)
+ {}
+
+ const ProcessModID & operator= (const ProcessModID &rhs)
+ {
+ if (this != &rhs)
+ {
+ m_stop_id = rhs.m_stop_id;
+ m_memory_id = rhs.m_memory_id;
+ }
+ return *this;
+ }
+
+ ~ProcessModID () {}
+
+ void BumpStopID () {
+ m_stop_id++;
+ if (!IsLastResumeForUserExpression())
+ m_last_natural_stop_id++;
+ }
+
+ void BumpMemoryID () { m_memory_id++; }
+
+ void BumpResumeID () {
+ m_resume_id++;
+ if (m_running_user_expression > 0)
+ m_last_user_expression_resume = m_resume_id;
+ }
+
+ uint32_t GetStopID() const { return m_stop_id; }
+ uint32_t GetLastNaturalStopID() const { return m_last_natural_stop_id; }
+ uint32_t GetMemoryID () const { return m_memory_id; }
+ uint32_t GetResumeID () const { return m_resume_id; }
+ uint32_t GetLastUserExpressionResumeID () const { return m_last_user_expression_resume; }
+
+ bool MemoryIDEqual (const ProcessModID &compare) const
+ {
+ return m_memory_id == compare.m_memory_id;
+ }
+
+ bool StopIDEqual (const ProcessModID &compare) const
+ {
+ return m_stop_id == compare.m_stop_id;
+ }
+
+ void SetInvalid ()
+ {
+ m_stop_id = UINT32_MAX;
+ }
+
+ bool IsValid () const
+ {
+ return m_stop_id != UINT32_MAX;
+ }
+
+ bool
+ IsLastResumeForUserExpression () const
+ {
+ return m_resume_id == m_last_user_expression_resume;
+ }
+
+ void
+ SetRunningUserExpression (bool on)
+ {
+ // REMOVEME printf ("Setting running user expression %s at resume id %d - value: %d.\n", on ? "on" : "off", m_resume_id, m_running_user_expression);
+ if (on)
+ m_running_user_expression++;
+ else
+ m_running_user_expression--;
+ }
+
+private:
+ uint32_t m_stop_id;
+ uint32_t m_last_natural_stop_id;
+ uint32_t m_resume_id;
+ uint32_t m_memory_id;
+ uint32_t m_last_user_expression_resume;
+ uint32_t m_running_user_expression;
+};
+inline bool operator== (const ProcessModID &lhs, const ProcessModID &rhs)
+{
+ if (lhs.StopIDEqual (rhs)
+ && lhs.MemoryIDEqual (rhs))
+ return true;
+ else
+ return false;
+}
+
+inline bool operator!= (const ProcessModID &lhs, const ProcessModID &rhs)
+{
+ if (!lhs.StopIDEqual (rhs)
+ || !lhs.MemoryIDEqual (rhs))
+ return true;
+ else
+ return false;
+}
+
+class MemoryRegionInfo
+{
+public:
+ typedef Range<lldb::addr_t, lldb::addr_t> RangeType;
+
+ enum OptionalBool {
+ eDontKnow = -1,
+ eNo = 0,
+ eYes = 1
+ };
+
+ MemoryRegionInfo () :
+ m_range (),
+ m_read (eDontKnow),
+ m_write (eDontKnow),
+ m_execute (eDontKnow)
+ {
+ }
+
+ ~MemoryRegionInfo ()
+ {
+ }
+
+ RangeType &
+ GetRange()
+ {
+ return m_range;
+ }
+
+ void
+ Clear()
+ {
+ m_range.Clear();
+ m_read = m_write = m_execute = eDontKnow;
+ }
+
+ const RangeType &
+ GetRange() const
+ {
+ return m_range;
+ }
+
+ OptionalBool
+ GetReadable () const
+ {
+ return m_read;
+ }
+
+ OptionalBool
+ GetWritable () const
+ {
+ return m_write;
+ }
+
+ OptionalBool
+ GetExecutable () const
+ {
+ return m_execute;
+ }
+
+ void
+ SetReadable (OptionalBool val)
+ {
+ m_read = val;
+ }
+
+ void
+ SetWritable (OptionalBool val)
+ {
+ m_write = val;
+ }
+
+ void
+ SetExecutable (OptionalBool val)
+ {
+ m_execute = val;
+ }
+
+protected:
+ RangeType m_range;
+ OptionalBool m_read;
+ OptionalBool m_write;
+ OptionalBool m_execute;
+};
+
+//----------------------------------------------------------------------
+/// @class Process Process.h "lldb/Target/Process.h"
+/// @brief A plug-in interface definition class for debugging a process.
+//----------------------------------------------------------------------
+class Process :
+ public std::enable_shared_from_this<Process>,
+ public ProcessProperties,
+ public UserID,
+ public Broadcaster,
+ public ExecutionContextScope,
+ public PluginInterface
+{
+friend class ThreadList;
+friend class ClangFunction; // For WaitForStateChangeEventsPrivate
+friend class CommandObjectProcessLaunch;
+friend class ProcessEventData;
+friend class CommandObjectBreakpointCommand;
+friend class StopInfo;
+
+public:
+
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ enum
+ {
+ eBroadcastBitStateChanged = (1 << 0),
+ eBroadcastBitInterrupt = (1 << 1),
+ eBroadcastBitSTDOUT = (1 << 2),
+ eBroadcastBitSTDERR = (1 << 3),
+ eBroadcastBitProfileData = (1 << 4)
+ };
+
+ enum
+ {
+ eBroadcastInternalStateControlStop = (1<<0),
+ eBroadcastInternalStateControlPause = (1<<1),
+ eBroadcastInternalStateControlResume = (1<<2)
+ };
+
+ typedef Range<lldb::addr_t, lldb::addr_t> LoadRange;
+ // We use a read/write lock to allow on or more clients to
+ // access the process state while the process is stopped (reader).
+ // We lock the write lock to control access to the process
+ // while it is running (readers, or clients that want the process
+ // stopped can block waiting for the process to stop, or just
+ // try to lock it to see if they can immediately access the stopped
+ // process. If the try read lock fails, then the process is running.
+ typedef ProcessRunLock::ProcessRunLocker StopLocker;
+
+ // These two functions fill out the Broadcaster interface:
+
+ static ConstString &GetStaticBroadcasterClass ();
+
+ virtual ConstString &GetBroadcasterClass() const
+ {
+ return GetStaticBroadcasterClass();
+ }
+
+
+ //------------------------------------------------------------------
+ /// A notification structure that can be used by clients to listen
+ /// for changes in a process's lifetime.
+ ///
+ /// @see RegisterNotificationCallbacks (const Notifications&)
+ /// @see UnregisterNotificationCallbacks (const Notifications&)
+ //------------------------------------------------------------------
+#ifndef SWIG
+ typedef struct
+ {
+ void *baton;
+ void (*initialize)(void *baton, Process *process);
+ void (*process_state_changed) (void *baton, Process *process, lldb::StateType state);
+ } Notifications;
+
+ class ProcessEventData :
+ public EventData
+ {
+ friend class Process;
+
+ public:
+ ProcessEventData ();
+ ProcessEventData (const lldb::ProcessSP &process, lldb::StateType state);
+
+ virtual ~ProcessEventData();
+
+ static const ConstString &
+ GetFlavorString ();
+
+ virtual const ConstString &
+ GetFlavor () const;
+
+ const lldb::ProcessSP &
+ GetProcessSP() const
+ {
+ return m_process_sp;
+ }
+ lldb::StateType
+ GetState() const
+ {
+ return m_state;
+ }
+ bool
+ GetRestarted () const
+ {
+ return m_restarted;
+ }
+
+ size_t
+ GetNumRestartedReasons ()
+ {
+ return m_restarted_reasons.size();
+ }
+
+ const char *
+ GetRestartedReasonAtIndex(size_t idx)
+ {
+ if (idx > m_restarted_reasons.size())
+ return NULL;
+ else
+ return m_restarted_reasons[idx].c_str();
+ }
+
+ bool
+ GetInterrupted () const
+ {
+ return m_interrupted;
+ }
+
+ virtual void
+ Dump (Stream *s) const;
+
+ virtual void
+ DoOnRemoval (Event *event_ptr);
+
+ static const Process::ProcessEventData *
+ GetEventDataFromEvent (const Event *event_ptr);
+
+ static lldb::ProcessSP
+ GetProcessFromEvent (const Event *event_ptr);
+
+ static lldb::StateType
+ GetStateFromEvent (const Event *event_ptr);
+
+ static bool
+ GetRestartedFromEvent (const Event *event_ptr);
+
+ static size_t
+ GetNumRestartedReasons(const Event *event_ptr);
+
+ static const char *
+ GetRestartedReasonAtIndex(const Event *event_ptr, size_t idx);
+
+ static void
+ AddRestartedReason (Event *event_ptr, const char *reason);
+
+ static void
+ SetRestartedInEvent (Event *event_ptr, bool new_value);
+
+ static bool
+ GetInterruptedFromEvent (const Event *event_ptr);
+
+ static void
+ SetInterruptedInEvent (Event *event_ptr, bool new_value);
+
+ static bool
+ SetUpdateStateOnRemoval (Event *event_ptr);
+
+ private:
+
+ void
+ SetUpdateStateOnRemoval()
+ {
+ m_update_state++;
+ }
+ void
+ SetRestarted (bool new_value)
+ {
+ m_restarted = new_value;
+ }
+ void
+ SetInterrupted (bool new_value)
+ {
+ m_interrupted = new_value;
+ }
+ void
+ AddRestartedReason (const char *reason)
+ {
+ m_restarted_reasons.push_back(reason);
+ }
+
+ lldb::ProcessSP m_process_sp;
+ lldb::StateType m_state;
+ std::vector<std::string> m_restarted_reasons;
+ bool m_restarted; // For "eStateStopped" events, this is true if the target was automatically restarted.
+ int m_update_state;
+ bool m_interrupted;
+ DISALLOW_COPY_AND_ASSIGN (ProcessEventData);
+
+ };
+
+#endif
+
+ static void
+ SettingsInitialize ();
+
+ static void
+ SettingsTerminate ();
+
+ static const ProcessPropertiesSP &
+ GetGlobalProperties();
+
+ //------------------------------------------------------------------
+ /// Construct with a shared pointer to a target, and the Process listener.
+ //------------------------------------------------------------------
+ Process(Target &target, Listener &listener);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be
+ /// inherited from by the plug-in instance.
+ //------------------------------------------------------------------
+ virtual
+ ~Process();
+
+ //------------------------------------------------------------------
+ /// Find a Process plug-in that can debug \a module using the
+ /// currently selected architecture.
+ ///
+ /// Scans all loaded plug-in interfaces that implement versions of
+ /// the Process plug-in interface and returns the first instance
+ /// that can debug the file.
+ ///
+ /// @param[in] module_sp
+ /// The module shared pointer that this process will debug.
+ ///
+ /// @param[in] plugin_name
+ /// If NULL, select the best plug-in for the binary. If non-NULL
+ /// then look for a plugin whose PluginInfo's name matches
+ /// this string.
+ ///
+ /// @see Process::CanDebug ()
+ //------------------------------------------------------------------
+ static lldb::ProcessSP
+ FindPlugin (Target &target,
+ const char *plugin_name,
+ Listener &listener,
+ const FileSpec *crash_file_path);
+
+
+
+ //------------------------------------------------------------------
+ /// Static function that can be used with the \b host function
+ /// Host::StartMonitoringChildProcess ().
+ ///
+ /// This function can be used by lldb_private::Process subclasses
+ /// when they want to watch for a local process and have its exit
+ /// status automatically set when the host child process exits.
+ /// Subclasses should call Host::StartMonitoringChildProcess ()
+ /// with:
+ /// callback = Process::SetHostProcessExitStatus
+ /// callback_baton = NULL
+ /// pid = Process::GetID()
+ /// monitor_signals = false
+ //------------------------------------------------------------------
+ static bool
+ SetProcessExitStatus (void *callback_baton, // The callback baton which should be set to NULL
+ lldb::pid_t pid, // The process ID we want to monitor
+ bool exited,
+ int signo, // Zero for no signal
+ int status); // Exit value of process if signal is zero
+
+ lldb::ByteOrder
+ GetByteOrder () const;
+
+ uint32_t
+ GetAddressByteSize () const;
+
+ uint32_t
+ GetUniqueID() const
+ {
+ return m_process_unique_id;
+ }
+ //------------------------------------------------------------------
+ /// Check if a plug-in instance can debug the file in \a module.
+ ///
+ /// Each plug-in is given a chance to say whether it can debug
+ /// the file in \a module. If the Process plug-in instance can
+ /// debug a file on the current system, it should return \b true.
+ ///
+ /// @return
+ /// Returns \b true if this Process plug-in instance can
+ /// debug the executable, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ CanDebug (Target &target,
+ bool plugin_specified_by_name) = 0;
+
+
+ //------------------------------------------------------------------
+ /// This object is about to be destroyed, do any necessary cleanup.
+ ///
+ /// Subclasses that override this method should always call this
+ /// superclass method.
+ //------------------------------------------------------------------
+ virtual void
+ Finalize();
+
+
+ //------------------------------------------------------------------
+ /// Return whether this object is valid (i.e. has not been finalized.)
+ ///
+ /// @return
+ /// Returns \b true if this Process has not been finalized
+ /// and \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsValid() const
+ {
+ return !m_finalize_called;
+ }
+
+ //------------------------------------------------------------------
+ /// Return a multi-word command object that can be used to expose
+ /// plug-in specific commands.
+ ///
+ /// This object will be used to resolve plug-in commands and can be
+ /// triggered by a call to:
+ ///
+ /// (lldb) process commmand <args>
+ ///
+ /// @return
+ /// A CommandObject which can be one of the concrete subclasses
+ /// of CommandObject like CommandObjectRaw, CommandObjectParsed,
+ /// or CommandObjectMultiword.
+ //------------------------------------------------------------------
+ virtual CommandObject *
+ GetPluginCommandObject()
+ {
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Launch a new process.
+ ///
+ /// Launch a new process by spawning a new process using the
+ /// target object's executable module's file as the file to launch.
+ /// Arguments are given in \a argv, and the environment variables
+ /// are in \a envp. Standard input and output files can be
+ /// optionally re-directed to \a stdin_path, \a stdout_path, and
+ /// \a stderr_path.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses. It will first call Process::WillLaunch (Module *)
+ /// and if that returns \b true, Process::DoLaunch (Module*,
+ /// char const *[],char const *[],const char *,const char *,
+ /// const char *) will be called to actually do the launching. If
+ /// DoLaunch returns \b true, then Process::DidLaunch() will be
+ /// called.
+ ///
+ /// @param[in] argv
+ /// The argument array.
+ ///
+ /// @param[in] envp
+ /// The environment array.
+ ///
+ /// @param[in] launch_flags
+ /// Flags to modify the launch (@see lldb::LaunchFlags)
+ ///
+ /// @param[in] stdin_path
+ /// The path to use when re-directing the STDIN of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] stdout_path
+ /// The path to use when re-directing the STDOUT of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] stderr_path
+ /// The path to use when re-directing the STDERR of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] working_directory
+ /// The working directory to have the child process run in
+ ///
+ /// @return
+ /// An error object. Call GetID() to get the process ID if
+ /// the error object is success.
+ //------------------------------------------------------------------
+ virtual Error
+ Launch (const ProcessLaunchInfo &launch_info);
+
+ virtual Error
+ LoadCore ();
+
+ virtual Error
+ DoLoadCore ()
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support loading core files.", GetPluginName().GetCString());
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the dynamic loader plug-in for this process.
+ ///
+ /// The default action is to let the DynamicLoader plug-ins check
+ /// the main executable and the DynamicLoader will select itself
+ /// automatically. Subclasses can override this if inspecting the
+ /// executable is not desired, or if Process subclasses can only
+ /// use a specific DynamicLoader plug-in.
+ //------------------------------------------------------------------
+ virtual DynamicLoader *
+ GetDynamicLoader ();
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process using the process attach info.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses. It will first call WillAttach (lldb::pid_t)
+ /// or WillAttach (const char *), and if that returns \b
+ /// true, DoAttach (lldb::pid_t) or DoAttach (const char *) will
+ /// be called to actually do the attach. If DoAttach returns \b
+ /// true, then Process::DidAttach() will be called.
+ ///
+ /// @param[in] pid
+ /// The process ID that we should attempt to attach to.
+ ///
+ /// @return
+ /// Returns \a pid if attaching was successful, or
+ /// LLDB_INVALID_PROCESS_ID if attaching fails.
+ //------------------------------------------------------------------
+ virtual Error
+ Attach (ProcessAttachInfo &attach_info);
+
+ //------------------------------------------------------------------
+ /// Attach to a remote system via a URL
+ ///
+ /// @param[in] strm
+ /// A stream where output intended for the user
+ /// (if the driver has a way to display that) generated during
+ /// the connection. This may be NULL if no output is needed.A
+ ///
+ /// @param[in] remote_url
+ /// The URL format that we are connecting to.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error
+ ConnectRemote (Stream *strm, const char *remote_url);
+
+ bool
+ GetShouldDetach () const
+ {
+ return m_should_detach;
+ }
+
+ void
+ SetShouldDetach (bool b)
+ {
+ m_should_detach = b;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the image information address for the current process.
+ ///
+ /// Some runtimes have system functions that can help dynamic
+ /// loaders locate the dynamic loader information needed to observe
+ /// shared libraries being loaded or unloaded. This function is
+ /// in the Process interface (as opposed to the DynamicLoader
+ /// interface) to ensure that remote debugging can take advantage of
+ /// this functionality.
+ ///
+ /// @return
+ /// The address of the dynamic loader information, or
+ /// LLDB_INVALID_ADDRESS if this is not supported by this
+ /// interface.
+ //------------------------------------------------------------------
+ virtual lldb::addr_t
+ GetImageInfoAddress ();
+
+ //------------------------------------------------------------------
+ /// Load a shared library into this process.
+ ///
+ /// Try and load a shared library into the current process. This
+ /// call might fail in the dynamic loader plug-in says it isn't safe
+ /// to try and load shared libraries at the moment.
+ ///
+ /// @param[in] image_spec
+ /// The image file spec that points to the shared library that
+ /// you want to load.
+ ///
+ /// @param[out] error
+ /// An error object that gets filled in with any errors that
+ /// might occur when trying to load the shared library.
+ ///
+ /// @return
+ /// A token that represents the shared library that can be
+ /// later used to unload the shared library. A value of
+ /// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
+ /// library can't be opened.
+ //------------------------------------------------------------------
+ virtual uint32_t
+ LoadImage (const FileSpec &image_spec, Error &error);
+
+ virtual Error
+ UnloadImage (uint32_t image_token);
+
+ //------------------------------------------------------------------
+ /// Register for process and thread notifications.
+ ///
+ /// Clients can register nofication callbacks by filling out a
+ /// Process::Notifications structure and calling this function.
+ ///
+ /// @param[in] callbacks
+ /// A structure that contains the notification baton and
+ /// callback functions.
+ ///
+ /// @see Process::Notifications
+ //------------------------------------------------------------------
+#ifndef SWIG
+ void
+ RegisterNotificationCallbacks (const Process::Notifications& callbacks);
+#endif
+ //------------------------------------------------------------------
+ /// Unregister for process and thread notifications.
+ ///
+ /// Clients can unregister nofication callbacks by passing a copy of
+ /// the original baton and callbacks in \a callbacks.
+ ///
+ /// @param[in] callbacks
+ /// A structure that contains the notification baton and
+ /// callback functions.
+ ///
+ /// @return
+ /// Returns \b true if the notification callbacks were
+ /// successfully removed from the process, \b false otherwise.
+ ///
+ /// @see Process::Notifications
+ //------------------------------------------------------------------
+#ifndef SWIG
+ bool
+ UnregisterNotificationCallbacks (const Process::Notifications& callbacks);
+#endif
+ //==================================================================
+ // Built in Process Control functions
+ //==================================================================
+ //------------------------------------------------------------------
+ /// Resumes all of a process's threads as configured using the
+ /// Thread run control functions.
+ ///
+ /// Threads for a process should be updated with one of the run
+ /// control actions (resume, step, or suspend) that they should take
+ /// when the process is resumed. If no run control action is given
+ /// to a thread it will be resumed by default.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses. This function will take care of disabling any
+ /// breakpoints that threads may be stopped at, single stepping, and
+ /// re-enabling breakpoints, and enabling the basic flow control
+ /// that the plug-in instances need not worry about.
+ ///
+ /// N.B. This function also sets the Write side of the Run Lock,
+ /// which is unset when the corresponding stop event is pulled off
+ /// the Public Event Queue. If you need to resume the process without
+ /// setting the Run Lock, use PrivateResume (though you should only do
+ /// that from inside the Process class.
+ ///
+ /// @return
+ /// Returns an error object.
+ ///
+ /// @see Thread:Resume()
+ /// @see Thread:Step()
+ /// @see Thread:Suspend()
+ //------------------------------------------------------------------
+ Error
+ Resume();
+
+ //------------------------------------------------------------------
+ /// Halts a running process.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses.
+ /// If the process is successfully halted, a eStateStopped
+ /// process event with GetInterrupted will be broadcast. If false, we will
+ /// halt the process with no events generated by the halt.
+ ///
+ /// @param[in] clear_thread_plans
+ /// If true, when the process stops, clear all thread plans.
+ ///
+ /// @return
+ /// Returns an error object. If the error is empty, the process is halted.
+ /// otherwise the halt has failed.
+ //------------------------------------------------------------------
+ Error
+ Halt (bool clear_thread_plans = false);
+
+ //------------------------------------------------------------------
+ /// Detaches from a running or stopped process.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses.
+ ///
+ /// @param[in] keep_stopped
+ /// If true, don't resume the process on detach.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ Error
+ Detach (bool keep_stopped);
+
+ //------------------------------------------------------------------
+ /// Kills the process and shuts down all threads that were spawned
+ /// to track and monitor the process.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ Error
+ Destroy();
+
+ //------------------------------------------------------------------
+ /// Sends a process a UNIX signal \a signal.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ Error
+ Signal (int signal);
+
+ virtual UnixSignals &
+ GetUnixSignals ()
+ {
+ return m_unix_signals;
+ }
+
+ //==================================================================
+ // Plug-in Process Control Overrides
+ //==================================================================
+
+ //------------------------------------------------------------------
+ /// Called before attaching to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before attaching a
+ /// process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error
+ WillAttachToProcessWithID (lldb::pid_t pid)
+ {
+ return Error();
+ }
+
+ //------------------------------------------------------------------
+ /// Called before attaching to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before attaching a
+ /// process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error
+ WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
+ {
+ return Error();
+ }
+
+ //------------------------------------------------------------------
+ /// Attach to a remote system via a URL
+ ///
+ /// @param[in] strm
+ /// A stream where output intended for the user
+ /// (if the driver has a way to display that) generated during
+ /// the connection. This may be NULL if no output is needed.A
+ ///
+ /// @param[in] remote_url
+ /// The URL format that we are connecting to.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error
+ DoConnectRemote (Stream *strm, const char *remote_url)
+ {
+ Error error;
+ error.SetErrorString ("remote connections are not supported");
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process using a process ID.
+ ///
+ /// @param[in] pid
+ /// The process ID that we should attempt to attach to.
+ ///
+ /// @return
+ /// Returns \a pid if attaching was successful, or
+ /// LLDB_INVALID_PROCESS_ID if attaching fails.
+ //------------------------------------------------------------------
+ virtual Error
+ DoAttachToProcessWithID (lldb::pid_t pid)
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support attaching to a process by pid", GetPluginName().GetCString());
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process using a process ID.
+ ///
+ /// @param[in] pid
+ /// The process ID that we should attempt to attach to.
+ ///
+ /// @param[in] attach_info
+ /// Information on how to do the attach. For example, GetUserID()
+ /// will return the uid to attach as.
+ ///
+ /// @return
+ /// Returns \a pid if attaching was successful, or
+ /// LLDB_INVALID_PROCESS_ID if attaching fails.
+ /// hanming : need flag
+ //------------------------------------------------------------------
+ virtual Error
+ DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support attaching to a process by pid", GetPluginName().GetCString());
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Attach to an existing process using a partial process name.
+ ///
+ /// @param[in] process_name
+ /// The name of the process to attach to.
+ ///
+ /// @param[in] wait_for_launch
+ /// If \b true, wait for the process to be launched and attach
+ /// as soon as possible after it does launch. If \b false, then
+ /// search for a matching process the currently exists.
+ ///
+ /// @param[in] attach_info
+ /// Information on how to do the attach. For example, GetUserID()
+ /// will return the uid to attach as.
+ ///
+ /// @return
+ /// Returns \a pid if attaching was successful, or
+ /// LLDB_INVALID_PROCESS_ID if attaching fails.
+ //------------------------------------------------------------------
+ virtual Error
+ DoAttachToProcessWithName (const char *process_name, bool wait_for_launch, const ProcessAttachInfo &attach_info)
+ {
+ Error error;
+ error.SetErrorString("attach by name is not supported");
+ return error;
+ }
+
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow Process plug-ins to execute some code after attaching to
+ /// a process.
+ //------------------------------------------------------------------
+ virtual void
+ DidAttach () {}
+
+
+ //------------------------------------------------------------------
+ /// Called after a process re-execs itself.
+ ///
+ /// Allow Process plug-ins to execute some code after a process has
+ /// exec'ed itself. Subclasses typically should override DoDidExec()
+ /// as the lldb_private::Process class needs to remove its dynamic
+ /// loader, runtime, ABI and other plug-ins, as well as unload all
+ /// shared libraries.
+ //------------------------------------------------------------------
+ virtual void
+ DidExec ();
+
+ //------------------------------------------------------------------
+ /// Subclasses of Process should implement this function if they
+ /// need to do anything after a process exec's itself.
+ //------------------------------------------------------------------
+ virtual void
+ DoDidExec ()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Called before launching to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before launching a
+ /// process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error
+ WillLaunch (Module* module)
+ {
+ return Error();
+ }
+
+ //------------------------------------------------------------------
+ /// Launch a new process.
+ ///
+ /// Launch a new process by spawning a new process using \a module's
+ /// file as the file to launch. Arguments are given in \a argv,
+ /// and the environment variables are in \a envp. Standard input
+ /// and output files can be optionally re-directed to \a stdin_path,
+ /// \a stdout_path, and \a stderr_path.
+ ///
+ /// @param[in] module
+ /// The module from which to extract the file specification and
+ /// launch.
+ ///
+ /// @param[in] argv
+ /// The argument array.
+ ///
+ /// @param[in] envp
+ /// The environment array.
+ ///
+ /// @param[in] launch_flags
+ /// Flags to modify the launch (@see lldb::LaunchFlags)
+ ///
+ /// @param[in] stdin_path
+ /// The path to use when re-directing the STDIN of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] stdout_path
+ /// The path to use when re-directing the STDOUT of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] stderr_path
+ /// The path to use when re-directing the STDERR of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] working_directory
+ /// The working directory to have the child process run in
+ ///
+ /// @return
+ /// A new valid process ID, or LLDB_INVALID_PROCESS_ID if
+ /// launching fails.
+ //------------------------------------------------------------------
+ virtual Error
+ DoLaunch (Module *exe_module,
+ const ProcessLaunchInfo &launch_info)
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support launching processes", GetPluginName().GetCString());
+ return error;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Called after launching a process.
+ ///
+ /// Allow Process plug-ins to execute some code after launching
+ /// a process.
+ //------------------------------------------------------------------
+ virtual void
+ DidLaunch () {}
+
+
+
+ //------------------------------------------------------------------
+ /// Called before resuming to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before resuming a
+ /// process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error
+ WillResume () { return Error(); }
+
+ //------------------------------------------------------------------
+ /// Resumes all of a process's threads as configured using the
+ /// Thread run control functions.
+ ///
+ /// Threads for a process should be updated with one of the run
+ /// control actions (resume, step, or suspend) that they should take
+ /// when the process is resumed. If no run control action is given
+ /// to a thread it will be resumed by default.
+ ///
+ /// @return
+ /// Returns \b true if the process successfully resumes using
+ /// the thread run control actions, \b false otherwise.
+ ///
+ /// @see Thread:Resume()
+ /// @see Thread:Step()
+ /// @see Thread:Suspend()
+ //------------------------------------------------------------------
+ virtual Error
+ DoResume ()
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support resuming processes", GetPluginName().GetCString());
+ return error;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Called after resuming a process.
+ ///
+ /// Allow Process plug-ins to execute some code after resuming
+ /// a process.
+ //------------------------------------------------------------------
+ virtual void
+ DidResume () {}
+
+
+ //------------------------------------------------------------------
+ /// Called before halting to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before halting a
+ /// process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error
+ WillHalt () { return Error(); }
+
+ //------------------------------------------------------------------
+ /// Halts a running process.
+ ///
+ /// DoHalt must produce one and only one stop StateChanged event if it actually
+ /// stops the process. If the stop happens through some natural event (for
+ /// instance a SIGSTOP), then forwarding that event will do. Otherwise, you must
+ /// generate the event manually. Note also, the private event thread is stopped when
+ /// DoHalt is run to prevent the events generated while halting to trigger
+ /// other state changes before the halt is complete.
+ ///
+ /// @param[out] caused_stop
+ /// If true, then this Halt caused the stop, otherwise, the
+ /// process was already stopped.
+ ///
+ /// @return
+ /// Returns \b true if the process successfully halts, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ virtual Error
+ DoHalt (bool &caused_stop)
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support halting processes", GetPluginName().GetCString());
+ return error;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Called after halting a process.
+ ///
+ /// Allow Process plug-ins to execute some code after halting
+ /// a process.
+ //------------------------------------------------------------------
+ virtual void
+ DidHalt () {}
+
+ //------------------------------------------------------------------
+ /// Called before detaching from a process.
+ ///
+ /// Allow Process plug-ins to execute some code before detaching
+ /// from a process.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error
+ WillDetach ()
+ {
+ return Error();
+ }
+
+ //------------------------------------------------------------------
+ /// Detaches from a running or stopped process.
+ ///
+ /// @return
+ /// Returns \b true if the process successfully detaches, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ virtual Error
+ DoDetach (bool keep_stopped)
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support detaching from processes", GetPluginName().GetCString());
+ return error;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Called after detaching from a process.
+ ///
+ /// Allow Process plug-ins to execute some code after detaching
+ /// from a process.
+ //------------------------------------------------------------------
+ virtual void
+ DidDetach () {}
+
+ virtual bool
+ DetachRequiresHalt() { return false; }
+
+ //------------------------------------------------------------------
+ /// Called before sending a signal to a process.
+ ///
+ /// Allow Process plug-ins to execute some code before sending a
+ /// signal to a process.
+ ///
+ /// @return
+ /// Returns no error if it is safe to proceed with a call to
+ /// Process::DoSignal(int), otherwise an error describing what
+ /// prevents the signal from being sent.
+ //------------------------------------------------------------------
+ virtual Error
+ WillSignal () { return Error(); }
+
+ //------------------------------------------------------------------
+ /// Sends a process a UNIX signal \a signal.
+ ///
+ /// @return
+ /// Returns an error object.
+ //------------------------------------------------------------------
+ virtual Error
+ DoSignal (int signal)
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support senging signals to processes", GetPluginName().GetCString());
+ return error;
+ }
+
+ virtual Error
+ WillDestroy () { return Error(); }
+
+ virtual Error
+ DoDestroy () = 0;
+
+ virtual void
+ DidDestroy () { }
+
+ virtual bool
+ DestroyRequiresHalt() { return true; }
+
+
+ //------------------------------------------------------------------
+ /// Called after sending a signal to a process.
+ ///
+ /// Allow Process plug-ins to execute some code after sending a
+ /// signal to a process.
+ //------------------------------------------------------------------
+ virtual void
+ DidSignal () {}
+
+ //------------------------------------------------------------------
+ /// Currently called as part of ShouldStop.
+ /// FIXME: Should really happen when the target stops before the
+ /// event is taken from the queue...
+ ///
+ /// This callback is called as the event
+ /// is about to be queued up to allow Process plug-ins to execute
+ /// some code prior to clients being notified that a process was
+ /// stopped. Common operations include updating the thread list,
+ /// invalidating any thread state (registers, stack, etc) prior to
+ /// letting the notification go out.
+ ///
+ //------------------------------------------------------------------
+ virtual void
+ RefreshStateAfterStop () = 0;
+
+ //------------------------------------------------------------------
+ /// Get the target object pointer for this module.
+ ///
+ /// @return
+ /// A Target object pointer to the target that owns this
+ /// module.
+ //------------------------------------------------------------------
+ Target &
+ GetTarget ()
+ {
+ return m_target;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the const target object pointer for this module.
+ ///
+ /// @return
+ /// A const Target object pointer to the target that owns this
+ /// module.
+ //------------------------------------------------------------------
+ const Target &
+ GetTarget () const
+ {
+ return m_target;
+ }
+
+ //------------------------------------------------------------------
+ /// Flush all data in the process.
+ ///
+ /// Flush the memory caches, all threads, and any other cached data
+ /// in the process.
+ ///
+ /// This function can be called after a world changing event like
+ /// adding a new symbol file, or after the process makes a large
+ /// context switch (from boot ROM to booted into an OS).
+ //------------------------------------------------------------------
+ void
+ Flush ();
+
+ //------------------------------------------------------------------
+ /// Get accessor for the current process state.
+ ///
+ /// @return
+ /// The current state of the process.
+ ///
+ /// @see lldb::StateType
+ //------------------------------------------------------------------
+ lldb::StateType
+ GetState ();
+
+ ExecutionResults
+ RunThreadPlan (ExecutionContext &exe_ctx,
+ lldb::ThreadPlanSP &thread_plan_sp,
+ bool stop_others,
+ bool run_others,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
+ uint32_t timeout_usec,
+ Stream &errors);
+
+ static const char *
+ ExecutionResultAsCString (ExecutionResults result);
+
+ void
+ GetStatus (Stream &ostrm);
+
+ size_t
+ GetThreadStatus (Stream &ostrm,
+ bool only_threads_with_stop_reason,
+ uint32_t start_frame,
+ uint32_t num_frames,
+ uint32_t num_frames_with_source);
+
+ void
+ SendAsyncInterrupt ();
+
+protected:
+
+ void
+ SetState (lldb::EventSP &event_sp);
+
+ lldb::StateType
+ GetPrivateState ();
+
+ //------------------------------------------------------------------
+ /// The "private" side of resuming a process. This doesn't alter the
+ /// state of m_run_lock, but just causes the process to resume.
+ ///
+ /// @return
+ /// An Error object describing the success or failure of the resume.
+ //------------------------------------------------------------------
+ Error
+ PrivateResume ();
+
+ //------------------------------------------------------------------
+ // Called internally
+ //------------------------------------------------------------------
+ void
+ CompleteAttach ();
+
+public:
+ //------------------------------------------------------------------
+ /// Get the exit status for a process.
+ ///
+ /// @return
+ /// The process's return code, or -1 if the current process
+ /// state is not eStateExited.
+ //------------------------------------------------------------------
+ int
+ GetExitStatus ();
+
+ //------------------------------------------------------------------
+ /// Get a textual description of what the process exited.
+ ///
+ /// @return
+ /// The textual description of why the process exited, or NULL
+ /// if there is no description available.
+ //------------------------------------------------------------------
+ const char *
+ GetExitDescription ();
+
+
+ virtual void
+ DidExit ()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Get the Modification ID of the process.
+ ///
+ /// @return
+ /// The modification ID of the process.
+ //------------------------------------------------------------------
+ ProcessModID
+ GetModID () const
+ {
+ return m_mod_id;
+ }
+
+ const ProcessModID &
+ GetModIDRef () const
+ {
+ return m_mod_id;
+ }
+
+ uint32_t
+ GetStopID () const
+ {
+ return m_mod_id.GetStopID();
+ }
+
+ uint32_t
+ GetResumeID () const
+ {
+ return m_mod_id.GetResumeID();
+ }
+
+ uint32_t
+ GetLastUserExpressionResumeID () const
+ {
+ return m_mod_id.GetLastUserExpressionResumeID();
+ }
+
+ uint32_t
+ GetLastNaturalStopID()
+ {
+ return m_mod_id.GetLastNaturalStopID();
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the process exit status (return code).
+ ///
+ /// Sometimes a child exits and the exit can be detected by global
+ /// functions (signal handler for SIGCHLD for example). This
+ /// accessor allows the exit status to be set from an external
+ /// source.
+ ///
+ /// Setting this will cause a eStateExited event to be posted to
+ /// the process event queue.
+ ///
+ /// @param[in] exit_status
+ /// The value for the process's return code.
+ ///
+ /// @see lldb::StateType
+ //------------------------------------------------------------------
+ virtual bool
+ SetExitStatus (int exit_status, const char *cstr);
+
+ //------------------------------------------------------------------
+ /// Check if a process is still alive.
+ ///
+ /// @return
+ /// Returns \b true if the process is still valid, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ IsAlive () = 0;
+
+ //------------------------------------------------------------------
+ /// Before lldb detaches from a process, it warns the user that they are about to lose their debug session.
+ /// In some cases, this warning doesn't need to be emitted -- for instance, with core file debugging where
+ /// the user can reconstruct the "state" by simply re-running the debugger on the core file.
+ ///
+ /// @return
+ // true if the user should be warned about detaching from this process.
+ //------------------------------------------------------------------
+ virtual bool
+ WarnBeforeDetach () const
+ {
+ return true;
+ }
+
+ //------------------------------------------------------------------
+ /// Actually do the reading of memory from a process.
+ ///
+ /// Subclasses must override this function and can return fewer
+ /// bytes than requested when memory requests are too large. This
+ /// class will break up the memory requests and keep advancing the
+ /// arguments along as needed.
+ ///
+ /// @param[in] vm_addr
+ /// A virtual load address that indicates where to start reading
+ /// memory from.
+ ///
+ /// @param[in] size
+ /// The number of bytes to read.
+ ///
+ /// @param[out] buf
+ /// A byte buffer that is at least \a size bytes long that
+ /// will receive the memory bytes.
+ ///
+ /// @return
+ /// The number of bytes that were actually read into \a buf.
+ //------------------------------------------------------------------
+ virtual size_t
+ DoReadMemory (lldb::addr_t vm_addr,
+ void *buf,
+ size_t size,
+ Error &error) = 0;
+
+ //------------------------------------------------------------------
+ /// Read of memory from a process.
+ ///
+ /// This function will read memory from the current process's
+ /// address space and remove any traps that may have been inserted
+ /// into the memory.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses, the subclasses should implement
+ /// Process::DoReadMemory (lldb::addr_t, size_t, void *).
+ ///
+ /// @param[in] vm_addr
+ /// A virtual load address that indicates where to start reading
+ /// memory from.
+ ///
+ /// @param[out] buf
+ /// A byte buffer that is at least \a size bytes long that
+ /// will receive the memory bytes.
+ ///
+ /// @param[in] size
+ /// The number of bytes to read.
+ ///
+ /// @return
+ /// The number of bytes that were actually read into \a buf. If
+ /// the returned number is greater than zero, yet less than \a
+ /// size, then this function will get called again with \a
+ /// vm_addr, \a buf, and \a size updated appropriately. Zero is
+ /// returned to indicate an error.
+ //------------------------------------------------------------------
+ virtual size_t
+ ReadMemory (lldb::addr_t vm_addr,
+ void *buf,
+ size_t size,
+ Error &error);
+
+ //------------------------------------------------------------------
+ /// Read a NULL terminated string from memory
+ ///
+ /// This function will read a cache page at a time until a NULL
+ /// string terminator is found. It will stop reading if an aligned
+ /// sequence of NULL termination \a type_width bytes is not found
+ /// before reading \a cstr_max_len bytes. The results are always
+ /// guaranteed to be NULL terminated, and that no more than
+ /// (max_bytes - type_width) bytes will be read.
+ ///
+ /// @param[in] vm_addr
+ /// The virtual load address to start the memory read.
+ ///
+ /// @param[in] str
+ /// A character buffer containing at least max_bytes.
+ ///
+ /// @param[in] max_bytes
+ /// The maximum number of bytes to read.
+ ///
+ /// @param[in] error
+ /// The error status of the read operation.
+ ///
+ /// @param[in] type_width
+ /// The size of the null terminator (1 to 4 bytes per
+ /// character). Defaults to 1.
+ ///
+ /// @return
+ /// The error status or the number of bytes prior to the null terminator.
+ //------------------------------------------------------------------
+ size_t
+ ReadStringFromMemory (lldb::addr_t vm_addr,
+ char *str,
+ size_t max_bytes,
+ Error &error,
+ size_t type_width = 1);
+
+ //------------------------------------------------------------------
+ /// Read a NULL terminated C string from memory
+ ///
+ /// This function will read a cache page at a time until the NULL
+ /// C string terminator is found. It will stop reading if the NULL
+ /// termination byte isn't found before reading \a cstr_max_len
+ /// bytes, and the results are always guaranteed to be NULL
+ /// terminated (at most cstr_max_len - 1 bytes will be read).
+ //------------------------------------------------------------------
+ size_t
+ ReadCStringFromMemory (lldb::addr_t vm_addr,
+ char *cstr,
+ size_t cstr_max_len,
+ Error &error);
+
+ size_t
+ ReadCStringFromMemory (lldb::addr_t vm_addr,
+ std::string &out_str,
+ Error &error);
+
+ size_t
+ ReadMemoryFromInferior (lldb::addr_t vm_addr,
+ void *buf,
+ size_t size,
+ Error &error);
+
+ //------------------------------------------------------------------
+ /// Reads an unsigned integer of the specified byte size from
+ /// process memory.
+ ///
+ /// @param[in] load_addr
+ /// A load address of the integer to read.
+ ///
+ /// @param[in] byte_size
+ /// The size in byte of the integer to read.
+ ///
+ /// @param[in] fail_value
+ /// The value to return if we fail to read an integer.
+ ///
+ /// @param[out] error
+ /// An error that indicates the success or failure of this
+ /// operation. If error indicates success (error.Success()),
+ /// then the value returned can be trusted, otherwise zero
+ /// will be returned.
+ ///
+ /// @return
+ /// The unsigned integer that was read from the process memory
+ /// space. If the integer was smaller than a uint64_t, any
+ /// unused upper bytes will be zero filled. If the process
+ /// byte order differs from the host byte order, the integer
+ /// value will be appropriately byte swapped into host byte
+ /// order.
+ //------------------------------------------------------------------
+ uint64_t
+ ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
+ size_t byte_size,
+ uint64_t fail_value,
+ Error &error);
+
+ lldb::addr_t
+ ReadPointerFromMemory (lldb::addr_t vm_addr,
+ Error &error);
+
+ bool
+ WritePointerToMemory (lldb::addr_t vm_addr,
+ lldb::addr_t ptr_value,
+ Error &error);
+
+ //------------------------------------------------------------------
+ /// Actually do the writing of memory to a process.
+ ///
+ /// @param[in] vm_addr
+ /// A virtual load address that indicates where to start writing
+ /// memory to.
+ ///
+ /// @param[in] buf
+ /// A byte buffer that is at least \a size bytes long that
+ /// contains the data to write.
+ ///
+ /// @param[in] size
+ /// The number of bytes to write.
+ ///
+ /// @param[out] error
+ /// An error value in case the memory write fails.
+ ///
+ /// @return
+ /// The number of bytes that were actually written.
+ //------------------------------------------------------------------
+ virtual size_t
+ DoWriteMemory (lldb::addr_t vm_addr, const void *buf, size_t size, Error &error)
+ {
+ error.SetErrorStringWithFormat("error: %s does not support writing to processes", GetPluginName().GetCString());
+ return 0;
+ }
+
+
+ //------------------------------------------------------------------
+ /// Write all or part of a scalar value to memory.
+ ///
+ /// The value contained in \a scalar will be swapped to match the
+ /// byte order of the process that is being debugged. If \a size is
+ /// less than the size of scalar, the least significate \a size bytes
+ /// from scalar will be written. If \a size is larger than the byte
+ /// size of scalar, then the extra space will be padded with zeros
+ /// and the scalar value will be placed in the least significant
+ /// bytes in memory.
+ ///
+ /// @param[in] vm_addr
+ /// A virtual load address that indicates where to start writing
+ /// memory to.
+ ///
+ /// @param[in] scalar
+ /// The scalar to write to the debugged process.
+ ///
+ /// @param[in] size
+ /// This value can be smaller or larger than the scalar value
+ /// itself. If \a size is smaller than the size of \a scalar,
+ /// the least significant bytes in \a scalar will be used. If
+ /// \a size is larger than the byte size of \a scalar, then
+ /// the extra space will be padded with zeros. If \a size is
+ /// set to UINT32_MAX, then the size of \a scalar will be used.
+ ///
+ /// @param[out] error
+ /// An error value in case the memory write fails.
+ ///
+ /// @return
+ /// The number of bytes that were actually written.
+ //------------------------------------------------------------------
+ size_t
+ WriteScalarToMemory (lldb::addr_t vm_addr,
+ const Scalar &scalar,
+ size_t size,
+ Error &error);
+
+ size_t
+ ReadScalarIntegerFromMemory (lldb::addr_t addr,
+ uint32_t byte_size,
+ bool is_signed,
+ Scalar &scalar,
+ Error &error);
+
+ //------------------------------------------------------------------
+ /// Write memory to a process.
+ ///
+ /// This function will write memory to the current process's
+ /// address space and maintain any traps that might be present due
+ /// to software breakpoints.
+ ///
+ /// This function is not meant to be overridden by Process
+ /// subclasses, the subclasses should implement
+ /// Process::DoWriteMemory (lldb::addr_t, size_t, void *).
+ ///
+ /// @param[in] vm_addr
+ /// A virtual load address that indicates where to start writing
+ /// memory to.
+ ///
+ /// @param[in] buf
+ /// A byte buffer that is at least \a size bytes long that
+ /// contains the data to write.
+ ///
+ /// @param[in] size
+ /// The number of bytes to write.
+ ///
+ /// @return
+ /// The number of bytes that were actually written.
+ //------------------------------------------------------------------
+ size_t
+ WriteMemory (lldb::addr_t vm_addr, const void *buf, size_t size, Error &error);
+
+
+ //------------------------------------------------------------------
+ /// Actually allocate memory in the process.
+ ///
+ /// This function will allocate memory in the process's address
+ /// space. This can't rely on the generic function calling mechanism,
+ /// since that requires this function.
+ ///
+ /// @param[in] size
+ /// The size of the allocation requested.
+ ///
+ /// @return
+ /// The address of the allocated buffer in the process, or
+ /// LLDB_INVALID_ADDRESS if the allocation failed.
+ //------------------------------------------------------------------
+
+ virtual lldb::addr_t
+ DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
+ {
+ error.SetErrorStringWithFormat("error: %s does not support allocating in the debug process", GetPluginName().GetCString());
+ return LLDB_INVALID_ADDRESS;
+ }
+
+
+ //------------------------------------------------------------------
+ /// The public interface to allocating memory in the process.
+ ///
+ /// This function will allocate memory in the process's address
+ /// space. This can't rely on the generic function calling mechanism,
+ /// since that requires this function.
+ ///
+ /// @param[in] size
+ /// The size of the allocation requested.
+ ///
+ /// @param[in] permissions
+ /// Or together any of the lldb::Permissions bits. The permissions on
+ /// a given memory allocation can't be changed after allocation. Note
+ /// that a block that isn't set writable can still be written on from lldb,
+ /// just not by the process itself.
+ ///
+ /// @param[in/out] error
+ /// An error object to fill in if things go wrong.
+ /// @return
+ /// The address of the allocated buffer in the process, or
+ /// LLDB_INVALID_ADDRESS if the allocation failed.
+ //------------------------------------------------------------------
+
+ lldb::addr_t
+ AllocateMemory (size_t size, uint32_t permissions, Error &error);
+
+
+ //------------------------------------------------------------------
+ /// Resolve dynamically loaded indirect functions.
+ ///
+ /// @param[in] address
+ /// The load address of the indirect function to resolve.
+ ///
+ /// @param[out] error
+ /// An error value in case the resolve fails.
+ ///
+ /// @return
+ /// The address of the resolved function.
+ /// LLDB_INVALID_ADDRESS if the resolution failed.
+ //------------------------------------------------------------------
+
+ virtual lldb::addr_t
+ ResolveIndirectFunction(const Address *address, Error &error)
+ {
+ error.SetErrorStringWithFormat("error: %s does not support indirect functions in the debug process", GetPluginName().GetCString());
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ virtual Error
+ GetMemoryRegionInfo (lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info)
+ {
+ Error error;
+ error.SetErrorString ("Process::GetMemoryRegionInfo() not supported");
+ return error;
+ }
+
+ virtual Error
+ GetWatchpointSupportInfo (uint32_t &num)
+ {
+ Error error;
+ num = 0;
+ error.SetErrorString ("Process::GetWatchpointSupportInfo() not supported");
+ return error;
+ }
+
+ virtual Error
+ GetWatchpointSupportInfo (uint32_t &num, bool& after)
+ {
+ Error error;
+ num = 0;
+ after = true;
+ error.SetErrorString ("Process::GetWatchpointSupportInfo() not supported");
+ return error;
+ }
+
+ lldb::ModuleSP
+ ReadModuleFromMemory (const FileSpec& file_spec,
+ lldb::addr_t header_addr);
+
+ //------------------------------------------------------------------
+ /// Attempt to get the attributes for a region of memory in the process.
+ ///
+ /// It may be possible for the remote debug server to inspect attributes
+ /// for a region of memory in the process, such as whether there is a
+ /// valid page of memory at a given address or whether that page is
+ /// readable/writable/executable by the process.
+ ///
+ /// @param[in] load_addr
+ /// The address of interest in the process.
+ ///
+ /// @param[out] permissions
+ /// If this call returns successfully, this bitmask will have
+ /// its Permissions bits set to indicate whether the region is
+ /// readable/writable/executable. If this call fails, the
+ /// bitmask values are undefined.
+ ///
+ /// @return
+ /// Returns true if it was able to determine the attributes of the
+ /// memory region. False if not.
+ //------------------------------------------------------------------
+
+ virtual bool
+ GetLoadAddressPermissions (lldb::addr_t load_addr, uint32_t &permissions)
+ {
+ MemoryRegionInfo range_info;
+ permissions = 0;
+ Error error (GetMemoryRegionInfo (load_addr, range_info));
+ if (!error.Success())
+ return false;
+ if (range_info.GetReadable() == MemoryRegionInfo::eDontKnow
+ || range_info.GetWritable() == MemoryRegionInfo::eDontKnow
+ || range_info.GetExecutable() == MemoryRegionInfo::eDontKnow)
+ {
+ return false;
+ }
+
+ if (range_info.GetReadable() == MemoryRegionInfo::eYes)
+ permissions |= lldb::ePermissionsReadable;
+
+ if (range_info.GetWritable() == MemoryRegionInfo::eYes)
+ permissions |= lldb::ePermissionsWritable;
+
+ if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
+ permissions |= lldb::ePermissionsExecutable;
+
+ return true;
+ }
+
+ //------------------------------------------------------------------
+ /// Determines whether executing JIT-compiled code in this process
+ /// is possible.
+ ///
+ /// @return
+ /// True if execution of JIT code is possible; false otherwise.
+ //------------------------------------------------------------------
+ bool CanJIT ();
+
+ //------------------------------------------------------------------
+ /// Sets whether executing JIT-compiled code in this process
+ /// is possible.
+ ///
+ /// @param[in] can_jit
+ /// True if execution of JIT code is possible; false otherwise.
+ //------------------------------------------------------------------
+ void SetCanJIT (bool can_jit);
+
+ //------------------------------------------------------------------
+ /// Actually deallocate memory in the process.
+ ///
+ /// This function will deallocate memory in the process's address
+ /// space that was allocated with AllocateMemory.
+ ///
+ /// @param[in] ptr
+ /// A return value from AllocateMemory, pointing to the memory you
+ /// want to deallocate.
+ ///
+ /// @return
+ /// \btrue if the memory was deallocated, \bfalse otherwise.
+ //------------------------------------------------------------------
+
+ virtual Error
+ DoDeallocateMemory (lldb::addr_t ptr)
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support deallocating in the debug process", GetPluginName().GetCString());
+ return error;
+ }
+
+
+ //------------------------------------------------------------------
+ /// The public interface to deallocating memory in the process.
+ ///
+ /// This function will deallocate memory in the process's address
+ /// space that was allocated with AllocateMemory.
+ ///
+ /// @param[in] ptr
+ /// A return value from AllocateMemory, pointing to the memory you
+ /// want to deallocate.
+ ///
+ /// @return
+ /// \btrue if the memory was deallocated, \bfalse otherwise.
+ //------------------------------------------------------------------
+
+ Error
+ DeallocateMemory (lldb::addr_t ptr);
+
+ //------------------------------------------------------------------
+ /// Get any available STDOUT.
+ ///
+ /// If the process was launched without supplying valid file paths
+ /// for stdin, stdout, and stderr, then the Process class might
+ /// try to cache the STDOUT for the process if it is able. Events
+ /// will be queued indicating that there is STDOUT available that
+ /// can be retrieved using this function.
+ ///
+ /// @param[out] buf
+ /// A buffer that will receive any STDOUT bytes that are
+ /// currently available.
+ ///
+ /// @param[out] buf_size
+ /// The size in bytes for the buffer \a buf.
+ ///
+ /// @return
+ /// The number of bytes written into \a buf. If this value is
+ /// equal to \a buf_size, another call to this function should
+ /// be made to retrieve more STDOUT data.
+ //------------------------------------------------------------------
+ virtual size_t
+ GetSTDOUT (char *buf, size_t buf_size, Error &error);
+
+ //------------------------------------------------------------------
+ /// Get any available STDERR.
+ ///
+ /// If the process was launched without supplying valid file paths
+ /// for stdin, stdout, and stderr, then the Process class might
+ /// try to cache the STDERR for the process if it is able. Events
+ /// will be queued indicating that there is STDERR available that
+ /// can be retrieved using this function.
+ ///
+ /// @param[out] buf
+ /// A buffer that will receive any STDERR bytes that are
+ /// currently available.
+ ///
+ /// @param[out] buf_size
+ /// The size in bytes for the buffer \a buf.
+ ///
+ /// @return
+ /// The number of bytes written into \a buf. If this value is
+ /// equal to \a buf_size, another call to this function should
+ /// be made to retrieve more STDERR data.
+ //------------------------------------------------------------------
+ virtual size_t
+ GetSTDERR (char *buf, size_t buf_size, Error &error);
+
+ virtual size_t
+ PutSTDIN (const char *buf, size_t buf_size, Error &error)
+ {
+ error.SetErrorString("stdin unsupported");
+ return 0;
+ }
+
+ //------------------------------------------------------------------
+ /// Get any available profile data.
+ ///
+ /// @param[out] buf
+ /// A buffer that will receive any profile data bytes that are
+ /// currently available.
+ ///
+ /// @param[out] buf_size
+ /// The size in bytes for the buffer \a buf.
+ ///
+ /// @return
+ /// The number of bytes written into \a buf. If this value is
+ /// equal to \a buf_size, another call to this function should
+ /// be made to retrieve more profile data.
+ //------------------------------------------------------------------
+ virtual size_t
+ GetAsyncProfileData (char *buf, size_t buf_size, Error &error);
+
+ //----------------------------------------------------------------------
+ // Process Breakpoints
+ //----------------------------------------------------------------------
+ size_t
+ GetSoftwareBreakpointTrapOpcode (BreakpointSite* bp_site);
+
+ virtual Error
+ EnableBreakpointSite (BreakpointSite *bp_site)
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support enabling breakpoints", GetPluginName().GetCString());
+ return error;
+ }
+
+
+ virtual Error
+ DisableBreakpointSite (BreakpointSite *bp_site)
+ {
+ Error error;
+ error.SetErrorStringWithFormat("error: %s does not support disabling breakpoints", GetPluginName().GetCString());
+ return error;
+ }
+
+
+ // This is implemented completely using the lldb::Process API. Subclasses
+ // don't need to implement this function unless the standard flow of
+ // read existing opcode, write breakpoint opcode, verify breakpoint opcode
+ // doesn't work for a specific process plug-in.
+ virtual Error
+ EnableSoftwareBreakpoint (BreakpointSite *bp_site);
+
+ // This is implemented completely using the lldb::Process API. Subclasses
+ // don't need to implement this function unless the standard flow of
+ // restoring original opcode in memory and verifying the restored opcode
+ // doesn't work for a specific process plug-in.
+ virtual Error
+ DisableSoftwareBreakpoint (BreakpointSite *bp_site);
+
+ BreakpointSiteList &
+ GetBreakpointSiteList();
+
+ const BreakpointSiteList &
+ GetBreakpointSiteList() const;
+
+ void
+ DisableAllBreakpointSites ();
+
+ Error
+ ClearBreakpointSiteByID (lldb::user_id_t break_id);
+
+ lldb::break_id_t
+ CreateBreakpointSite (const lldb::BreakpointLocationSP &owner,
+ bool use_hardware);
+
+ Error
+ DisableBreakpointSiteByID (lldb::user_id_t break_id);
+
+ Error
+ EnableBreakpointSiteByID (lldb::user_id_t break_id);
+
+
+ // BreakpointLocations use RemoveOwnerFromBreakpointSite to remove
+ // themselves from the owner's list of this breakpoint sites.
+ void
+ RemoveOwnerFromBreakpointSite (lldb::user_id_t owner_id,
+ lldb::user_id_t owner_loc_id,
+ lldb::BreakpointSiteSP &bp_site_sp);
+
+ //----------------------------------------------------------------------
+ // Process Watchpoints (optional)
+ //----------------------------------------------------------------------
+ virtual Error
+ EnableWatchpoint (Watchpoint *wp, bool notify = true);
+
+ virtual Error
+ DisableWatchpoint (Watchpoint *wp, bool notify = true);
+
+ //------------------------------------------------------------------
+ // Thread Queries
+ //------------------------------------------------------------------
+ virtual bool
+ UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list) = 0;
+
+ void
+ UpdateThreadListIfNeeded ();
+
+ ThreadList &
+ GetThreadList ()
+ {
+ return m_thread_list;
+ }
+
+ uint32_t
+ GetNextThreadIndexID (uint64_t thread_id);
+
+ lldb::ThreadSP
+ CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context);
+
+ // Returns true if an index id has been assigned to a thread.
+ bool
+ HasAssignedIndexIDToThread(uint64_t sb_thread_id);
+
+ // Given a thread_id, it will assign a more reasonable index id for display to the user.
+ // If the thread_id has previously been assigned, the same index id will be used.
+ uint32_t
+ AssignIndexIDToThread(uint64_t thread_id);
+
+ //------------------------------------------------------------------
+ // Event Handling
+ //------------------------------------------------------------------
+ lldb::StateType
+ GetNextEvent (lldb::EventSP &event_sp);
+
+ lldb::StateType
+ WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp_ptr = NULL);
+
+ lldb::StateType
+ WaitForStateChangedEvents (const TimeValue *timeout, lldb::EventSP &event_sp);
+
+ Event *
+ PeekAtStateChangedEvents ();
+
+
+ class
+ ProcessEventHijacker
+ {
+ public:
+ ProcessEventHijacker (Process &process, Listener *listener) :
+ m_process (process)
+ {
+ m_process.HijackProcessEvents (listener);
+ }
+ ~ProcessEventHijacker ()
+ {
+ m_process.RestoreProcessEvents();
+ }
+
+ private:
+ Process &m_process;
+ };
+ friend class ProcessEventHijacker;
+ //------------------------------------------------------------------
+ /// If you need to ensure that you and only you will hear about some public
+ /// event, then make a new listener, set to listen to process events, and
+ /// then call this with that listener. Then you will have to wait on that
+ /// listener explicitly for events (rather than using the GetNextEvent & WaitFor*
+ /// calls above. Be sure to call RestoreProcessEvents when you are done.
+ ///
+ /// @param[in] listener
+ /// This is the new listener to whom all process events will be delivered.
+ ///
+ /// @return
+ /// Returns \b true if the new listener could be installed,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ HijackProcessEvents (Listener *listener);
+
+ //------------------------------------------------------------------
+ /// Restores the process event broadcasting to its normal state.
+ ///
+ //------------------------------------------------------------------
+ void
+ RestoreProcessEvents ();
+
+private:
+ //------------------------------------------------------------------
+ /// This is the part of the event handling that for a process event.
+ /// It decides what to do with the event and returns true if the
+ /// event needs to be propagated to the user, and false otherwise.
+ /// If the event is not propagated, this call will most likely set
+ /// the target to executing again.
+ /// There is only one place where this call should be called, HandlePrivateEvent.
+ /// Don't call it from anywhere else...
+ ///
+ /// @param[in] event_ptr
+ /// This is the event we are handling.
+ ///
+ /// @return
+ /// Returns \b true if the event should be reported to the
+ /// user, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ShouldBroadcastEvent (Event *event_ptr);
+
+public:
+ const lldb::ABISP &
+ GetABI ();
+
+ OperatingSystem *
+ GetOperatingSystem ()
+ {
+ return m_os_ap.get();
+ }
+
+
+ virtual LanguageRuntime *
+ GetLanguageRuntime (lldb::LanguageType language, bool retry_if_null = true);
+
+ virtual CPPLanguageRuntime *
+ GetCPPLanguageRuntime (bool retry_if_null = true);
+
+ virtual ObjCLanguageRuntime *
+ GetObjCLanguageRuntime (bool retry_if_null = true);
+
+ bool
+ IsPossibleDynamicValue (ValueObject& in_value);
+
+ bool
+ IsRunning () const;
+
+ DynamicCheckerFunctions *GetDynamicCheckers()
+ {
+ return m_dynamic_checkers_ap.get();
+ }
+
+ void SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers)
+ {
+ m_dynamic_checkers_ap.reset(dynamic_checkers);
+ }
+
+ //------------------------------------------------------------------
+ /// Call this to set the lldb in the mode where it breaks on new thread
+ /// creations, and then auto-restarts. This is useful when you are trying
+ /// to run only one thread, but either that thread or the kernel is creating
+ /// new threads in the process. If you stop when the thread is created, you
+ /// can immediately suspend it, and keep executing only the one thread you intend.
+ ///
+ /// @return
+ /// Returns \b true if we were able to start up the notification
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ StartNoticingNewThreads()
+ {
+ return true;
+ }
+
+ //------------------------------------------------------------------
+ /// Call this to turn off the stop & notice new threads mode.
+ ///
+ /// @return
+ /// Returns \b true if we were able to start up the notification
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ StopNoticingNewThreads()
+ {
+ return true;
+ }
+
+ void
+ SetRunningUserExpression (bool on);
+
+ //------------------------------------------------------------------
+ // lldb::ExecutionContextScope pure virtual functions
+ //------------------------------------------------------------------
+ virtual lldb::TargetSP
+ CalculateTarget ();
+
+ virtual lldb::ProcessSP
+ CalculateProcess ()
+ {
+ return shared_from_this();
+ }
+
+ virtual lldb::ThreadSP
+ CalculateThread ()
+ {
+ return lldb::ThreadSP();
+ }
+
+ virtual lldb::StackFrameSP
+ CalculateStackFrame ()
+ {
+ return lldb::StackFrameSP();
+ }
+
+ virtual void
+ CalculateExecutionContext (ExecutionContext &exe_ctx);
+
+ void
+ SetSTDIOFileDescriptor (int file_descriptor);
+
+ //------------------------------------------------------------------
+ // Add a permanent region of memory that should never be read or
+ // written to. This can be used to ensure that memory reads or writes
+ // to certain areas of memory never end up being sent to the
+ // DoReadMemory or DoWriteMemory functions which can improve
+ // performance.
+ //------------------------------------------------------------------
+ void
+ AddInvalidMemoryRegion (const LoadRange &region);
+
+ //------------------------------------------------------------------
+ // Remove a permanent region of memory that should never be read or
+ // written to that was previously added with AddInvalidMemoryRegion.
+ //------------------------------------------------------------------
+ bool
+ RemoveInvalidMemoryRange (const LoadRange &region);
+
+ //------------------------------------------------------------------
+ // If the setup code of a thread plan needs to do work that might involve
+ // calling a function in the target, it should not do that work directly
+ // in one of the thread plan functions (DidPush/WillResume) because
+ // such work needs to be handled carefully. Instead, put that work in
+ // a PreResumeAction callback, and register it with the process. It will
+ // get done before the actual "DoResume" gets called.
+ //------------------------------------------------------------------
+
+ typedef bool (PreResumeActionCallback)(void *);
+
+ void
+ AddPreResumeAction (PreResumeActionCallback callback, void *baton);
+
+ bool
+ RunPreResumeActions ();
+
+ void
+ ClearPreResumeActions ();
+
+ ProcessRunLock &
+ GetRunLock ()
+ {
+ if (Host::GetCurrentThread() == m_private_state_thread)
+ return m_private_run_lock;
+ else
+ return m_public_run_lock;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // NextEventAction provides a way to register an action on the next
+ // event that is delivered to this process. There is currently only
+ // one next event action allowed in the process at one time. If a
+ // new "NextEventAction" is added while one is already present, the
+ // old action will be discarded (with HandleBeingUnshipped called
+ // after it is discarded.)
+ //
+ // If you want to resume the process as a result of a resume action,
+ // call RequestResume, don't call Resume directly.
+ //------------------------------------------------------------------
+ class NextEventAction
+ {
+ public:
+ typedef enum EventActionResult
+ {
+ eEventActionSuccess,
+ eEventActionRetry,
+ eEventActionExit
+ } EventActionResult;
+
+ NextEventAction (Process *process) :
+ m_process(process)
+ {
+ }
+
+ virtual
+ ~NextEventAction()
+ {
+ }
+
+ virtual EventActionResult PerformAction (lldb::EventSP &event_sp) = 0;
+ virtual void HandleBeingUnshipped () {}
+ virtual EventActionResult HandleBeingInterrupted () = 0;
+ virtual const char *GetExitString() = 0;
+ void RequestResume()
+ {
+ m_process->m_resume_requested = true;
+ }
+ protected:
+ Process *m_process;
+ };
+
+ void SetNextEventAction (Process::NextEventAction *next_event_action)
+ {
+ if (m_next_event_action_ap.get())
+ m_next_event_action_ap->HandleBeingUnshipped();
+
+ m_next_event_action_ap.reset(next_event_action);
+ }
+
+ // This is the completer for Attaching:
+ class AttachCompletionHandler : public NextEventAction
+ {
+ public:
+ AttachCompletionHandler (Process *process, uint32_t exec_count) :
+ NextEventAction (process),
+ m_exec_count (exec_count)
+ {
+ }
+
+ virtual
+ ~AttachCompletionHandler()
+ {
+ }
+
+ virtual EventActionResult PerformAction (lldb::EventSP &event_sp);
+ virtual EventActionResult HandleBeingInterrupted ();
+ virtual const char *GetExitString();
+ private:
+ uint32_t m_exec_count;
+ std::string m_exit_string;
+ };
+
+ bool
+ HijackPrivateProcessEvents (Listener *listener);
+
+ void
+ RestorePrivateProcessEvents ();
+
+ bool
+ PrivateStateThreadIsValid () const
+ {
+ return IS_VALID_LLDB_HOST_THREAD(m_private_state_thread);
+ }
+
+ //------------------------------------------------------------------
+ // Type definitions
+ //------------------------------------------------------------------
+ typedef std::map<lldb::LanguageType, lldb::LanguageRuntimeSP> LanguageRuntimeCollection;
+
+ struct PreResumeCallbackAndBaton
+ {
+ bool (*callback) (void *);
+ void *baton;
+ PreResumeCallbackAndBaton (PreResumeActionCallback in_callback, void *in_baton) :
+ callback (in_callback),
+ baton (in_baton)
+ {
+ }
+ };
+
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ Target & m_target; ///< The target that owns this process.
+ ThreadSafeValue<lldb::StateType> m_public_state;
+ ThreadSafeValue<lldb::StateType> m_private_state; // The actual state of our process
+ Broadcaster m_private_state_broadcaster; // This broadcaster feeds state changed events into the private state thread's listener.
+ Broadcaster m_private_state_control_broadcaster; // This is the control broadcaster, used to pause, resume & stop the private state thread.
+ Listener m_private_state_listener; // This is the listener for the private state thread.
+ Predicate<bool> m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete.
+ lldb::thread_t m_private_state_thread; // Thread ID for the thread that watches interal state events
+ ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations.
+ uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is created gets a unique integer ID that increments with each new instance
+ uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index that won't get re-used.
+ std::map<uint64_t, uint32_t> m_thread_id_to_index_id_map;
+ int m_exit_status; ///< The exit status of the process, or -1 if not set.
+ std::string m_exit_string; ///< A textual description of why a process exited.
+ Mutex m_thread_mutex;
+ ThreadList m_thread_list_real; ///< The threads for this process as are known to the protocol we are debugging with
+ ThreadList m_thread_list; ///< The threads for this process as the user will see them. This is usually the same as
+ ///< m_thread_list_real, but might be different if there is an OS plug-in creating memory threads
+ std::vector<Notifications> m_notifications; ///< The list of notifications that this process can deliver.
+ std::vector<lldb::addr_t> m_image_tokens;
+ Listener &m_listener;
+ BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend to insert in the target.
+ std::unique_ptr<DynamicLoader> m_dyld_ap;
+ std::unique_ptr<DynamicCheckerFunctions> m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use.
+ std::unique_ptr<OperatingSystem> m_os_ap;
+ UnixSignals m_unix_signals; /// This is the current signal set for this process.
+ lldb::ABISP m_abi_sp;
+ lldb::InputReaderSP m_process_input_reader;
+ Communication m_stdio_communication;
+ Mutex m_stdio_communication_mutex;
+ std::string m_stdout_data;
+ std::string m_stderr_data;
+ Mutex m_profile_data_comm_mutex;
+ std::vector<std::string> m_profile_data;
+ MemoryCache m_memory_cache;
+ AllocatedMemoryCache m_allocated_memory_cache;
+ bool m_should_detach; /// Should we detach if the process object goes away with an explicit call to Kill or Detach?
+ LanguageRuntimeCollection m_language_runtimes;
+ std::unique_ptr<NextEventAction> m_next_event_action_ap;
+ std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions;
+ ProcessRunLock m_public_run_lock;
+ ProcessRunLock m_private_run_lock;
+ Predicate<bool> m_currently_handling_event; // This predicate is set in HandlePrivateEvent while all its business is being done.
+ bool m_currently_handling_do_on_removals;
+ bool m_resume_requested; // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check.
+ bool m_finalize_called;
+ bool m_clear_thread_plans_on_stop;
+ lldb::StateType m_last_broadcast_state; /// This helps with the Public event coalescing in ShouldBroadcastEvent.
+ bool m_destroy_in_process;
+
+ enum {
+ eCanJITDontKnow= 0,
+ eCanJITYes,
+ eCanJITNo
+ } m_can_jit;
+
+ size_t
+ RemoveBreakpointOpcodesFromBuffer (lldb::addr_t addr, size_t size, uint8_t *buf) const;
+
+ void
+ SynchronouslyNotifyStateChanged (lldb::StateType state);
+
+ void
+ SetPublicState (lldb::StateType new_state, bool restarted);
+
+ void
+ SetPrivateState (lldb::StateType state);
+
+ bool
+ StartPrivateStateThread (bool force = false);
+
+ void
+ StopPrivateStateThread ();
+
+ void
+ PausePrivateStateThread ();
+
+ void
+ ResumePrivateStateThread ();
+
+ static void *
+ PrivateStateThread (void *arg);
+
+ void *
+ RunPrivateStateThread ();
+
+ void
+ HandlePrivateEvent (lldb::EventSP &event_sp);
+
+ lldb::StateType
+ WaitForProcessStopPrivate (const TimeValue *timeout, lldb::EventSP &event_sp);
+
+ // This waits for both the state change broadcaster, and the control broadcaster.
+ // If control_only, it only waits for the control broadcaster.
+
+ bool
+ WaitForEventsPrivate (const TimeValue *timeout, lldb::EventSP &event_sp, bool control_only);
+
+ lldb::StateType
+ WaitForStateChangedEventsPrivate (const TimeValue *timeout, lldb::EventSP &event_sp);
+
+ lldb::StateType
+ WaitForState (const TimeValue *timeout,
+ const lldb::StateType *match_states,
+ const uint32_t num_match_states);
+
+ size_t
+ WriteMemoryPrivate (lldb::addr_t addr, const void *buf, size_t size, Error &error);
+
+ void
+ AppendSTDOUT (const char *s, size_t len);
+
+ void
+ AppendSTDERR (const char *s, size_t len);
+
+ void
+ BroadcastAsyncProfileData(const std::string &one_profile_data);
+
+ static void
+ STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
+
+ void
+ PushProcessInputReader ();
+
+ void
+ PopProcessInputReader ();
+
+ void
+ ResetProcessInputReader ();
+
+ static size_t
+ ProcessInputReaderCallback (void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+ Error
+ HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp);
+
+private:
+ //------------------------------------------------------------------
+ // For Process only
+ //------------------------------------------------------------------
+ void ControlPrivateStateThread (uint32_t signal);
+
+ DISALLOW_COPY_AND_ASSIGN (Process);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Process_h_
diff --git a/include/lldb/Target/RegisterContext.h b/include/lldb/Target/RegisterContext.h
new file mode 100644
index 000000000000..dd0e73fc7eb3
--- /dev/null
+++ b/include/lldb/Target/RegisterContext.h
@@ -0,0 +1,213 @@
+//===-- RegisterContext.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContext_h_
+#define liblldb_RegisterContext_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/ExecutionContextScope.h"
+
+namespace lldb_private {
+
+class RegisterContext :
+ public std::enable_shared_from_this<RegisterContext>,
+ public ExecutionContextScope
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ RegisterContext (Thread &thread, uint32_t concrete_frame_idx);
+
+ virtual
+ ~RegisterContext ();
+
+ void
+ InvalidateIfNeeded (bool force);
+
+ //------------------------------------------------------------------
+ // Subclasses must override these functions
+ //------------------------------------------------------------------
+ virtual void
+ InvalidateAllRegisters () = 0;
+
+ virtual size_t
+ GetRegisterCount () = 0;
+
+ virtual const RegisterInfo *
+ GetRegisterInfoAtIndex (size_t reg) = 0;
+
+ virtual size_t
+ GetRegisterSetCount () = 0;
+
+ virtual const RegisterSet *
+ GetRegisterSet (size_t reg_set) = 0;
+
+ virtual bool
+ ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) = 0;
+
+ virtual bool
+ WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) = 0;
+
+ // These two functions are used to implement "push" and "pop" of register states. They are used primarily
+ // for expression evaluation, where we need to push a new state (storing the old one in data_sp) and then
+ // restoring the original state by passing the data_sp we got from ReadAllRegisters to WriteAllRegisterValues.
+ // ReadAllRegisters will do what is necessary to return a coherent set of register values for this thread, which
+ // may mean e.g. interrupting a thread that is sitting in a kernel trap. That is a somewhat disruptive operation,
+ // so these API's should only be used when this behavior is needed.
+
+ virtual bool
+ ReadAllRegisterValues (lldb::DataBufferSP &data_sp) = 0;
+
+ virtual bool
+ WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) = 0;
+
+ bool
+ CopyFromRegisterContext (lldb::RegisterContextSP context);
+
+ virtual uint32_t
+ ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) = 0;
+
+ //------------------------------------------------------------------
+ // Subclasses can override these functions if desired
+ //------------------------------------------------------------------
+ virtual uint32_t
+ NumSupportedHardwareBreakpoints ();
+
+ virtual uint32_t
+ SetHardwareBreakpoint (lldb::addr_t addr, size_t size);
+
+ virtual bool
+ ClearHardwareBreakpoint (uint32_t hw_idx);
+
+ virtual uint32_t
+ NumSupportedHardwareWatchpoints ();
+
+ virtual uint32_t
+ SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write);
+
+ virtual bool
+ ClearHardwareWatchpoint (uint32_t hw_index);
+
+ virtual bool
+ HardwareSingleStep (bool enable);
+
+ virtual Error
+ ReadRegisterValueFromMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue &reg_value);
+
+ virtual Error
+ WriteRegisterValueToMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value);
+
+ //------------------------------------------------------------------
+ // Subclasses should not override these
+ //------------------------------------------------------------------
+ virtual lldb::tid_t
+ GetThreadID() const;
+
+ virtual Thread &
+ GetThread ()
+ {
+ return m_thread;
+ }
+
+ const RegisterInfo *
+ GetRegisterInfoByName (const char *reg_name, uint32_t start_idx = 0);
+
+ uint64_t
+ GetPC (uint64_t fail_value = LLDB_INVALID_ADDRESS);
+
+ bool
+ SetPC (uint64_t pc);
+
+ uint64_t
+ GetSP (uint64_t fail_value = LLDB_INVALID_ADDRESS);
+
+ bool
+ SetSP (uint64_t sp);
+
+ uint64_t
+ GetFP (uint64_t fail_value = LLDB_INVALID_ADDRESS);
+
+ bool
+ SetFP (uint64_t fp);
+
+ const char *
+ GetRegisterName (uint32_t reg);
+
+ uint64_t
+ GetReturnAddress (uint64_t fail_value = LLDB_INVALID_ADDRESS);
+
+ uint64_t
+ GetFlags (uint64_t fail_value = 0);
+
+ uint64_t
+ ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value);
+
+ uint64_t
+ ReadRegisterAsUnsigned (const RegisterInfo *reg_info, uint64_t fail_value);
+
+ bool
+ WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval);
+
+ bool
+ WriteRegisterFromUnsigned (const RegisterInfo *reg_info, uint64_t uval);
+ bool
+ ConvertBetweenRegisterKinds (int source_rk, uint32_t source_regnum, int target_rk, uint32_t& target_regnum);
+
+ //------------------------------------------------------------------
+ // lldb::ExecutionContextScope pure virtual functions
+ //------------------------------------------------------------------
+ virtual lldb::TargetSP
+ CalculateTarget ();
+
+ virtual lldb::ProcessSP
+ CalculateProcess ();
+
+ virtual lldb::ThreadSP
+ CalculateThread ();
+
+ virtual lldb::StackFrameSP
+ CalculateStackFrame ();
+
+ virtual void
+ CalculateExecutionContext (ExecutionContext &exe_ctx);
+
+ uint32_t
+ GetStopID () const
+ {
+ return m_stop_id;
+ }
+
+ void
+ SetStopID (uint32_t stop_id)
+ {
+ m_stop_id = stop_id;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from RegisterContext can see and modify these
+ //------------------------------------------------------------------
+ Thread &m_thread; // The thread that this register context belongs to.
+ uint32_t m_concrete_frame_idx; // The concrete frame index for this register context
+ uint32_t m_stop_id; // The stop ID that any data in this context is valid for
+private:
+ //------------------------------------------------------------------
+ // For RegisterContext only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (RegisterContext);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_RegisterContext_h_
diff --git a/include/lldb/Target/SectionLoadList.h b/include/lldb/Target/SectionLoadList.h
new file mode 100644
index 000000000000..ac05bf7a9cb4
--- /dev/null
+++ b/include/lldb/Target/SectionLoadList.h
@@ -0,0 +1,89 @@
+//===-- SectionLoadList.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SectionLoadList_h_
+#define liblldb_SectionLoadList_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+
+// Other libraries and framework includes
+#include "llvm/ADT/DenseMap.h"
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+class SectionLoadList
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SectionLoadList () :
+ m_addr_to_sect (),
+ m_sect_to_addr (),
+ m_mutex (Mutex::eMutexTypeRecursive)
+
+ {
+ }
+
+ ~SectionLoadList()
+ {
+ // Call clear since this takes a lock and clears the section load list
+ // in case another thread is currently using this section load list
+ Clear();
+ }
+
+ bool
+ IsEmpty() const;
+
+ void
+ Clear ();
+
+ lldb::addr_t
+ GetSectionLoadAddress (const lldb::SectionSP &section_sp) const;
+
+ bool
+ ResolveLoadAddress (lldb::addr_t load_addr, Address &so_addr) const;
+
+ bool
+ SetSectionLoadAddress (const lldb::SectionSP &section_sp, lldb::addr_t load_addr, bool warn_multiple = false);
+
+ // The old load address should be specified when unloading to ensure we get
+ // the correct instance of the section as a shared library could be loaded
+ // at more than one location.
+ bool
+ SetSectionUnloaded (const lldb::SectionSP &section_sp, lldb::addr_t load_addr);
+
+ // Unload all instances of a section. This function can be used on systems
+ // that don't support multiple copies of the same shared library to be
+ // loaded at the same time.
+ size_t
+ SetSectionUnloaded (const lldb::SectionSP &section_sp);
+
+ void
+ Dump (Stream &s, Target *target);
+
+protected:
+ typedef std::map<lldb::addr_t, lldb::SectionSP> addr_to_sect_collection;
+ typedef llvm::DenseMap<const Section *, lldb::addr_t> sect_to_addr_collection;
+ addr_to_sect_collection m_addr_to_sect;
+ sect_to_addr_collection m_sect_to_addr;
+ mutable Mutex m_mutex;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (SectionLoadList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_SectionLoadList_h_
diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h
new file mode 100644
index 000000000000..877bd8ce661b
--- /dev/null
+++ b/include/lldb/Target/StackFrame.h
@@ -0,0 +1,207 @@
+//===-- StackFrame.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StackFrame_h_
+#define liblldb_StackFrame_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackID.h"
+
+namespace lldb_private {
+
+class StackFrame :
+ public std::enable_shared_from_this<StackFrame>,
+ public ExecutionContextScope
+{
+public:
+ enum ExpressionPathOption
+ {
+ eExpressionPathOptionCheckPtrVsMember = (1u << 0),
+ eExpressionPathOptionsNoFragileObjcIvar = (1u << 1),
+ eExpressionPathOptionsNoSyntheticChildren = (1u << 2),
+ eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3),
+ eExpressionPathOptionsAllowDirectIVarAccess = (1u << 4)
+ };
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ StackFrame (const lldb::ThreadSP &thread_sp,
+ lldb::user_id_t frame_idx,
+ lldb::user_id_t concrete_frame_idx,
+ lldb::addr_t cfa,
+ lldb::addr_t pc,
+ const SymbolContext *sc_ptr);
+
+ StackFrame (const lldb::ThreadSP &thread_sp,
+ lldb::user_id_t frame_idx,
+ lldb::user_id_t concrete_frame_idx,
+ const lldb::RegisterContextSP &reg_context_sp,
+ lldb::addr_t cfa,
+ lldb::addr_t pc,
+ const SymbolContext *sc_ptr);
+
+ StackFrame (const lldb::ThreadSP &thread_sp,
+ lldb::user_id_t frame_idx,
+ lldb::user_id_t concrete_frame_idx,
+ const lldb::RegisterContextSP &reg_context_sp,
+ lldb::addr_t cfa,
+ const Address& pc,
+ const SymbolContext *sc_ptr);
+
+ virtual ~StackFrame ();
+
+ lldb::ThreadSP
+ GetThread () const
+ {
+ return m_thread_wp.lock();
+ }
+
+ StackID&
+ GetStackID();
+
+ const Address&
+ GetFrameCodeAddress();
+
+ void
+ ChangePC (lldb::addr_t pc);
+
+ const SymbolContext&
+ GetSymbolContext (uint32_t resolve_scope);
+
+ bool
+ GetFrameBaseValue(Scalar &value, Error *error_ptr);
+
+ Block *
+ GetFrameBlock ();
+
+ lldb::RegisterContextSP
+ GetRegisterContext ();
+
+ const lldb::RegisterContextSP &
+ GetRegisterContextSP () const
+ {
+ return m_reg_context_sp;
+ }
+
+ VariableList *
+ GetVariableList (bool get_file_globals);
+
+ lldb::VariableListSP
+ GetInScopeVariableList (bool get_file_globals);
+
+ // See ExpressionPathOption enumeration for "options" values
+ lldb::ValueObjectSP
+ GetValueForVariableExpressionPath (const char *var_expr,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t options,
+ lldb::VariableSP &var_sp,
+ Error &error);
+
+ bool
+ HasDebugInformation ();
+
+ const char *
+ Disassemble ();
+
+ void
+ DumpUsingSettingsFormat (Stream *strm);
+
+ void
+ Dump (Stream *strm, bool show_frame_index, bool show_fullpaths);
+
+ bool
+ IsInlined ();
+
+ uint32_t
+ GetFrameIndex () const;
+
+ uint32_t
+ GetConcreteFrameIndex () const
+ {
+ return m_concrete_frame_index;
+ }
+
+ lldb::ValueObjectSP
+ GetValueObjectForFrameVariable (const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic);
+
+ lldb::ValueObjectSP
+ TrackGlobalVariable (const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic);
+
+ //------------------------------------------------------------------
+ // lldb::ExecutionContextScope pure virtual functions
+ //------------------------------------------------------------------
+ virtual lldb::TargetSP
+ CalculateTarget ();
+
+ virtual lldb::ProcessSP
+ CalculateProcess ();
+
+ virtual lldb::ThreadSP
+ CalculateThread ();
+
+ virtual lldb::StackFrameSP
+ CalculateStackFrame ();
+
+ virtual void
+ CalculateExecutionContext (ExecutionContext &exe_ctx);
+
+ bool
+ GetStatus (Stream &strm,
+ bool show_frame_info,
+ bool show_source);
+
+protected:
+ friend class StackFrameList;
+
+ void
+ SetSymbolContextScope (SymbolContextScope *symbol_scope);
+
+ void
+ UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame);
+
+ void
+ UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame);
+
+ bool
+ HasCachedData () const;
+
+private:
+ //------------------------------------------------------------------
+ // For StackFrame only
+ //------------------------------------------------------------------
+ lldb::ThreadWP m_thread_wp;
+ uint32_t m_frame_index;
+ uint32_t m_concrete_frame_index;
+ lldb::RegisterContextSP m_reg_context_sp;
+ StackID m_id;
+ Address m_frame_code_addr; // The frame code address (might not be the same as the actual PC for inlined frames) as a section/offset address
+ SymbolContext m_sc;
+ Flags m_flags;
+ Scalar m_frame_base;
+ Error m_frame_base_error;
+ lldb::VariableListSP m_variable_list_sp;
+ ValueObjectList m_variable_list_value_objects; // Value objects for each variable in m_variable_list_sp
+ StreamString m_disassembly;
+ DISALLOW_COPY_AND_ASSIGN (StackFrame);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StackFrame_h_
diff --git a/include/lldb/Target/StackFrameList.h b/include/lldb/Target/StackFrameList.h
new file mode 100644
index 000000000000..b2689d0391e9
--- /dev/null
+++ b/include/lldb/Target/StackFrameList.h
@@ -0,0 +1,157 @@
+//===-- StackFrameList.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StackFrameList_h_
+#define liblldb_StackFrameList_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/StackFrame.h"
+
+namespace lldb_private {
+
+class StackFrameList
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ StackFrameList (Thread &thread,
+ const lldb::StackFrameListSP &prev_frames_sp,
+ bool show_inline_frames);
+
+ ~StackFrameList();
+
+ uint32_t
+ GetNumFrames (bool can_create = true);
+
+ lldb::StackFrameSP
+ GetFrameAtIndex (uint32_t idx);
+
+ lldb::StackFrameSP
+ GetFrameWithConcreteFrameIndex (uint32_t unwind_idx);
+
+ lldb::StackFrameSP
+ GetFrameWithStackID (const StackID &stack_id);
+
+ // Mark a stack frame as the current frame
+ uint32_t
+ SetSelectedFrame (lldb_private::StackFrame *frame);
+
+ uint32_t
+ GetSelectedFrameIndex () const;
+
+ // Mark a stack frame as the current frame using the frame index
+ bool
+ SetSelectedFrameByIndex (uint32_t idx);
+
+ uint32_t
+ GetVisibleStackFrameIndex(uint32_t idx)
+ {
+ if (m_current_inlined_depth < UINT32_MAX)
+ return idx - m_current_inlined_depth;
+ else
+ return idx;
+ }
+
+ void
+ CalculateCurrentInlinedDepth ();
+
+ void
+ SetDefaultFileAndLineToSelectedFrame();
+
+ void
+ Clear ();
+
+ void
+ InvalidateFrames (uint32_t start_idx);
+
+ void
+ Dump (Stream *s);
+
+ lldb::StackFrameSP
+ GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr);
+
+ size_t
+ GetStatus (Stream &strm,
+ uint32_t first_frame,
+ uint32_t num_frames,
+ bool show_frame_info,
+ uint32_t num_frames_with_source);
+
+protected:
+
+ friend class Thread;
+
+ bool
+ SetFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp);
+
+ static void
+ Merge (std::unique_ptr<StackFrameList>& curr_ap,
+ lldb::StackFrameListSP& prev_sp);
+
+ void
+ GetFramesUpTo (uint32_t end_idx);
+
+ bool
+ GetAllFramesFetched()
+ {
+ return m_concrete_frames_fetched == UINT32_MAX;
+ }
+
+ void
+ SetAllFramesFetched ()
+ {
+ m_concrete_frames_fetched = UINT32_MAX;
+ }
+
+ bool
+ DecrementCurrentInlinedDepth ();
+
+ void
+ ResetCurrentInlinedDepth();
+
+ uint32_t
+ GetCurrentInlinedDepth ();
+
+ void
+ SetCurrentInlinedDepth (uint32_t new_depth);
+
+ //------------------------------------------------------------------
+ // Classes that inherit from StackFrameList can see and modify these
+ //------------------------------------------------------------------
+ typedef std::vector<lldb::StackFrameSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ Thread &m_thread;
+ lldb::StackFrameListSP m_prev_frames_sp;
+ mutable Mutex m_mutex;
+ collection m_frames;
+ uint32_t m_selected_frame_idx;
+ uint32_t m_concrete_frames_fetched;
+ uint32_t m_current_inlined_depth;
+ lldb::addr_t m_current_inlined_pc;
+ bool m_show_inlined_frames;
+
+private:
+ //------------------------------------------------------------------
+ // For StackFrameList only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (StackFrameList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StackFrameList_h_
diff --git a/include/lldb/Target/StackID.h b/include/lldb/Target/StackID.h
new file mode 100644
index 000000000000..7e713c73d972
--- /dev/null
+++ b/include/lldb/Target/StackID.h
@@ -0,0 +1,149 @@
+//===-- StackID.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StackID_h_
+#define liblldb_StackID_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
+
+namespace lldb_private {
+
+class StackID
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ StackID () :
+ m_pc (LLDB_INVALID_ADDRESS),
+ m_cfa (LLDB_INVALID_ADDRESS),
+ m_symbol_scope (NULL)
+ {
+ }
+
+ explicit
+ StackID (lldb::addr_t pc, lldb::addr_t cfa, SymbolContextScope *symbol_scope) :
+ m_pc (pc),
+ m_cfa (cfa),
+ m_symbol_scope (symbol_scope)
+ {
+ }
+
+ StackID (const StackID& rhs) :
+ m_pc (rhs.m_pc),
+ m_cfa (rhs.m_cfa),
+ m_symbol_scope (rhs.m_symbol_scope)
+ {
+ }
+
+ ~StackID()
+ {
+ }
+
+ lldb::addr_t
+ GetPC() const
+ {
+ return m_pc;
+ }
+
+ lldb::addr_t
+ GetCallFrameAddress() const
+ {
+ return m_cfa;
+ }
+
+ SymbolContextScope *
+ GetSymbolContextScope () const
+ {
+ return m_symbol_scope;
+ }
+
+ void
+ SetSymbolContextScope (SymbolContextScope *symbol_scope)
+ {
+ m_symbol_scope = symbol_scope;
+ }
+
+ void
+ Clear ()
+ {
+ m_pc = LLDB_INVALID_ADDRESS;
+ m_cfa = LLDB_INVALID_ADDRESS;
+ m_symbol_scope = NULL;
+ }
+
+ bool
+ IsValid () const
+ {
+ return m_pc != LLDB_INVALID_ADDRESS || m_cfa != LLDB_INVALID_ADDRESS;
+ }
+
+ void
+ Dump (Stream *s);
+
+ //------------------------------------------------------------------
+ // Operators
+ //------------------------------------------------------------------
+ const StackID&
+ operator=(const StackID& rhs)
+ {
+ if (this != &rhs)
+ {
+ m_pc = rhs.m_pc;
+ m_cfa = rhs.m_cfa;
+ m_symbol_scope = rhs.m_symbol_scope;
+ }
+ return *this;
+ }
+
+protected:
+
+ friend class StackFrame;
+
+ void
+ SetPC (lldb::addr_t pc)
+ {
+ m_pc = pc;
+ }
+
+
+ //------------------------------------------------------------------
+ // Classes that inherit from StackID can see and modify these
+ //------------------------------------------------------------------
+ lldb::addr_t m_pc; // The pc value for the function/symbol for this frame. This will
+ // only get used if the symbol scope is NULL (the code where we are
+ // stopped is not represented by any function or symbol in any
+ // shared library).
+ lldb::addr_t m_cfa; // The call frame address (stack pointer) value
+ // at the beginning of the function that uniquely
+ // identifies this frame (along with m_symbol_scope below)
+ SymbolContextScope *m_symbol_scope; // If NULL, there is no block or symbol for this frame.
+ // If not NULL, this will either be the scope for the
+ // lexical block for the frame, or the scope
+ // for the symbol. Symbol context scopes are
+ // always be unique pointers since the are part
+ // of the Block and Symbol objects and can easily
+ // be used to tell if a stack ID is the same as
+ // another.
+};
+
+bool operator== (const StackID& lhs, const StackID& rhs);
+bool operator!= (const StackID& lhs, const StackID& rhs);
+
+// frame_id_1 < frame_id_2 means "frame_id_1 is YOUNGER than frame_id_2"
+bool operator< (const StackID& lhs, const StackID& rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_StackID_h_
diff --git a/include/lldb/Target/StopInfo.h b/include/lldb/Target/StopInfo.h
new file mode 100644
index 000000000000..3435d392e2b9
--- /dev/null
+++ b/include/lldb/Target/StopInfo.h
@@ -0,0 +1,227 @@
+//===-- StopInfo.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StopInfo_h_
+#define liblldb_StopInfo_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Target/Process.h"
+
+namespace lldb_private {
+
+class StopInfo
+{
+ friend class Process::ProcessEventData;
+ friend class ThreadPlanBase;
+
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ StopInfo (Thread &thread, uint64_t value);
+
+ virtual ~StopInfo()
+ {
+ }
+
+
+ bool
+ IsValid () const;
+
+ void
+ SetThread (const lldb::ThreadSP &thread_sp)
+ {
+ m_thread_wp = thread_sp;
+ }
+
+ lldb::ThreadSP
+ GetThread() const
+ {
+ return m_thread_wp.lock();
+ }
+
+ // The value of the StopInfo depends on the StopReason.
+ // StopReason Meaning
+ // ----------------------------------------------
+ // eStopReasonBreakpoint BreakpointSiteID
+ // eStopReasonSignal Signal number
+ // eStopReasonWatchpoint WatchpointLocationID
+ // eStopReasonPlanComplete No significance
+
+ uint64_t
+ GetValue() const
+ {
+ return m_value;
+ }
+
+ virtual lldb::StopReason
+ GetStopReason () const = 0;
+
+ // ShouldStopSynchronous will get called before any thread plans are consulted, and if it says we should
+ // resume the target, then we will just immediately resume. This should not run any code in or resume the
+ // target.
+
+ virtual bool
+ ShouldStopSynchronous (Event *event_ptr)
+ {
+ return true;
+ }
+
+ void
+ OverrideShouldNotify (bool override_value)
+ {
+ m_override_should_notify = override_value ? eLazyBoolYes : eLazyBoolNo;
+ }
+
+ // If should stop returns false, check if we should notify of this event
+ virtual bool
+ ShouldNotify (Event *event_ptr)
+ {
+ if (m_override_should_notify == eLazyBoolCalculate)
+ return DoShouldNotify (event_ptr);
+ else
+ return m_override_should_notify == eLazyBoolYes;
+ }
+
+ virtual void
+ WillResume (lldb::StateType resume_state)
+ {
+ // By default, don't do anything
+ }
+
+ virtual const char *
+ GetDescription ()
+ {
+ return m_description.c_str();
+ }
+
+ virtual void
+ SetDescription (const char *desc_cstr)
+ {
+ if (desc_cstr && desc_cstr[0])
+ m_description.assign (desc_cstr);
+ else
+ m_description.clear();
+ }
+
+ // Sometimes the thread plan logic will know that it wants a given stop to stop or not,
+ // regardless of what the ordinary logic for that StopInfo would dictate. The main example
+ // of this is the ThreadPlanCallFunction, which for instance knows - based on how that particular
+ // expression was executed - whether it wants all breakpoints to auto-continue or not.
+ // Use OverrideShouldStop on the StopInfo to implement this.
+
+ void
+ OverrideShouldStop (bool override_value)
+ {
+ m_override_should_stop = override_value ? eLazyBoolYes : eLazyBoolNo;
+ }
+
+ bool
+ GetOverrideShouldStop()
+ {
+ return m_override_should_stop != eLazyBoolCalculate;
+ }
+
+ bool
+ GetOverriddenShouldStopValue ()
+ {
+ return m_override_should_stop == eLazyBoolYes;
+ }
+
+ static lldb::StopInfoSP
+ CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id);
+
+ // This creates a StopInfo for the thread where the should_stop is already set, and won't be recalculated.
+ static lldb::StopInfoSP
+ CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id, bool should_stop);
+
+ static lldb::StopInfoSP
+ CreateStopReasonWithWatchpointID (Thread &thread, lldb::break_id_t watch_id);
+
+ static lldb::StopInfoSP
+ CreateStopReasonWithSignal (Thread &thread, int signo);
+
+ static lldb::StopInfoSP
+ CreateStopReasonToTrace (Thread &thread);
+
+ static lldb::StopInfoSP
+ CreateStopReasonWithPlan (lldb::ThreadPlanSP &plan, lldb::ValueObjectSP return_valobj_sp);
+
+ static lldb::StopInfoSP
+ CreateStopReasonWithException (Thread &thread, const char *description);
+
+ static lldb::StopInfoSP
+ CreateStopReasonWithExec (Thread &thread);
+
+ static lldb::ValueObjectSP
+ GetReturnValueObject (lldb::StopInfoSP &stop_info_sp);
+
+protected:
+ // Perform any action that is associated with this stop. This is done as the
+ // Event is removed from the event queue. ProcessEventData::DoOnRemoval does the job.
+
+ virtual void
+ PerformAction (Event *event_ptr)
+ {
+ }
+
+ virtual bool
+ DoShouldNotify (Event *event_ptr)
+ {
+ return false;
+ }
+
+ // Stop the thread by default. Subclasses can override this to allow
+ // the thread to continue if desired. The ShouldStop method should not do anything
+ // that might run code. If you need to run code when deciding whether to stop
+ // at this StopInfo, that must be done in the PerformAction.
+ // The PerformAction will always get called before the ShouldStop. This is done by the
+ // ProcessEventData::DoOnRemoval, though the ThreadPlanBase needs to consult this later on.
+ virtual bool
+ ShouldStop (Event *event_ptr)
+ {
+ return true;
+ }
+
+ //------------------------------------------------------------------
+ // Classes that inherit from StackID can see and modify these
+ //------------------------------------------------------------------
+ lldb::ThreadWP m_thread_wp; // The thread corresponding to the stop reason.
+ uint32_t m_stop_id; // The process stop ID for which this stop info is valid
+ uint32_t m_resume_id; // This is the resume ID when we made this stop ID.
+ uint64_t m_value; // A generic value that can be used for things pertaining to this stop info
+ std::string m_description; // A textual description describing this stop.
+ LazyBool m_override_should_notify;
+ LazyBool m_override_should_stop;
+
+ // This determines whether the target has run since this stop info.
+ // N.B. running to evaluate a user expression does not count.
+ bool HasTargetRunSinceMe ();
+
+ // MakeStopInfoValid is necessary to allow saved stop infos to resurrect themselves as valid.
+ // It should only be used by Thread::RestoreThreadStateFromCheckpoint and to make sure the one-step
+ // needed for before-the-fact watchpoints does not prevent us from stopping
+ void
+ MakeStopInfoValid ();
+
+private:
+ friend class Thread;
+
+ DISALLOW_COPY_AND_ASSIGN (StopInfo);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StopInfo_h_
diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h
new file mode 100644
index 000000000000..87fa57b3a299
--- /dev/null
+++ b/include/lldb/Target/Target.h
@@ -0,0 +1,1223 @@
+//===-- Target.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Target_h_
+#define liblldb_Target_h_
+
+// C Includes
+// C++ Includes
+#include <list>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Breakpoint/BreakpointList.h"
+#include "lldb/Breakpoint/BreakpointLocationCollection.h"
+#include "lldb/Breakpoint/WatchpointList.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/Event.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueEnumeration.h"
+#include "lldb/Interpreter/OptionValueFileSpec.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/PathMappingList.h"
+#include "lldb/Target/SectionLoadList.h"
+
+namespace lldb_private {
+
+extern OptionEnumValueElement g_dynamic_value_types[];
+
+typedef enum InlineStrategy
+{
+ eInlineBreakpointsNever = 0,
+ eInlineBreakpointsHeaders,
+ eInlineBreakpointsAlways
+} InlineStrategy;
+
+typedef enum LoadScriptFromSymFile
+{
+ eLoadScriptFromSymFileTrue,
+ eLoadScriptFromSymFileFalse,
+ eLoadScriptFromSymFileWarn
+} LoadScriptFromSymFile;
+
+//----------------------------------------------------------------------
+// TargetProperties
+//----------------------------------------------------------------------
+class TargetProperties : public Properties
+{
+public:
+ TargetProperties(Target *target);
+
+ virtual
+ ~TargetProperties();
+
+ ArchSpec
+ GetDefaultArchitecture () const;
+
+ void
+ SetDefaultArchitecture (const ArchSpec& arch);
+
+ lldb::DynamicValueType
+ GetPreferDynamicValue() const;
+
+ bool
+ GetDisableASLR () const;
+
+ void
+ SetDisableASLR (bool b);
+
+ bool
+ GetDisableSTDIO () const;
+
+ void
+ SetDisableSTDIO (bool b);
+
+ const char *
+ GetDisassemblyFlavor() const;
+
+// void
+// SetDisassemblyFlavor(const char *flavor);
+
+ InlineStrategy
+ GetInlineStrategy () const;
+
+ const char *
+ GetArg0 () const;
+
+ void
+ SetArg0 (const char *arg);
+
+ bool
+ GetRunArguments (Args &args) const;
+
+ void
+ SetRunArguments (const Args &args);
+
+ size_t
+ GetEnvironmentAsArgs (Args &env) const;
+
+ bool
+ GetSkipPrologue() const;
+
+ PathMappingList &
+ GetSourcePathMap () const;
+
+ FileSpecList &
+ GetExecutableSearchPaths ();
+
+ FileSpecList &
+ GetDebugFileSearchPaths ();
+
+ bool
+ GetEnableSyntheticValue () const;
+
+ uint32_t
+ GetMaximumNumberOfChildrenToDisplay() const;
+
+ uint32_t
+ GetMaximumSizeOfStringSummary() const;
+
+ uint32_t
+ GetMaximumMemReadSize () const;
+
+ FileSpec
+ GetStandardInputPath () const;
+
+ void
+ SetStandardInputPath (const char *path);
+
+ FileSpec
+ GetStandardOutputPath () const;
+
+ void
+ SetStandardOutputPath (const char *path);
+
+ FileSpec
+ GetStandardErrorPath () const;
+
+ void
+ SetStandardErrorPath (const char *path);
+
+ bool
+ GetBreakpointsConsultPlatformAvoidList ();
+
+ const char *
+ GetExpressionPrefixContentsAsCString ();
+
+ bool
+ GetUseHexImmediates() const;
+
+ bool
+ GetUseFastStepping() const;
+
+ LoadScriptFromSymFile
+ GetLoadScriptFromSymbolFile() const;
+
+ Disassembler::HexImmediateStyle
+ GetHexImmediateStyle() const;
+
+ MemoryModuleLoadLevel
+ GetMemoryModuleLoadLevel() const;
+
+};
+
+typedef std::shared_ptr<TargetProperties> TargetPropertiesSP;
+
+class EvaluateExpressionOptions
+{
+public:
+ static const uint32_t default_timeout = 500000;
+ EvaluateExpressionOptions() :
+ m_execution_policy(eExecutionPolicyOnlyWhenNeeded),
+ m_coerce_to_id(false),
+ m_unwind_on_error(true),
+ m_ignore_breakpoints (false),
+ m_keep_in_memory(false),
+ m_run_others(true),
+ m_use_dynamic(lldb::eNoDynamicValues),
+ m_timeout_usec(default_timeout)
+ {}
+
+ ExecutionPolicy
+ GetExecutionPolicy () const
+ {
+ return m_execution_policy;
+ }
+
+ EvaluateExpressionOptions&
+ SetExecutionPolicy (ExecutionPolicy policy = eExecutionPolicyAlways)
+ {
+ m_execution_policy = policy;
+ return *this;
+ }
+
+ bool
+ DoesCoerceToId () const
+ {
+ return m_coerce_to_id;
+ }
+
+ EvaluateExpressionOptions&
+ SetCoerceToId (bool coerce = true)
+ {
+ m_coerce_to_id = coerce;
+ return *this;
+ }
+
+ bool
+ DoesUnwindOnError () const
+ {
+ return m_unwind_on_error;
+ }
+
+ EvaluateExpressionOptions&
+ SetUnwindOnError (bool unwind = false)
+ {
+ m_unwind_on_error = unwind;
+ return *this;
+ }
+
+ bool
+ DoesIgnoreBreakpoints () const
+ {
+ return m_ignore_breakpoints;
+ }
+
+ EvaluateExpressionOptions&
+ SetIgnoreBreakpoints (bool ignore = false)
+ {
+ m_ignore_breakpoints = ignore;
+ return *this;
+ }
+
+ bool
+ DoesKeepInMemory () const
+ {
+ return m_keep_in_memory;
+ }
+
+ EvaluateExpressionOptions&
+ SetKeepInMemory (bool keep = true)
+ {
+ m_keep_in_memory = keep;
+ return *this;
+ }
+
+ lldb::DynamicValueType
+ GetUseDynamic () const
+ {
+ return m_use_dynamic;
+ }
+
+ EvaluateExpressionOptions&
+ SetUseDynamic (lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget)
+ {
+ m_use_dynamic = dynamic;
+ return *this;
+ }
+
+ uint32_t
+ GetTimeoutUsec () const
+ {
+ return m_timeout_usec;
+ }
+
+ EvaluateExpressionOptions&
+ SetTimeoutUsec (uint32_t timeout = 0)
+ {
+ m_timeout_usec = timeout;
+ return *this;
+ }
+
+ bool
+ GetRunOthers () const
+ {
+ return m_run_others;
+ }
+
+ EvaluateExpressionOptions&
+ SetRunOthers (bool run_others = true)
+ {
+ m_run_others = run_others;
+ return *this;
+ }
+
+private:
+ ExecutionPolicy m_execution_policy;
+ bool m_coerce_to_id;
+ bool m_unwind_on_error;
+ bool m_ignore_breakpoints;
+ bool m_keep_in_memory;
+ bool m_run_others;
+ lldb::DynamicValueType m_use_dynamic;
+ uint32_t m_timeout_usec;
+};
+
+//----------------------------------------------------------------------
+// Target
+//----------------------------------------------------------------------
+class Target :
+ public std::enable_shared_from_this<Target>,
+ public TargetProperties,
+ public Broadcaster,
+ public ExecutionContextScope,
+ public ModuleList::Notifier
+{
+public:
+ friend class TargetList;
+
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ enum
+ {
+ eBroadcastBitBreakpointChanged = (1 << 0),
+ eBroadcastBitModulesLoaded = (1 << 1),
+ eBroadcastBitModulesUnloaded = (1 << 2),
+ eBroadcastBitWatchpointChanged = (1 << 3),
+ eBroadcastBitSymbolsLoaded = (1 << 4)
+ };
+
+ // These two functions fill out the Broadcaster interface:
+
+ static ConstString &GetStaticBroadcasterClass ();
+
+ virtual ConstString &GetBroadcasterClass() const
+ {
+ return GetStaticBroadcasterClass();
+ }
+
+ // This event data class is for use by the TargetList to broadcast new target notifications.
+ class TargetEventData : public EventData
+ {
+ public:
+
+ static const ConstString &
+ GetFlavorString ();
+
+ virtual const ConstString &
+ GetFlavor () const;
+
+ TargetEventData (const lldb::TargetSP &new_target_sp);
+
+ lldb::TargetSP &
+ GetTarget()
+ {
+ return m_target_sp;
+ }
+
+ virtual
+ ~TargetEventData();
+
+ virtual void
+ Dump (Stream *s) const;
+
+ static const lldb::TargetSP
+ GetTargetFromEvent (const lldb::EventSP &event_sp);
+
+ static const TargetEventData *
+ GetEventDataFromEvent (const Event *event_sp);
+
+ private:
+ lldb::TargetSP m_target_sp;
+
+ DISALLOW_COPY_AND_ASSIGN (TargetEventData);
+ };
+
+ static void
+ SettingsInitialize ();
+
+ static void
+ SettingsTerminate ();
+
+// static lldb::UserSettingsControllerSP &
+// GetSettingsController ();
+
+ static FileSpecList
+ GetDefaultExecutableSearchPaths ();
+
+ static FileSpecList
+ GetDefaultDebugFileSearchPaths ();
+
+ static ArchSpec
+ GetDefaultArchitecture ();
+
+ static void
+ SetDefaultArchitecture (const ArchSpec &arch);
+
+// void
+// UpdateInstanceName ();
+
+ lldb::ModuleSP
+ GetSharedModule (const ModuleSpec &module_spec,
+ Error *error_ptr = NULL);
+
+ //----------------------------------------------------------------------
+ // Settings accessors
+ //----------------------------------------------------------------------
+
+ static const TargetPropertiesSP &
+ GetGlobalProperties();
+
+
+private:
+ //------------------------------------------------------------------
+ /// Construct with optional file and arch.
+ ///
+ /// This member is private. Clients must use
+ /// TargetList::CreateTarget(const FileSpec*, const ArchSpec*)
+ /// so all targets can be tracked from the central target list.
+ ///
+ /// @see TargetList::CreateTarget(const FileSpec*, const ArchSpec*)
+ //------------------------------------------------------------------
+ Target (Debugger &debugger,
+ const ArchSpec &target_arch,
+ const lldb::PlatformSP &platform_sp);
+
+ // Helper function.
+ bool
+ ProcessIsValid ();
+
+public:
+ ~Target();
+
+ Mutex &
+ GetAPIMutex ()
+ {
+ return m_mutex;
+ }
+
+ void
+ DeleteCurrentProcess ();
+
+ void
+ CleanupProcess ();
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s. The dumped content will be only what has
+ /// been loaded or parsed up to this point at which this function
+ /// is called, so this is a good way to see what has been parsed
+ /// in a target.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, lldb::DescriptionLevel description_level);
+
+ const lldb::ProcessSP &
+ CreateProcess (Listener &listener,
+ const char *plugin_name,
+ const FileSpec *crash_file);
+
+ const lldb::ProcessSP &
+ GetProcessSP () const;
+
+ bool
+ IsValid()
+ {
+ return m_valid;
+ }
+
+ void
+ Destroy();
+
+ //------------------------------------------------------------------
+ // This part handles the breakpoints.
+ //------------------------------------------------------------------
+
+ BreakpointList &
+ GetBreakpointList(bool internal = false);
+
+ const BreakpointList &
+ GetBreakpointList(bool internal = false) const;
+
+ lldb::BreakpointSP
+ GetLastCreatedBreakpoint ()
+ {
+ return m_last_created_breakpoint;
+ }
+
+ lldb::BreakpointSP
+ GetBreakpointByID (lldb::break_id_t break_id);
+
+ // Use this to create a file and line breakpoint to a given module or all module it is NULL
+ lldb::BreakpointSP
+ CreateBreakpoint (const FileSpecList *containingModules,
+ const FileSpec &file,
+ uint32_t line_no,
+ LazyBool check_inlines = eLazyBoolCalculate,
+ LazyBool skip_prologue = eLazyBoolCalculate,
+ bool internal = false);
+
+ // Use this to create breakpoint that matches regex against the source lines in files given in source_file_list:
+ lldb::BreakpointSP
+ CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
+ const FileSpecList *source_file_list,
+ RegularExpression &source_regex,
+ bool internal = false);
+
+ // Use this to create a breakpoint from a load address
+ lldb::BreakpointSP
+ CreateBreakpoint (lldb::addr_t load_addr,
+ bool internal = false);
+
+ // Use this to create Address breakpoints:
+ lldb::BreakpointSP
+ CreateBreakpoint (Address &addr,
+ bool internal = false);
+
+ // Use this to create a function breakpoint by regexp in containingModule/containingSourceFiles, or all modules if it is NULL
+ // When "skip_prologue is set to eLazyBoolCalculate, we use the current target
+ // setting, else we use the values passed in
+ lldb::BreakpointSP
+ CreateFuncRegexBreakpoint (const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles,
+ RegularExpression &func_regexp,
+ LazyBool skip_prologue = eLazyBoolCalculate,
+ bool internal = false);
+
+ // Use this to create a function breakpoint by name in containingModule, or all modules if it is NULL
+ // When "skip_prologue is set to eLazyBoolCalculate, we use the current target
+ // setting, else we use the values passed in
+ lldb::BreakpointSP
+ CreateBreakpoint (const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles,
+ const char *func_name,
+ uint32_t func_name_type_mask,
+ LazyBool skip_prologue = eLazyBoolCalculate,
+ bool internal = false);
+
+ lldb::BreakpointSP
+ CreateExceptionBreakpoint (enum lldb::LanguageType language, bool catch_bp, bool throw_bp, bool internal = false);
+
+ // This is the same as the func_name breakpoint except that you can specify a vector of names. This is cheaper
+ // than a regular expression breakpoint in the case where you just want to set a breakpoint on a set of names
+ // you already know.
+ lldb::BreakpointSP
+ CreateBreakpoint (const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles,
+ const char *func_names[],
+ size_t num_names,
+ uint32_t func_name_type_mask,
+ LazyBool skip_prologue = eLazyBoolCalculate,
+ bool internal = false);
+
+ lldb::BreakpointSP
+ CreateBreakpoint (const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles,
+ const std::vector<std::string> &func_names,
+ uint32_t func_name_type_mask,
+ LazyBool skip_prologue = eLazyBoolCalculate,
+ bool internal = false);
+
+
+ // Use this to create a general breakpoint:
+ lldb::BreakpointSP
+ CreateBreakpoint (lldb::SearchFilterSP &filter_sp,
+ lldb::BreakpointResolverSP &resolver_sp,
+ bool internal = false);
+
+ // Use this to create a watchpoint:
+ lldb::WatchpointSP
+ CreateWatchpoint (lldb::addr_t addr,
+ size_t size,
+ const ClangASTType *type,
+ uint32_t kind,
+ Error &error);
+
+ lldb::WatchpointSP
+ GetLastCreatedWatchpoint ()
+ {
+ return m_last_created_watchpoint;
+ }
+
+ WatchpointList &
+ GetWatchpointList()
+ {
+ return m_watchpoint_list;
+ }
+
+ void
+ RemoveAllBreakpoints (bool internal_also = false);
+
+ void
+ DisableAllBreakpoints (bool internal_also = false);
+
+ void
+ EnableAllBreakpoints (bool internal_also = false);
+
+ bool
+ DisableBreakpointByID (lldb::break_id_t break_id);
+
+ bool
+ EnableBreakpointByID (lldb::break_id_t break_id);
+
+ bool
+ RemoveBreakpointByID (lldb::break_id_t break_id);
+
+ // The flag 'end_to_end', default to true, signifies that the operation is
+ // performed end to end, for both the debugger and the debuggee.
+
+ bool
+ RemoveAllWatchpoints (bool end_to_end = true);
+
+ bool
+ DisableAllWatchpoints (bool end_to_end = true);
+
+ bool
+ EnableAllWatchpoints (bool end_to_end = true);
+
+ bool
+ ClearAllWatchpointHitCounts ();
+
+ bool
+ IgnoreAllWatchpoints (uint32_t ignore_count);
+
+ bool
+ DisableWatchpointByID (lldb::watch_id_t watch_id);
+
+ bool
+ EnableWatchpointByID (lldb::watch_id_t watch_id);
+
+ bool
+ RemoveWatchpointByID (lldb::watch_id_t watch_id);
+
+ bool
+ IgnoreWatchpointByID (lldb::watch_id_t watch_id, uint32_t ignore_count);
+
+ //------------------------------------------------------------------
+ /// Get \a load_addr as a callable code load address for this target
+ ///
+ /// Take \a load_addr and potentially add any address bits that are
+ /// needed to make the address callable. For ARM this can set bit
+ /// zero (if it already isn't) if \a load_addr is a thumb function.
+ /// If \a addr_class is set to eAddressClassInvalid, then the address
+ /// adjustment will always happen. If it is set to an address class
+ /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be
+ /// returned.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetCallableLoadAddress (lldb::addr_t load_addr, lldb::AddressClass addr_class = lldb::eAddressClassInvalid) const;
+
+ //------------------------------------------------------------------
+ /// Get \a load_addr as an opcode for this target.
+ ///
+ /// Take \a load_addr and potentially strip any address bits that are
+ /// needed to make the address point to an opcode. For ARM this can
+ /// clear bit zero (if it already isn't) if \a load_addr is a
+ /// thumb function and load_addr is in code.
+ /// If \a addr_class is set to eAddressClassInvalid, then the address
+ /// adjustment will always happen. If it is set to an address class
+ /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be
+ /// returned.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetOpcodeLoadAddress (lldb::addr_t load_addr, lldb::AddressClass addr_class = lldb::eAddressClassInvalid) const;
+
+protected:
+ //------------------------------------------------------------------
+ /// Implementing of ModuleList::Notifier.
+ //------------------------------------------------------------------
+
+ virtual void
+ ModuleAdded (const ModuleList& module_list, const lldb::ModuleSP& module_sp);
+
+ virtual void
+ ModuleRemoved (const ModuleList& module_list, const lldb::ModuleSP& module_sp);
+
+ virtual void
+ ModuleUpdated (const ModuleList& module_list,
+ const lldb::ModuleSP& old_module_sp,
+ const lldb::ModuleSP& new_module_sp);
+ virtual void
+ WillClearList (const ModuleList& module_list);
+
+public:
+
+ void
+ ModulesDidLoad (ModuleList &module_list);
+
+ void
+ ModulesDidUnload (ModuleList &module_list);
+
+ void
+ SymbolsDidLoad (ModuleList &module_list);
+
+ //------------------------------------------------------------------
+ /// Gets the module for the main executable.
+ ///
+ /// Each process has a notion of a main executable that is the file
+ /// that will be executed or attached to. Executable files can have
+ /// dependent modules that are discovered from the object files, or
+ /// discovered at runtime as things are dynamically loaded.
+ ///
+ /// @return
+ /// The shared pointer to the executable module which can
+ /// contains a NULL Module object if no executable has been
+ /// set.
+ ///
+ /// @see DynamicLoader
+ /// @see ObjectFile::GetDependentModules (FileSpecList&)
+ /// @see Process::SetExecutableModule(lldb::ModuleSP&)
+ //------------------------------------------------------------------
+ lldb::ModuleSP
+ GetExecutableModule ();
+
+ Module*
+ GetExecutableModulePointer ();
+
+ //------------------------------------------------------------------
+ /// Set the main executable module.
+ ///
+ /// Each process has a notion of a main executable that is the file
+ /// that will be executed or attached to. Executable files can have
+ /// dependent modules that are discovered from the object files, or
+ /// discovered at runtime as things are dynamically loaded.
+ ///
+ /// Setting the executable causes any of the current dependant
+ /// image information to be cleared and replaced with the static
+ /// dependent image information found by calling
+ /// ObjectFile::GetDependentModules (FileSpecList&) on the main
+ /// executable and any modules on which it depends. Calling
+ /// Process::GetImages() will return the newly found images that
+ /// were obtained from all of the object files.
+ ///
+ /// @param[in] module_sp
+ /// A shared pointer reference to the module that will become
+ /// the main executable for this process.
+ ///
+ /// @param[in] get_dependent_files
+ /// If \b true then ask the object files to track down any
+ /// known dependent files.
+ ///
+ /// @see ObjectFile::GetDependentModules (FileSpecList&)
+ /// @see Process::GetImages()
+ //------------------------------------------------------------------
+ void
+ SetExecutableModule (lldb::ModuleSP& module_sp, bool get_dependent_files);
+
+ bool
+ LoadScriptingResources (std::list<Error>& errors,
+ Stream* feedback_stream = NULL,
+ bool continue_on_error = true)
+ {
+ return m_images.LoadScriptingResourcesInTarget(this,errors,feedback_stream,continue_on_error);
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor for the images for this process.
+ ///
+ /// Each process has a notion of a main executable that is the file
+ /// that will be executed or attached to. Executable files can have
+ /// dependent modules that are discovered from the object files, or
+ /// discovered at runtime as things are dynamically loaded. After
+ /// a main executable has been set, the images will contain a list
+ /// of all the files that the executable depends upon as far as the
+ /// object files know. These images will usually contain valid file
+ /// virtual addresses only. When the process is launched or attached
+ /// to, the DynamicLoader plug-in will discover where these images
+ /// were loaded in memory and will resolve the load virtual
+ /// addresses is each image, and also in images that are loaded by
+ /// code.
+ ///
+ /// @return
+ /// A list of Module objects in a module list.
+ //------------------------------------------------------------------
+ const ModuleList&
+ GetImages () const
+ {
+ return m_images;
+ }
+
+ ModuleList&
+ GetImages ()
+ {
+ return m_images;
+ }
+
+ //------------------------------------------------------------------
+ /// Return whether this FileSpec corresponds to a module that should be considered for general searches.
+ ///
+ /// This API will be consulted by the SearchFilterForNonModuleSpecificSearches
+ /// and any module that returns \b true will not be searched. Note the
+ /// SearchFilterForNonModuleSpecificSearches is the search filter that
+ /// gets used in the CreateBreakpoint calls when no modules is provided.
+ ///
+ /// The target call at present just consults the Platform's call of the
+ /// same name.
+ ///
+ /// @param[in] module_sp
+ /// A shared pointer reference to the module that checked.
+ ///
+ /// @return \b true if the module should be excluded, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ModuleIsExcludedForNonModuleSpecificSearches (const FileSpec &module_spec);
+
+ //------------------------------------------------------------------
+ /// Return whether this module should be considered for general searches.
+ ///
+ /// This API will be consulted by the SearchFilterForNonModuleSpecificSearches
+ /// and any module that returns \b true will not be searched. Note the
+ /// SearchFilterForNonModuleSpecificSearches is the search filter that
+ /// gets used in the CreateBreakpoint calls when no modules is provided.
+ ///
+ /// The target call at present just consults the Platform's call of the
+ /// same name.
+ ///
+ /// FIXME: When we get time we should add a way for the user to set modules that they
+ /// don't want searched, in addition to or instead of the platform ones.
+ ///
+ /// @param[in] module_sp
+ /// A shared pointer reference to the module that checked.
+ ///
+ /// @return \b true if the module should be excluded, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ModuleIsExcludedForNonModuleSpecificSearches (const lldb::ModuleSP &module_sp);
+
+ ArchSpec &
+ GetArchitecture ()
+ {
+ return m_arch;
+ }
+
+ const ArchSpec &
+ GetArchitecture () const
+ {
+ return m_arch;
+ }
+
+ //------------------------------------------------------------------
+ /// Set the architecture for this target.
+ ///
+ /// If the current target has no Images read in, then this just sets the architecture, which will
+ /// be used to select the architecture of the ExecutableModule when that is set.
+ /// If the current target has an ExecutableModule, then calling SetArchitecture with a different
+ /// architecture from the currently selected one will reset the ExecutableModule to that slice
+ /// of the file backing the ExecutableModule. If the file backing the ExecutableModule does not
+ /// contain a fork of this architecture, then this code will return false, and the architecture
+ /// won't be changed.
+ /// If the input arch_spec is the same as the already set architecture, this is a no-op.
+ ///
+ /// @param[in] arch_spec
+ /// The new architecture.
+ ///
+ /// @return
+ /// \b true if the architecture was successfully set, \bfalse otherwise.
+ //------------------------------------------------------------------
+ bool
+ SetArchitecture (const ArchSpec &arch_spec);
+
+ Debugger &
+ GetDebugger ()
+ {
+ return m_debugger;
+ }
+
+ size_t
+ ReadMemoryFromFileCache (const Address& addr,
+ void *dst,
+ size_t dst_len,
+ Error &error);
+
+ // Reading memory through the target allows us to skip going to the process
+ // for reading memory if possible and it allows us to try and read from
+ // any constant sections in our object files on disk. If you always want
+ // live program memory, read straight from the process. If you possibly
+ // want to read from const sections in object files, read from the target.
+ // This version of ReadMemory will try and read memory from the process
+ // if the process is alive. The order is:
+ // 1 - if (prefer_file_cache == true) then read from object file cache
+ // 2 - if there is a valid process, try and read from its memory
+ // 3 - if (prefer_file_cache == false) then read from object file cache
+ size_t
+ ReadMemory (const Address& addr,
+ bool prefer_file_cache,
+ void *dst,
+ size_t dst_len,
+ Error &error,
+ lldb::addr_t *load_addr_ptr = NULL);
+
+ size_t
+ ReadCStringFromMemory (const Address& addr, std::string &out_str, Error &error);
+
+ size_t
+ ReadCStringFromMemory (const Address& addr, char *dst, size_t dst_max_len, Error &result_error);
+
+ size_t
+ ReadScalarIntegerFromMemory (const Address& addr,
+ bool prefer_file_cache,
+ uint32_t byte_size,
+ bool is_signed,
+ Scalar &scalar,
+ Error &error);
+
+ uint64_t
+ ReadUnsignedIntegerFromMemory (const Address& addr,
+ bool prefer_file_cache,
+ size_t integer_byte_size,
+ uint64_t fail_value,
+ Error &error);
+
+ bool
+ ReadPointerFromMemory (const Address& addr,
+ bool prefer_file_cache,
+ Error &error,
+ Address &pointer_addr);
+
+ SectionLoadList&
+ GetSectionLoadList()
+ {
+ return m_section_load_list;
+ }
+
+ const SectionLoadList&
+ GetSectionLoadList() const
+ {
+ return m_section_load_list;
+ }
+
+ static Target *
+ GetTargetFromContexts (const ExecutionContext *exe_ctx_ptr,
+ const SymbolContext *sc_ptr);
+
+ //------------------------------------------------------------------
+ // lldb::ExecutionContextScope pure virtual functions
+ //------------------------------------------------------------------
+ virtual lldb::TargetSP
+ CalculateTarget ();
+
+ virtual lldb::ProcessSP
+ CalculateProcess ();
+
+ virtual lldb::ThreadSP
+ CalculateThread ();
+
+ virtual lldb::StackFrameSP
+ CalculateStackFrame ();
+
+ virtual void
+ CalculateExecutionContext (ExecutionContext &exe_ctx);
+
+ PathMappingList &
+ GetImageSearchPathList ();
+
+ ClangASTContext *
+ GetScratchClangASTContext(bool create_on_demand=true);
+
+ ClangASTImporter *
+ GetClangASTImporter();
+
+
+ // Since expressions results can persist beyond the lifetime of a process,
+ // and the const expression results are available after a process is gone,
+ // we provide a way for expressions to be evaluated from the Target itself.
+ // If an expression is going to be run, then it should have a frame filled
+ // in in th execution context.
+ ExecutionResults
+ EvaluateExpression (const char *expression,
+ StackFrame *frame,
+ lldb::ValueObjectSP &result_valobj_sp,
+ const EvaluateExpressionOptions& options = EvaluateExpressionOptions());
+
+ ClangPersistentVariables &
+ GetPersistentVariables()
+ {
+ return m_persistent_variables;
+ }
+
+ //------------------------------------------------------------------
+ // Target Stop Hooks
+ //------------------------------------------------------------------
+ class StopHook : public UserID
+ {
+ public:
+ ~StopHook ();
+
+ StopHook (const StopHook &rhs);
+
+ StringList *
+ GetCommandPointer ()
+ {
+ return &m_commands;
+ }
+
+ const StringList &
+ GetCommands()
+ {
+ return m_commands;
+ }
+
+ lldb::TargetSP &
+ GetTarget()
+ {
+ return m_target_sp;
+ }
+
+ void
+ SetCommands (StringList &in_commands)
+ {
+ m_commands = in_commands;
+ }
+
+ // Set the specifier. The stop hook will own the specifier, and is responsible for deleting it when we're done.
+ void
+ SetSpecifier (SymbolContextSpecifier *specifier)
+ {
+ m_specifier_sp.reset (specifier);
+ }
+
+ SymbolContextSpecifier *
+ GetSpecifier ()
+ {
+ return m_specifier_sp.get();
+ }
+
+ // Set the Thread Specifier. The stop hook will own the thread specifier, and is responsible for deleting it when we're done.
+ void
+ SetThreadSpecifier (ThreadSpec *specifier);
+
+ ThreadSpec *
+ GetThreadSpecifier()
+ {
+ return m_thread_spec_ap.get();
+ }
+
+ bool
+ IsActive()
+ {
+ return m_active;
+ }
+
+ void
+ SetIsActive (bool is_active)
+ {
+ m_active = is_active;
+ }
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+ private:
+ lldb::TargetSP m_target_sp;
+ StringList m_commands;
+ lldb::SymbolContextSpecifierSP m_specifier_sp;
+ std::unique_ptr<ThreadSpec> m_thread_spec_ap;
+ bool m_active;
+
+ // Use AddStopHook to make a new empty stop hook. The GetCommandPointer and fill it with commands,
+ // and SetSpecifier to set the specifier shared pointer (can be null, that will match anything.)
+ StopHook (lldb::TargetSP target_sp, lldb::user_id_t uid);
+ friend class Target;
+ };
+ typedef std::shared_ptr<StopHook> StopHookSP;
+
+ // Add an empty stop hook to the Target's stop hook list, and returns a shared pointer to it in new_hook.
+ // Returns the id of the new hook.
+ lldb::user_id_t
+ AddStopHook (StopHookSP &new_hook);
+
+ void
+ RunStopHooks ();
+
+ size_t
+ GetStopHookSize();
+
+ bool
+ SetSuppresStopHooks (bool suppress)
+ {
+ bool old_value = m_suppress_stop_hooks;
+ m_suppress_stop_hooks = suppress;
+ return old_value;
+ }
+
+ bool
+ GetSuppressStopHooks ()
+ {
+ return m_suppress_stop_hooks;
+ }
+
+ bool
+ SetSuppressSyntheticValue (bool suppress)
+ {
+ bool old_value = m_suppress_synthetic_value;
+ m_suppress_synthetic_value = suppress;
+ return old_value;
+ }
+
+ bool
+ GetSuppressSyntheticValue ()
+ {
+ return m_suppress_synthetic_value;
+ }
+
+// StopHookSP &
+// GetStopHookByIndex (size_t index);
+//
+ bool
+ RemoveStopHookByID (lldb::user_id_t uid);
+
+ void
+ RemoveAllStopHooks ();
+
+ StopHookSP
+ GetStopHookByID (lldb::user_id_t uid);
+
+ bool
+ SetStopHookActiveStateByID (lldb::user_id_t uid, bool active_state);
+
+ void
+ SetAllStopHooksActiveState (bool active_state);
+
+ size_t GetNumStopHooks () const
+ {
+ return m_stop_hooks.size();
+ }
+
+ StopHookSP
+ GetStopHookAtIndex (size_t index)
+ {
+ if (index >= GetNumStopHooks())
+ return StopHookSP();
+ StopHookCollection::iterator pos = m_stop_hooks.begin();
+
+ while (index > 0)
+ {
+ pos++;
+ index--;
+ }
+ return (*pos).second;
+ }
+
+ lldb::PlatformSP
+ GetPlatform ()
+ {
+ return m_platform_sp;
+ }
+
+ void
+ SetPlatform (const lldb::PlatformSP &platform_sp)
+ {
+ m_platform_sp = platform_sp;
+ }
+
+ SourceManager &
+ GetSourceManager ();
+
+ //------------------------------------------------------------------
+ // Methods.
+ //------------------------------------------------------------------
+ lldb::SearchFilterSP
+ GetSearchFilterForModule (const FileSpec *containingModule);
+
+ lldb::SearchFilterSP
+ GetSearchFilterForModuleList (const FileSpecList *containingModuleList);
+
+ lldb::SearchFilterSP
+ GetSearchFilterForModuleAndCUList (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles);
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ Debugger & m_debugger;
+ lldb::PlatformSP m_platform_sp; ///< The platform for this target.
+ Mutex m_mutex; ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe
+ ArchSpec m_arch;
+ ModuleList m_images; ///< The list of images for this process (shared libraries and anything dynamically loaded).
+ SectionLoadList m_section_load_list;
+ BreakpointList m_breakpoint_list;
+ BreakpointList m_internal_breakpoint_list;
+ lldb::BreakpointSP m_last_created_breakpoint;
+ WatchpointList m_watchpoint_list;
+ lldb::WatchpointSP m_last_created_watchpoint;
+ // We want to tightly control the process destruction process so
+ // we can correctly tear down everything that we need to, so the only
+ // class that knows about the process lifespan is this target class.
+ lldb::ProcessSP m_process_sp;
+ bool m_valid;
+ lldb::SearchFilterSP m_search_filter_sp;
+ PathMappingList m_image_search_paths;
+ std::unique_ptr<ClangASTContext> m_scratch_ast_context_ap;
+ std::unique_ptr<ClangASTSource> m_scratch_ast_source_ap;
+ std::unique_ptr<ClangASTImporter> m_ast_importer_ap;
+ ClangPersistentVariables m_persistent_variables; ///< These are the persistent variables associated with this process for the expression parser.
+
+ std::unique_ptr<SourceManager> m_source_manager_ap;
+
+ typedef std::map<lldb::user_id_t, StopHookSP> StopHookCollection;
+ StopHookCollection m_stop_hooks;
+ lldb::user_id_t m_stop_hook_next_id;
+ bool m_suppress_stop_hooks;
+ bool m_suppress_synthetic_value;
+
+ static void
+ ImageSearchPathsChanged (const PathMappingList &path_list,
+ void *baton);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (Target);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Target_h_
diff --git a/include/lldb/Target/TargetList.h b/include/lldb/Target/TargetList.h
new file mode 100644
index 000000000000..41404e11c7fa
--- /dev/null
+++ b/include/lldb/Target/TargetList.h
@@ -0,0 +1,239 @@
+//===-- TargetList.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TargetList_h_
+#define liblldb_TargetList_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/Target.h"
+
+namespace lldb_private {
+
+class TargetList : public Broadcaster
+{
+private:
+ friend class Debugger;
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// The constructor for the target list is private. Clients can
+ /// get ahold of of the one and only target list through the
+ /// lldb_private::Debugger::GetSharedInstance().GetTargetList().
+ ///
+ /// @see static TargetList& lldb_private::Debugger::GetTargetList().
+ //------------------------------------------------------------------
+ TargetList(Debugger &debugger);
+
+public:
+
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ enum
+ {
+ eBroadcastBitInterrupt = (1 << 0)
+ };
+
+
+ // These two functions fill out the Broadcaster interface:
+
+ static ConstString &GetStaticBroadcasterClass ();
+
+ virtual ConstString &GetBroadcasterClass() const
+ {
+ return GetStaticBroadcasterClass();
+ }
+
+ virtual ~TargetList();
+
+ //------------------------------------------------------------------
+ /// Create a new Target.
+ ///
+ /// Clients must use this function to create a Target. This allows
+ /// a global list of targets to be maintained in a central location
+ /// so signal handlers and other global functions can use it to
+ /// locate an appropriate target to deliver asynchronous information
+ /// to.
+ ///
+ /// @param[in] debugger
+ /// The debugger to associate this target with
+ ///
+ /// @param[in] file_spec
+ /// The main executable file for a debug target. This value
+ /// can be NULL and the file can be set later using:
+ /// Target::SetExecutableModule (ModuleSP&)
+ ///
+ /// @param[in] triple_cstr
+ /// A target triple string to be used for the target. This can
+ /// be NULL if the triple is not known or when attaching to a
+ /// process.
+ ///
+ /// @param[in] get_dependent_modules
+ /// Track down the dependent modules for an executable and
+ /// load those into the module list.
+ ///
+ /// @param[in] platform_options
+ /// A pointer to the platform options to use when creating this
+ /// target. If this value is NULL, then the currently selected
+ /// platform will be used.
+ ///
+ /// @param[out] target_sp
+ /// A shared pointer to a target that will be filled in if
+ /// this call is successful.
+ ///
+ /// @return
+ /// An error object that indicates success or failure
+ //------------------------------------------------------------------
+ Error
+ CreateTarget (Debugger &debugger,
+ const char *user_exe_path,
+ const char *triple_cstr,
+ bool get_dependent_modules,
+ const OptionGroupPlatform *platform_options,
+ lldb::TargetSP &target_sp);
+
+ //------------------------------------------------------------------
+ /// Create a new Target.
+ ///
+ /// Same as the function above, but used when you already know the
+ /// platform you will be using
+ //------------------------------------------------------------------
+ Error
+ CreateTarget (Debugger &debugger,
+ const char *user_exe_path,
+ const ArchSpec& arch,
+ bool get_dependent_modules,
+ lldb::PlatformSP &platform_sp,
+ lldb::TargetSP &target_sp);
+
+ //------------------------------------------------------------------
+ /// Delete a Target object from the list.
+ ///
+ /// When clients are done with the Target objets, this function
+ /// should be called to release the memory associated with a target
+ /// object.
+ ///
+ /// @param[in] target_sp
+ /// The shared pointer to a target.
+ ///
+ /// @return
+ /// Returns \b true if the target was successfully removed from
+ /// from this target list, \b false otherwise. The client will
+ /// be left with the last remaining shared pointer to the target
+ /// in \a target_sp which can then be properly released.
+ //------------------------------------------------------------------
+ bool
+ DeleteTarget (lldb::TargetSP &target_sp);
+
+ int
+ GetNumTargets () const;
+
+ lldb::TargetSP
+ GetTargetAtIndex (uint32_t index) const;
+
+ uint32_t
+ GetIndexOfTarget (lldb::TargetSP target_sp) const;
+
+ //------------------------------------------------------------------
+ /// Find the target that contains has an executable whose path
+ /// matches \a exe_file_spec, and whose architecture matches
+ /// \a arch_ptr if arch_ptr is not NULL.
+ ///
+ /// @param[in] exe_file_spec
+ /// A file spec containing a basename, or a full path (directory
+ /// and basename). If \a exe_file_spec contains only a filename
+ /// (empty GetDirectory() value) then matching will be done
+ /// solely based on the filenames and directories won't be
+ /// compared. If \a exe_file_spec contains a filename and a
+ /// directory, then both must match.
+ ///
+ /// @param[in] exe_arch_ptr
+ /// If not NULL then the architecture also needs to match, else
+ /// the architectures will be compared.
+ ///
+ /// @return
+ /// A shared pointer to a target object. The returned shared
+ /// pointer will contain NULL if no target objects have a
+ /// executable whose full or partial path matches
+ /// with a matching process ID.
+ //------------------------------------------------------------------
+ lldb::TargetSP
+ FindTargetWithExecutableAndArchitecture (const FileSpec &exe_file_spec,
+ const ArchSpec *exe_arch_ptr = NULL) const;
+
+ //------------------------------------------------------------------
+ /// Find the target that contains a process with process ID \a
+ /// pid.
+ ///
+ /// @param[in] pid
+ /// The process ID to search our target list for.
+ ///
+ /// @return
+ /// A shared pointer to a target object. The returned shared
+ /// pointer will contain NULL if no target objects own a process
+ /// with a matching process ID.
+ //------------------------------------------------------------------
+ lldb::TargetSP
+ FindTargetWithProcessID (lldb::pid_t pid) const;
+
+ lldb::TargetSP
+ FindTargetWithProcess (lldb_private::Process *process) const;
+
+ lldb::TargetSP
+ GetTargetSP (Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Send an async interrupt to one or all processes.
+ ///
+ /// Find the target that contains the process with process ID \a
+ /// pid and send a LLDB_EVENT_ASYNC_INTERRUPT event to the process's
+ /// event queue.
+ ///
+ /// @param[in] pid
+ /// The process ID to search our target list for, if \a pid is
+ /// LLDB_INVALID_PROCESS_ID, then the interrupt will be sent to
+ /// all processes.
+ ///
+ /// @return
+ /// The number of async interrupts sent.
+ //------------------------------------------------------------------
+ uint32_t
+ SendAsyncInterrupt (lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
+
+ uint32_t
+ SignalIfRunning (lldb::pid_t pid, int signo);
+
+ uint32_t
+ SetSelectedTarget (Target *target);
+
+ lldb::TargetSP
+ GetSelectedTarget ();
+
+
+protected:
+ typedef std::vector<lldb::TargetSP> collection;
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ collection m_target_list;
+ mutable Mutex m_target_list_mutex;
+ uint32_t m_selected_target_idx;
+private:
+ DISALLOW_COPY_AND_ASSIGN (TargetList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_TargetList_h_
diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h
new file mode 100644
index 000000000000..e4e532e4b331
--- /dev/null
+++ b/include/lldb/Target/Thread.h
@@ -0,0 +1,1067 @@
+//===-- Thread.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Thread_h_
+#define liblldb_Thread_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Event.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrameList.h"
+
+#define LLDB_THREAD_MAX_STOP_EXC_DATA 8
+
+namespace lldb_private {
+
+class ThreadProperties : public Properties
+{
+public:
+ ThreadProperties(bool is_global);
+
+ virtual
+ ~ThreadProperties();
+
+ //------------------------------------------------------------------
+ /// The regular expression returned determines symbols that this
+ /// thread won't stop in during "step-in" operations.
+ ///
+ /// @return
+ /// A pointer to a regular expression to compare against symbols,
+ /// or NULL if all symbols are allowed.
+ ///
+ //------------------------------------------------------------------
+ const RegularExpression *
+ GetSymbolsToAvoidRegexp();
+
+ bool
+ GetTraceEnabledState() const;
+};
+
+typedef std::shared_ptr<ThreadProperties> ThreadPropertiesSP;
+
+class Thread :
+ public std::enable_shared_from_this<Thread>,
+ public ThreadProperties,
+ public UserID,
+ public ExecutionContextScope,
+ public Broadcaster
+{
+public:
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ enum
+ {
+ eBroadcastBitStackChanged = (1 << 0),
+ eBroadcastBitThreadSuspended = (1 << 1),
+ eBroadcastBitThreadResumed = (1 << 2),
+ eBroadcastBitSelectedFrameChanged = (1 << 3),
+ eBroadcastBitThreadSelected = (1 << 4)
+ };
+
+ static ConstString &GetStaticBroadcasterClass ();
+
+ virtual ConstString &GetBroadcasterClass() const
+ {
+ return GetStaticBroadcasterClass();
+ }
+
+ class ThreadEventData :
+ public EventData
+ {
+ public:
+ ThreadEventData (const lldb::ThreadSP thread_sp);
+
+ ThreadEventData (const lldb::ThreadSP thread_sp, const StackID &stack_id);
+
+ ThreadEventData();
+
+ virtual ~ThreadEventData();
+
+ static const ConstString &
+ GetFlavorString ();
+
+ virtual const ConstString &
+ GetFlavor () const
+ {
+ return ThreadEventData::GetFlavorString ();
+ }
+
+ virtual void
+ Dump (Stream *s) const;
+
+ static const ThreadEventData *
+ GetEventDataFromEvent (const Event *event_ptr);
+
+ static lldb::ThreadSP
+ GetThreadFromEvent (const Event *event_ptr);
+
+ static StackID
+ GetStackIDFromEvent (const Event *event_ptr);
+
+ static lldb::StackFrameSP
+ GetStackFrameFromEvent (const Event *event_ptr);
+
+ lldb::ThreadSP
+ GetThread () const
+ {
+ return m_thread_sp;
+ }
+
+ StackID
+ GetStackID () const
+ {
+ return m_stack_id;
+ }
+
+ private:
+ lldb::ThreadSP m_thread_sp;
+ StackID m_stack_id;
+ DISALLOW_COPY_AND_ASSIGN (ThreadEventData);
+ };
+
+ // TODO: You shouldn't just checkpoint the register state alone, so this should get
+ // moved to protected. To do that ThreadStateCheckpoint needs to be returned as a token...
+ class RegisterCheckpoint
+ {
+ public:
+
+ RegisterCheckpoint() :
+ m_stack_id (),
+ m_data_sp ()
+ {
+ }
+
+ RegisterCheckpoint (const StackID &stack_id) :
+ m_stack_id (stack_id),
+ m_data_sp ()
+ {
+ }
+
+ ~RegisterCheckpoint()
+ {
+ }
+
+ const RegisterCheckpoint&
+ operator= (const RegisterCheckpoint &rhs)
+ {
+ if (this != &rhs)
+ {
+ this->m_stack_id = rhs.m_stack_id;
+ this->m_data_sp = rhs.m_data_sp;
+ }
+ return *this;
+ }
+
+ RegisterCheckpoint (const RegisterCheckpoint &rhs) :
+ m_stack_id (rhs.m_stack_id),
+ m_data_sp (rhs.m_data_sp)
+ {
+ }
+
+ const StackID &
+ GetStackID()
+ {
+ return m_stack_id;
+ }
+
+ void
+ SetStackID (const StackID &stack_id)
+ {
+ m_stack_id = stack_id;
+ }
+
+ lldb::DataBufferSP &
+ GetData()
+ {
+ return m_data_sp;
+ }
+
+ const lldb::DataBufferSP &
+ GetData() const
+ {
+ return m_data_sp;
+ }
+
+ protected:
+ StackID m_stack_id;
+ lldb::DataBufferSP m_data_sp;
+ };
+
+ struct ThreadStateCheckpoint
+ {
+ uint32_t orig_stop_id; // Dunno if I need this yet but it is an interesting bit of data.
+ lldb::StopInfoSP stop_info_sp; // You have to restore the stop info or you might continue with the wrong signals.
+ RegisterCheckpoint register_backup; // You need to restore the registers, of course...
+ uint32_t current_inlined_depth;
+ lldb::addr_t current_inlined_pc;
+ };
+
+ static void
+ SettingsInitialize ();
+
+ static void
+ SettingsTerminate ();
+
+ static const ThreadPropertiesSP &
+ GetGlobalProperties();
+
+ Thread (Process &process, lldb::tid_t tid);
+ virtual ~Thread();
+
+ lldb::ProcessSP
+ GetProcess() const
+ {
+ return m_process_wp.lock();
+ }
+
+ int
+ GetResumeSignal () const
+ {
+ return m_resume_signal;
+ }
+
+ void
+ SetResumeSignal (int signal)
+ {
+ m_resume_signal = signal;
+ }
+
+ lldb::StateType
+ GetState() const;
+
+ void
+ SetState (lldb::StateType state);
+
+ lldb::StateType
+ GetResumeState () const
+ {
+ return m_resume_state;
+ }
+
+ void
+ SetResumeState (lldb::StateType state)
+ {
+ m_resume_state = state;
+ }
+
+ // This function is called on all the threads before "ShouldResume" and
+ // "WillResume" in case a thread needs to change its state before the
+ // ThreadList polls all the threads to figure out which ones actually
+ // will get to run and how.
+ void
+ SetupForResume ();
+
+ // Do not override this function, it is for thread plan logic only
+ bool
+ ShouldResume (lldb::StateType resume_state);
+
+ // Override this to do platform specific tasks before resume.
+ virtual void
+ WillResume (lldb::StateType resume_state)
+ {
+ }
+
+ // This clears generic thread state after a resume. If you subclass this,
+ // be sure to call it.
+ virtual void
+ DidResume ();
+
+ // This notifies the thread when a private stop occurs.
+ virtual void
+ DidStop ();
+
+ virtual void
+ RefreshStateAfterStop() = 0;
+
+ void
+ WillStop ();
+
+ bool
+ ShouldStop (Event *event_ptr);
+
+ Vote
+ ShouldReportStop (Event *event_ptr);
+
+ Vote
+ ShouldReportRun (Event *event_ptr);
+
+ void
+ Flush ();
+
+ // Return whether this thread matches the specification in ThreadSpec. This is a virtual
+ // method because at some point we may extend the thread spec with a platform specific
+ // dictionary of attributes, which then only the platform specific Thread implementation
+ // would know how to match. For now, this just calls through to the ThreadSpec's
+ // ThreadPassesBasicTests method.
+ virtual bool
+ MatchesSpec (const ThreadSpec *spec);
+
+ lldb::StopInfoSP
+ GetStopInfo ();
+
+ lldb::StopReason
+ GetStopReason();
+
+ // This sets the stop reason to a "blank" stop reason, so you can call functions on the thread
+ // without having the called function run with whatever stop reason you stopped with.
+ void
+ SetStopInfoToNothing();
+
+ bool
+ ThreadStoppedForAReason ();
+
+ static const char *
+ RunModeAsCString (lldb::RunMode mode);
+
+ static const char *
+ StopReasonAsCString (lldb::StopReason reason);
+
+ virtual const char *
+ GetInfo ()
+ {
+ return NULL;
+ }
+
+ virtual const char *
+ GetName ()
+ {
+ return NULL;
+ }
+
+ virtual const char *
+ GetQueueName ()
+ {
+ return NULL;
+ }
+
+ virtual uint32_t
+ GetStackFrameCount()
+ {
+ return GetStackFrameList()->GetNumFrames();
+ }
+
+ virtual lldb::StackFrameSP
+ GetStackFrameAtIndex (uint32_t idx)
+ {
+ return GetStackFrameList()->GetFrameAtIndex(idx);
+ }
+
+ virtual lldb::StackFrameSP
+ GetFrameWithConcreteFrameIndex (uint32_t unwind_idx);
+
+ bool
+ DecrementCurrentInlinedDepth()
+ {
+ return GetStackFrameList()->DecrementCurrentInlinedDepth();
+ }
+
+ uint32_t
+ GetCurrentInlinedDepth()
+ {
+ return GetStackFrameList()->GetCurrentInlinedDepth();
+ }
+
+ Error
+ ReturnFromFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp, bool broadcast = false);
+
+ Error
+ ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp, bool broadcast = false);
+
+ virtual lldb::StackFrameSP
+ GetFrameWithStackID (const StackID &stack_id)
+ {
+ if (stack_id.IsValid())
+ return GetStackFrameList()->GetFrameWithStackID (stack_id);
+ return lldb::StackFrameSP();
+ }
+
+ uint32_t
+ GetSelectedFrameIndex ()
+ {
+ return GetStackFrameList()->GetSelectedFrameIndex();
+ }
+
+ lldb::StackFrameSP
+ GetSelectedFrame ()
+ {
+ lldb::StackFrameListSP stack_frame_list_sp(GetStackFrameList());
+ return stack_frame_list_sp->GetFrameAtIndex (stack_frame_list_sp->GetSelectedFrameIndex());
+ }
+
+ uint32_t
+ SetSelectedFrame (lldb_private::StackFrame *frame, bool broadcast = false);
+
+
+ bool
+ SetSelectedFrameByIndex (uint32_t frame_idx, bool broadcast = false);
+
+ bool
+ SetSelectedFrameByIndexNoisily (uint32_t frame_idx, Stream &output_stream);
+
+ void
+ SetDefaultFileAndLineToSelectedFrame()
+ {
+ GetStackFrameList()->SetDefaultFileAndLineToSelectedFrame();
+ }
+
+ virtual lldb::RegisterContextSP
+ GetRegisterContext () = 0;
+
+ virtual lldb::RegisterContextSP
+ CreateRegisterContextForFrame (StackFrame *frame) = 0;
+
+ virtual void
+ ClearStackFrames ();
+
+ virtual bool
+ SetBackingThread (const lldb::ThreadSP &thread_sp)
+ {
+ return false;
+ }
+
+ virtual lldb::ThreadSP
+ GetBackingThread () const
+ {
+ return lldb::ThreadSP();
+ }
+
+ virtual void
+ ClearBackingThread ()
+ {
+ // Subclasses can use this function if a thread is actually backed by
+ // another thread. This is currently used for the OperatingSystem plug-ins
+ // where they might have a thread that is in memory, yet its registers
+ // are available through the lldb_private::Thread subclass for the current
+ // lldb_private::Process class. Since each time the process stops the backing
+ // threads for memory threads can change, we need a way to clear the backing
+ // thread for all memory threads each time we stop.
+ }
+
+ void
+ DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx);
+
+ //------------------------------------------------------------------
+ // Thread Plan Providers:
+ // This section provides the basic thread plans that the Process control
+ // machinery uses to run the target. ThreadPlan.h provides more details on
+ // how this mechanism works.
+ // The thread provides accessors to a set of plans that perform basic operations.
+ // The idea is that particular Platform plugins can override these methods to
+ // provide the implementation of these basic operations appropriate to their
+ // environment.
+ //
+ // NB: All the QueueThreadPlanXXX providers return Shared Pointers to
+ // Thread plans. This is useful so that you can modify the plans after
+ // creation in ways specific to that plan type. Also, it is often necessary for
+ // ThreadPlans that utilize other ThreadPlans to implement their task to keep a shared
+ // pointer to the sub-plan.
+ // But besides that, the shared pointers should only be held onto by entities who live no longer
+ // than the thread containing the ThreadPlan.
+ // FIXME: If this becomes a problem, we can make a version that just returns a pointer,
+ // which it is clearly unsafe to hold onto, and a shared pointer version, and only allow
+ // ThreadPlan and Co. to use the latter. That is made more annoying to do because there's
+ // no elegant way to friend a method to all sub-classes of a given class.
+ //
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Queues the base plan for a thread.
+ /// The version returned by Process does some things that are useful,
+ /// like handle breakpoints and signals, so if you return a plugin specific
+ /// one you probably want to call through to the Process one for anything
+ /// your plugin doesn't explicitly handle.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @return
+ /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP
+ QueueFundamentalPlan (bool abort_other_plans);
+
+ //------------------------------------------------------------------
+ /// Queues the plan used to step over a breakpoint at the current PC of \a thread.
+ /// The default version returned by Process handles trap based breakpoints, and
+ /// will disable the breakpoint, single step over it, then re-enable it.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @return
+ /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans);
+
+ //------------------------------------------------------------------
+ /// Queues the plan used to step one instruction from the current PC of \a thread.
+ ///
+ /// @param[in] step_over
+ /// \b true if we step over calls to functions, false if we step in.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// @return
+ /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepSingleInstruction (bool step_over,
+ bool abort_other_plans,
+ bool stop_other_threads);
+
+ //------------------------------------------------------------------
+ /// Queues the plan used to step through an address range, stepping over
+ /// function calls.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @param[in] type
+ /// Type of step to do, only eStepTypeInto and eStepTypeOver are supported by this plan.
+ ///
+ /// @param[in] range
+ /// The address range to step through.
+ ///
+ /// @param[in] addr_context
+ /// When dealing with stepping through inlined functions the current PC is not enough information to know
+ /// what "step" means. For instance a series of nested inline functions might start at the same address.
+ // The \a addr_context provides the current symbol context the step
+ /// is supposed to be out of.
+ // FIXME: Currently unused.
+ ///
+ /// @param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// @return
+ /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepOverRange (bool abort_other_plans,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_other_threads);
+
+ //------------------------------------------------------------------
+ /// Queues the plan used to step through an address range, stepping into functions.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @param[in] type
+ /// Type of step to do, only eStepTypeInto and eStepTypeOver are supported by this plan.
+ ///
+ /// @param[in] range
+ /// The address range to step through.
+ ///
+ /// @param[in] addr_context
+ /// When dealing with stepping through inlined functions the current PC is not enough information to know
+ /// what "step" means. For instance a series of nested inline functions might start at the same address.
+ // The \a addr_context provides the current symbol context the step
+ /// is supposed to be out of.
+ // FIXME: Currently unused.
+ ///
+ /// @param[in] step_in_target
+ /// Name if function we are trying to step into. We will step out if we don't land in that function.
+ ///
+ /// @param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// @param[in] avoid_code_without_debug_info
+ /// If \b true we will step out if we step into code with no debug info.
+ ///
+ /// @return
+ /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepInRange (bool abort_other_plans,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ const char *step_in_target,
+ lldb::RunMode stop_other_threads,
+ bool avoid_code_without_debug_info);
+
+ //------------------------------------------------------------------
+ /// Queue the plan used to step out of the function at the current PC of
+ /// \a thread.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @param[in] addr_context
+ /// When dealing with stepping through inlined functions the current PC is not enough information to know
+ /// what "step" means. For instance a series of nested inline functions might start at the same address.
+ // The \a addr_context provides the current symbol context the step
+ /// is supposed to be out of.
+ // FIXME: Currently unused.
+ ///
+ /// @param[in] first_insn
+ /// \b true if this is the first instruction of a function.
+ ///
+ /// @param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// @param[in] stop_vote
+ /// @param[in] run_vote
+ /// See standard meanings for the stop & run votes in ThreadPlan.h.
+ ///
+ /// @return
+ /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepOut (bool abort_other_plans,
+ SymbolContext *addr_context,
+ bool first_insn,
+ bool stop_other_threads,
+ Vote stop_vote, // = eVoteYes,
+ Vote run_vote, // = eVoteNoOpinion);
+ uint32_t frame_idx);
+
+ //------------------------------------------------------------------
+ /// Gets the plan used to step through the code that steps from a function
+ /// call site at the current PC into the actual function call.
+ ///
+ ///
+ /// @param[in] return_stack_id
+ /// The stack id that we will return to (by setting backstop breakpoints on the return
+ /// address to that frame) if we fail to step through.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// @return
+ /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepThrough (StackID &return_stack_id,
+ bool abort_other_plans,
+ bool stop_other_threads);
+
+ //------------------------------------------------------------------
+ /// Gets the plan used to continue from the current PC.
+ /// This is a simple plan, mostly useful as a backstop when you are continuing
+ /// for some particular purpose.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @param[in] target_addr
+ /// The address to which we're running.
+ ///
+ /// @param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// @return
+ /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
+ //------------------------------------------------------------------
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForRunToAddress (bool abort_other_plans,
+ Address &target_addr,
+ bool stop_other_threads);
+
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepUntil (bool abort_other_plans,
+ lldb::addr_t *address_list,
+ size_t num_addresses,
+ bool stop_others,
+ uint32_t frame_idx);
+
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForCallFunction (bool abort_other_plans,
+ Address& function,
+ lldb::addr_t arg,
+ bool stop_other_threads,
+ bool unwind_on_error = false,
+ bool ignore_breakpoints = true);
+
+ //------------------------------------------------------------------
+ // Thread Plan accessors:
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Gets the plan which will execute next on the plan stack.
+ ///
+ /// @return
+ /// A pointer to the next executed plan.
+ //------------------------------------------------------------------
+ ThreadPlan *
+ GetCurrentPlan ();
+
+ //------------------------------------------------------------------
+ /// Unwinds the thread stack for the innermost expression plan currently
+ /// on the thread plan stack.
+ ///
+ /// @return
+ /// An error if the thread plan could not be unwound.
+ //------------------------------------------------------------------
+
+ Error
+ UnwindInnermostExpression();
+
+private:
+ bool
+ PlanIsBasePlan (ThreadPlan *plan_ptr);
+
+ void
+ BroadcastSelectedFrameChange(StackID &new_frame_id);
+
+public:
+
+ //------------------------------------------------------------------
+ /// Gets the outer-most plan that was popped off the plan stack in the
+ /// most recent stop. Useful for printing the stop reason accurately.
+ ///
+ /// @return
+ /// A pointer to the last completed plan.
+ //------------------------------------------------------------------
+ lldb::ThreadPlanSP
+ GetCompletedPlan ();
+
+ //------------------------------------------------------------------
+ /// Gets the outer-most return value from the completed plans
+ ///
+ /// @return
+ /// A ValueObjectSP, either empty if there is no return value,
+ /// or containing the return value.
+ //------------------------------------------------------------------
+ lldb::ValueObjectSP
+ GetReturnValueObject ();
+
+ //------------------------------------------------------------------
+ /// Checks whether the given plan is in the completed plans for this
+ /// stop.
+ ///
+ /// @param[in] plan
+ /// Pointer to the plan you're checking.
+ ///
+ /// @return
+ /// Returns true if the input plan is in the completed plan stack,
+ /// false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsThreadPlanDone (ThreadPlan *plan);
+
+ //------------------------------------------------------------------
+ /// Checks whether the given plan is in the discarded plans for this
+ /// stop.
+ ///
+ /// @param[in] plan
+ /// Pointer to the plan you're checking.
+ ///
+ /// @return
+ /// Returns true if the input plan is in the discarded plan stack,
+ /// false otherwise.
+ //------------------------------------------------------------------
+ bool
+ WasThreadPlanDiscarded (ThreadPlan *plan);
+
+ //------------------------------------------------------------------
+ /// Queues a generic thread plan.
+ ///
+ /// @param[in] plan_sp
+ /// The plan to queue.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @return
+ /// A pointer to the last completed plan.
+ //------------------------------------------------------------------
+ void
+ QueueThreadPlan (lldb::ThreadPlanSP &plan_sp, bool abort_other_plans);
+
+
+ //------------------------------------------------------------------
+ /// Discards the plans queued on the plan stack of the current thread. This is
+ /// arbitrated by the "Master" ThreadPlans, using the "OkayToDiscard" call.
+ // But if \a force is true, all thread plans are discarded.
+ //------------------------------------------------------------------
+ void
+ DiscardThreadPlans (bool force);
+
+ //------------------------------------------------------------------
+ /// Discards the plans queued on the plan stack of the current thread up to and
+ /// including up_to_plan_sp.
+ //
+ // @param[in] up_to_plan_sp
+ // Discard all plans up to and including this one.
+ //------------------------------------------------------------------
+ void
+ DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp);
+
+ void
+ DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr);
+
+ //------------------------------------------------------------------
+ /// Prints the current plan stack.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the plan stack info.
+ ///
+ //------------------------------------------------------------------
+ void
+ DumpThreadPlans (Stream *s) const;
+
+ virtual bool
+ CheckpointThreadState (ThreadStateCheckpoint &saved_state);
+
+ virtual bool
+ RestoreRegisterStateFromCheckpoint (ThreadStateCheckpoint &saved_state);
+
+ virtual bool
+ RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state);
+
+ void
+ EnableTracer (bool value, bool single_step);
+
+ void
+ SetTracer (lldb::ThreadPlanTracerSP &tracer_sp);
+
+ //------------------------------------------------------------------
+ // Get the thread index ID. The index ID that is guaranteed to not
+ // be re-used by a process. They start at 1 and increase with each
+ // new thread. This allows easy command line access by a unique ID
+ // that is easier to type than the actual system thread ID.
+ //------------------------------------------------------------------
+ uint32_t
+ GetIndexID () const;
+
+
+ //------------------------------------------------------------------
+ // The API ID is often the same as the Thread::GetID(), but not in
+ // all cases. Thread::GetID() is the user visible thread ID that
+ // clients would want to see. The API thread ID is the thread ID
+ // that is used when sending data to/from the debugging protocol.
+ //------------------------------------------------------------------
+ virtual lldb::user_id_t
+ GetProtocolID () const
+ {
+ return GetID();
+ }
+
+ //------------------------------------------------------------------
+ // lldb::ExecutionContextScope pure virtual functions
+ //------------------------------------------------------------------
+ virtual lldb::TargetSP
+ CalculateTarget ();
+
+ virtual lldb::ProcessSP
+ CalculateProcess ();
+
+ virtual lldb::ThreadSP
+ CalculateThread ();
+
+ virtual lldb::StackFrameSP
+ CalculateStackFrame ();
+
+ virtual void
+ CalculateExecutionContext (ExecutionContext &exe_ctx);
+
+ lldb::StackFrameSP
+ GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr);
+
+ size_t
+ GetStatus (Stream &strm,
+ uint32_t start_frame,
+ uint32_t num_frames,
+ uint32_t num_frames_with_source);
+
+ size_t
+ GetStackFrameStatus (Stream& strm,
+ uint32_t first_frame,
+ uint32_t num_frames,
+ bool show_frame_info,
+ uint32_t num_frames_with_source);
+
+ // We need a way to verify that even though we have a thread in a shared
+ // pointer that the object itself is still valid. Currently this won't be
+ // the case if DestroyThread() was called. DestroyThread is called when
+ // a thread has been removed from the Process' thread list.
+ bool
+ IsValid () const
+ {
+ return !m_destroy_called;
+ }
+
+ // Sets and returns a valid stop info based on the process stop ID and the
+ // current thread plan. If the thread stop ID does not match the process'
+ // stop ID, the private stop reason is not set and an invalid StopInfoSP may
+ // be returned.
+ //
+ // NOTE: This function must be called before the current thread plan is
+ // moved to the completed plan stack (in Thread::ShouldStop()).
+ //
+ // NOTE: If subclasses override this function, ensure they do not overwrite
+ // the m_actual_stop_info if it is valid. The stop info may be a
+ // "checkpointed and restored" stop info, so if it is still around it is
+ // right even if you have not calculated this yourself, or if it disagrees
+ // with what you might have calculated.
+ virtual lldb::StopInfoSP
+ GetPrivateStopInfo ();
+
+ //----------------------------------------------------------------------
+ // Ask the thread subclass to set its stop info.
+ //
+ // Thread subclasses should call Thread::SetStopInfo(...) with the
+ // reason the thread stopped.
+ //
+ // @return
+ // True if Thread::SetStopInfo(...) was called, false otherwise.
+ //----------------------------------------------------------------------
+ virtual bool
+ CalculateStopInfo () = 0;
+
+ //----------------------------------------------------------------------
+ // Gets the temporary resume state for a thread.
+ //
+ // This value gets set in each thread by complex debugger logic in
+ // Thread::ShouldResume() and an appropriate thread resume state will get
+ // set in each thread every time the process is resumed prior to calling
+ // Process::DoResume(). The lldb_private::Process subclass should adhere
+ // to the thread resume state request which will be one of:
+ //
+ // eStateRunning - thread will resume when process is resumed
+ // eStateStepping - thread should step 1 instruction and stop when process
+ // is resumed
+ // eStateSuspended - thread should not execute any instructions when
+ // process is resumed
+ //----------------------------------------------------------------------
+ lldb::StateType
+ GetTemporaryResumeState() const
+ {
+ return m_temporary_resume_state;
+ }
+
+ void
+ SetStopInfo (const lldb::StopInfoSP &stop_info_sp);
+
+ void
+ SetShouldReportStop (Vote vote);
+
+protected:
+
+ friend class ThreadPlan;
+ friend class ThreadList;
+ friend class ThreadEventData;
+ friend class StackFrameList;
+ friend class StackFrame;
+ friend class OperatingSystem;
+
+ // This is necessary to make sure thread assets get destroyed while the thread is still in good shape
+ // to call virtual thread methods. This must be called by classes that derive from Thread in their destructor.
+ virtual void DestroyThread ();
+
+ void
+ PushPlan (lldb::ThreadPlanSP &plan_sp);
+
+ void
+ PopPlan ();
+
+ void
+ DiscardPlan ();
+
+ ThreadPlan *GetPreviousPlan (ThreadPlan *plan);
+
+ typedef std::vector<lldb::ThreadPlanSP> plan_stack;
+
+ virtual bool
+ SaveFrameZeroState (RegisterCheckpoint &checkpoint);
+
+ virtual bool
+ RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint);
+
+ // register_data_sp must be a DataSP passed to ReadAllRegisterValues.
+ bool
+ ResetFrameZeroRegisters (lldb::DataBufferSP register_data_sp);
+
+ virtual lldb_private::Unwind *
+ GetUnwinder ();
+
+ // Check to see whether the thread is still at the last breakpoint hit that stopped it.
+ virtual bool
+ IsStillAtLastBreakpointHit();
+
+ // Some threads are threads that are made up by OperatingSystem plugins that
+ // are threads that exist and are context switched out into memory. The
+ // OperatingSystem plug-in need a ways to know if a thread is "real" or made
+ // up.
+ virtual bool
+ IsOperatingSystemPluginThread () const
+ {
+ return false;
+ }
+
+
+ lldb::StackFrameListSP
+ GetStackFrameList ();
+
+ struct ThreadState
+ {
+ uint32_t orig_stop_id;
+ lldb::StopInfoSP stop_info_sp;
+ RegisterCheckpoint register_backup;
+ };
+
+ //------------------------------------------------------------------
+ // Classes that inherit from Process can see and modify these
+ //------------------------------------------------------------------
+ lldb::ProcessWP m_process_wp; ///< The process that owns this thread.
+ lldb::StopInfoSP m_stop_info_sp; ///< The private stop reason for this thread
+ uint32_t m_stop_info_stop_id; // This is the stop id for which the StopInfo is valid. Can use this so you know that
+ // the thread's m_stop_info_sp is current and you don't have to fetch it again
+ const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread for easy UI/command line access.
+ lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this thread's current register state.
+ lldb::StateType m_state; ///< The state of our process.
+ mutable Mutex m_state_mutex; ///< Multithreaded protection for m_state.
+ plan_stack m_plan_stack; ///< The stack of plans this thread is executing.
+ plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes.
+ plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes.
+ mutable Mutex m_frame_mutex; ///< Multithreaded protection for m_state.
+ lldb::StackFrameListSP m_curr_frames_sp; ///< The stack frames that get lazily populated after a thread stops.
+ lldb::StackFrameListSP m_prev_frames_sp; ///< The previous stack frames from the last time this thread stopped.
+ int m_resume_signal; ///< The signal that should be used when continuing this thread.
+ lldb::StateType m_resume_state; ///< This state is used to force a thread to be suspended from outside the ThreadPlan logic.
+ lldb::StateType m_temporary_resume_state; ///< This state records what the thread was told to do by the thread plan logic for the current resume.
+ /// It gets set in Thread::ShoudResume.
+ std::unique_ptr<lldb_private::Unwind> m_unwinder_ap;
+ bool m_destroy_called; // This is used internally to make sure derived Thread classes call DestroyThread.
+ LazyBool m_override_should_notify;
+private:
+ //------------------------------------------------------------------
+ // For Thread only
+ //------------------------------------------------------------------
+
+ DISALLOW_COPY_AND_ASSIGN (Thread);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Thread_h_
diff --git a/include/lldb/Target/ThreadList.h b/include/lldb/Target/ThreadList.h
new file mode 100644
index 000000000000..ddf49b002ecf
--- /dev/null
+++ b/include/lldb/Target/ThreadList.h
@@ -0,0 +1,163 @@
+//===-- ThreadList.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadList_h_
+#define liblldb_ThreadList_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/UserID.h"
+
+
+// FIXME: Currently this is a thread list with lots of functionality for use only by
+// the process for which this is the thread list. If we ever want a container class
+// to hand out that is just a random subset of threads, with iterator functionality,
+// then we should make that part a base class, and make a ProcessThreadList for the
+// process.
+namespace lldb_private {
+
+class ThreadList
+{
+friend class Process;
+
+public:
+
+ ThreadList (Process *process);
+
+ ThreadList (const ThreadList &rhs);
+
+ ~ThreadList ();
+
+ const ThreadList&
+ operator = (const ThreadList& rhs);
+
+ uint32_t
+ GetSize(bool can_update = true);
+
+ void
+ AddThread (const lldb::ThreadSP &thread_sp);
+
+ // Return the selected thread if there is one. Otherwise, return the thread
+ // selected at index 0.
+ lldb::ThreadSP
+ GetSelectedThread ();
+
+ bool
+ SetSelectedThreadByID (lldb::tid_t tid, bool notify = false);
+
+ bool
+ SetSelectedThreadByIndexID (uint32_t index_id, bool notify = false);
+
+ void
+ Clear();
+
+ void
+ Flush();
+
+ void
+ Destroy();
+
+ // Note that "idx" is not the same as the "thread_index". It is a zero
+ // based index to accessing the current threads, whereas "thread_index"
+ // is a unique index assigned
+ lldb::ThreadSP
+ GetThreadAtIndex (uint32_t idx, bool can_update = true);
+
+ lldb::ThreadSP
+ FindThreadByID (lldb::tid_t tid, bool can_update = true);
+
+ lldb::ThreadSP
+ FindThreadByProtocolID (lldb::tid_t tid, bool can_update = true);
+
+ lldb::ThreadSP
+ RemoveThreadByID (lldb::tid_t tid, bool can_update = true);
+
+ lldb::ThreadSP
+ RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update = true);
+
+ lldb::ThreadSP
+ FindThreadByIndexID (uint32_t index_id, bool can_update = true);
+
+ lldb::ThreadSP
+ GetThreadSPForThreadPtr (Thread *thread_ptr);
+
+ bool
+ ShouldStop (Event *event_ptr);
+
+ Vote
+ ShouldReportStop (Event *event_ptr);
+
+ Vote
+ ShouldReportRun (Event *event_ptr);
+
+ void
+ RefreshStateAfterStop ();
+
+ //------------------------------------------------------------------
+ /// The thread list asks tells all the threads it is about to resume.
+ /// If a thread can "resume" without having to resume the target, it
+ /// will return false for WillResume, and then the process will not be
+ /// restarted.
+ ///
+ /// @return
+ /// \b true instructs the process to resume normally,
+ /// \b false means start & stopped events will be generated, but
+ /// the process will not actually run. The thread must then return
+ /// the correct StopInfo when asked.
+ ///
+ //------------------------------------------------------------------
+ bool
+ WillResume ();
+
+ void
+ DidResume ();
+
+ void
+ DidStop ();
+
+ void
+ DiscardThreadPlans();
+
+ uint32_t
+ GetStopID () const;
+
+ void
+ SetStopID (uint32_t stop_id);
+
+ Mutex &
+ GetMutex ();
+
+ void
+ Update (ThreadList &rhs);
+
+protected:
+
+ void
+ SetShouldReportStop (Vote vote);
+
+ void
+ NotifySelectedThreadChanged (lldb::tid_t tid);
+
+ typedef std::vector<lldb::ThreadSP> collection;
+ //------------------------------------------------------------------
+ // Classes that inherit from Process can see and modify these
+ //------------------------------------------------------------------
+ Process *m_process; ///< The process that manages this thread list.
+ uint32_t m_stop_id; ///< The process stop ID that this thread list is valid for.
+ collection m_threads; ///< The threads for this process.
+ lldb::tid_t m_selected_tid; ///< For targets that need the notion of a current thread.
+
+private:
+ ThreadList ();
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadList_h_
diff --git a/include/lldb/Target/ThreadPlan.h b/include/lldb/Target/ThreadPlan.h
new file mode 100644
index 000000000000..3c83fd1b9630
--- /dev/null
+++ b/include/lldb/Target/ThreadPlan.h
@@ -0,0 +1,658 @@
+//===-- ThreadPlan.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlan_h_
+#define liblldb_ThreadPlan_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanTracer.h"
+#include "lldb/Target/StopInfo.h"
+
+namespace lldb_private {
+
+//------------------------------------------------------------------
+// ThreadPlan:
+// This is the pure virtual base class for thread plans.
+//
+// The thread plans provide the "atoms" of behavior that
+// all the logical process control, either directly from commands or through
+// more complex composite plans will rely on.
+//
+// Plan Stack:
+//
+// The thread maintaining a thread plan stack, and you program the actions of a particular thread
+// by pushing plans onto the plan stack.
+// There is always a "Current" plan, which is the head of the plan stack, though in some cases
+// a plan may defer to plans higher in the stack for some piece of information.
+//
+// The plan stack is never empty, there is always a Base Plan which persists through the life
+// of the running process.
+//
+//
+// Creating Plans:
+//
+// The thread plan is generally created and added to the plan stack through the QueueThreadPlanFor... API
+// in lldb::Thread. Those API's will return the plan that performs the named operation in a manner
+// appropriate for the current process. The plans in lldb/source/Target are generic
+// implementations, but a Process plugin can override them.
+//
+// ValidatePlan is then called. If it returns false, the plan is unshipped. This is a little
+// convenience which keeps us from having to error out of the constructor.
+//
+// Then the plan is added to the plan stack. When the plan is added to the plan stack its DidPush
+// will get called. This is useful if a plan wants to push any additional plans as it is constructed,
+// since you need to make sure you're already on the stack before you push additional plans.
+//
+// Completed Plans:
+//
+// When the target process stops the plans are queried, among other things, for whether their job is done.
+// If it is they are moved from the plan stack to the Completed Plan stack in reverse order from their position
+// on the plan stack (since multiple plans may be done at a given stop.) This is used primarily so that
+// the lldb::Thread::StopInfo for the thread can be set properly. If one plan pushes another to achieve part of
+// its job, but it doesn't want that sub-plan to be the one that sets the StopInfo, then call SetPrivate on the
+// sub-plan when you create it, and the Thread will pass over that plan in reporting the reason for the stop.
+//
+// Discarded plans:
+//
+// Your plan may also get discarded, i.e. moved from the plan stack to the "discarded plan stack". This can
+// happen, for instance, if the plan is calling a function and the function call crashes and you want
+// to unwind the attempt to call. So don't assume that your plan will always successfully stop. Which leads to:
+//
+// Cleaning up after your plans:
+//
+// When the plan is moved from the plan stack its WillPop method is always called, no matter why. Once it is
+// moved off the plan stack it is done, and won't get a chance to run again. So you should
+// undo anything that affects target state in this method. But be sure to leave the plan able to correctly
+// fill the StopInfo, however.
+// N.B. Don't wait to do clean up target state till the destructor, since that will usually get called when
+// the target resumes, and you want to leave the target state correct for new plans in the time between when
+// your plan gets unshipped and the next resume.
+//
+// Over the lifetime of the plan, various methods of the ThreadPlan are then called in response to changes of state in
+// the process we are debugging as follows:
+//
+// Resuming:
+//
+// When the target process is about to be restarted, the plan's WillResume method is called,
+// giving the plan a chance to prepare for the run. If WillResume returns false, then the
+// process is not restarted. Be sure to set an appropriate error value in the Process if
+// you have to do this. Note, ThreadPlans actually implement DoWillResume, WillResume wraps that call.
+//
+// Next the "StopOthers" method of all the threads are polled, and if one thread's Current plan
+// returns "true" then only that thread gets to run. If more than one returns "true" the threads that want to run solo
+// get run one by one round robin fashion. Otherwise all are let to run.
+//
+// Note, the way StopOthers is implemented, the base class implementation just asks the previous plan. So if your plan
+// has no opinion about whether it should run stopping others or not, just don't implement StopOthers, and the parent
+// will be asked.
+//
+// Finally, for each thread that is running, it run state is set to the return of RunState from the
+// thread's Current plan.
+//
+// Responding to a stop:
+//
+// When the target process stops, the plan is called in the following stages:
+//
+// First the thread asks the Current Plan if it can handle this stop by calling PlanExplainsStop.
+// If the Current plan answers "true" then it is asked if the stop should percolate all the way to the
+// user by calling the ShouldStop method. If the current plan doesn't explain the stop, then we query down
+// the plan stack for a plan that does explain the stop. The plan that does explain the stop then needs to
+// figure out what to do about the plans below it in the stack. If the stop is recoverable, then the plan that
+// understands it can just do what it needs to set up to restart, and then continue.
+// Otherwise, the plan that understood the stop should call DiscardPlanStack to clean up the stack below it.
+// Note, plans actually implement DoPlanExplainsStop, the result is cached in PlanExplainsStop so the DoPlanExplainsStop
+// itself will only get called once per stop.
+//
+// Master plans:
+//
+// In the normal case, when we decide to stop, we will collapse the plan stack up to the point of the plan that understood
+// the stop reason. However, if a plan wishes to stay on the stack after an event it didn't directly handle
+// it can designate itself a "Master" plan by responding true to IsMasterPlan, and then if it wants not to be
+// discarded, it can return true to OkayToDiscard, and it and all its dependent plans will be preserved when
+// we resume execution.
+//
+// The other effect of being a master plan is that when the Master plan is done , if it has set "OkayToDiscard" to false,
+// then it will be popped & execution will stop and return to the user. Remember that if OkayToDiscard is false, the
+// plan will be popped and control will be given to the next plan above it on the stack So setting OkayToDiscard to
+// false means the user will regain control when the MasterPlan is completed.
+//
+// Between these two controls this allows things like: a MasterPlan/DontDiscard Step Over to hit a breakpoint, stop and
+// return control to the user, but then when the user continues, the step out succeeds.
+// Even more tricky, when the breakpoint is hit, the user can continue to step in/step over/etc, and finally when they
+// continue, they will finish up the Step Over.
+//
+// FIXME: MasterPlan & OkayToDiscard aren't really orthogonal. MasterPlan designation means that this plan controls
+// it's fate and the fate of plans below it. OkayToDiscard tells whether the MasterPlan wants to stay on the stack. I
+// originally thought "MasterPlan-ness" would need to be a fixed characteristic of a ThreadPlan, in which case you needed
+// the extra control. But that doesn't seem to be true. So we should be able to convert to only MasterPlan status to mean
+// the current "MasterPlan/DontDiscard". Then no plans would be MasterPlans by default, and you would set the ones you
+// wanted to be "user level" in this way.
+//
+//
+// Actually Stopping:
+//
+// If a plan says responds "true" to ShouldStop, then it is asked if it's job is complete by calling
+// MischiefManaged. If that returns true, the thread is popped from the plan stack and added to the
+// Completed Plan Stack. Then the next plan in the stack is asked if it ShouldStop, and it returns "true",
+// it is asked if it is done, and if yes popped, and so on till we reach a plan that is not done.
+//
+// Since you often know in the ShouldStop method whether your plan is complete, as a convenience you can call
+// SetPlanComplete and the ThreadPlan implementation of MischiefManaged will return "true", without your having
+// to redo the calculation when your sub-classes MischiefManaged is called. If you call SetPlanComplete, you can
+// later use IsPlanComplete to determine whether the plan is complete. This is only a convenience for sub-classes,
+// the logic in lldb::Thread will only call MischiefManaged.
+//
+// One slightly tricky point is you have to be careful using SetPlanComplete in PlanExplainsStop because you
+// are not guaranteed that PlanExplainsStop for a plan will get called before ShouldStop gets called. If your sub-plan
+// explained the stop and then popped itself, only your ShouldStop will get called.
+//
+// If ShouldStop for any thread returns "true", then the WillStop method of the Current plan of
+// all threads will be called, the stop event is placed on the Process's public broadcaster, and
+// control returns to the upper layers of the debugger.
+//
+// Reporting the stop:
+//
+// When the process stops, the thread is given a StopReason, in the form of a StopInfo object. If there is a completed
+// plan corresponding to the stop, then the "actual" stop reason will be suppressed, and instead a StopInfoThreadPlan
+// object will be cons'ed up from the highest completed plan in the stack. However, if the plan doesn't want to be
+// the stop reason, then it can call SetPlanComplete and pass in "false" for the "success" parameter. In that case,
+// the real stop reason will be used instead. One exapmle of this is the "StepRangeStepIn" thread plan. If it stops
+// because of a crash or breakpoint hit, it wants to unship itself, because it isn't so useful to have step in keep going
+// after a breakpoint hit. But it can't be the reason for the stop or no-one would see that they had hit a breakpoint.
+//
+// Cleaning up the plan stack:
+//
+// One of the complications of MasterPlans is that you may get past the limits of a plan without triggering it to clean
+// itself up. For instance, if you are doing a MasterPlan StepOver, and hit a breakpoint in a called function, then
+// step over enough times to step out of the initial StepOver range, each of the step overs will explain the stop &
+// take themselves off the stack, but control would never be returned to the original StepOver. Eventually, the user
+// will continue, and when that continue stops, the old stale StepOver plan that was left on the stack will get woken
+// up and notice it is done. But that can leave junk on the stack for a while. To avoid that, the plans implement a
+// "IsPlanStale" method, that can check whether it is relevant anymore. On stop, after the regular plan negotiation,
+// the remaining plan stack is consulted and if any plan says it is stale, it and the plans below it are discarded from
+// the stack.
+//
+// Automatically Resuming:
+//
+// If ShouldStop for all threads returns "false", then the target process will resume. This then cycles back to
+// Resuming above.
+//
+// Reporting eStateStopped events when the target is restarted:
+//
+// If a plan decides to auto-continue the target by returning "false" from ShouldStop, then it will be asked
+// whether the Stopped event should still be reported. For instance, if you hit a breakpoint that is a User set
+// breakpoint, but the breakpoint callback said to continue the target process, you might still want to inform
+// the upper layers of lldb that the stop had happened.
+// The way this works is every thread gets to vote on whether to report the stop. If all votes are eVoteNoOpinion,
+// then the thread list will decide what to do (at present it will pretty much always suppress these stopped events.)
+// If there is an eVoteYes, then the event will be reported regardless of the other votes. If there is an eVoteNo
+// and no eVoteYes's, then the event won't be reported.
+//
+// One other little detail here, sometimes a plan will push another plan onto the plan stack to do some part of
+// the first plan's job, and it would be convenient to tell that plan how it should respond to ShouldReportStop.
+// You can do that by setting the stop_vote in the child plan when you create it.
+//
+// Suppressing the initial eStateRunning event:
+//
+// The private process running thread will take care of ensuring that only one "eStateRunning" event will be
+// delivered to the public Process broadcaster per public eStateStopped event. However there are some cases
+// where the public state of this process is eStateStopped, but a thread plan needs to restart the target, but
+// doesn't want the running event to be publically broadcast. The obvious example of this is running functions
+// by hand as part of expression evaluation. To suppress the running event return eVoteNo from ShouldReportStop,
+// to force a running event to be reported return eVoteYes, in general though you should return eVoteNoOpinion
+// which will allow the ThreadList to figure out the right thing to do.
+// The run_vote argument to the constructor works like stop_vote, and is a way for a plan to instruct a sub-plan
+// on how to respond to ShouldReportStop.
+//
+//------------------------------------------------------------------
+
+class ThreadPlan :
+ public UserID
+{
+public:
+ typedef enum
+ {
+ eAllThreads,
+ eSomeThreads,
+ eThisThread
+ } ThreadScope;
+
+ // We use these enums so that we can cast a base thread plan to it's real type without having to resort
+ // to dynamic casting.
+ typedef enum
+ {
+ eKindGeneric,
+ eKindNull,
+ eKindBase,
+ eKindCallFunction,
+ eKindStepInstruction,
+ eKindStepOut,
+ eKindStepOverBreakpoint,
+ eKindStepOverRange,
+ eKindStepInRange,
+ eKindRunToAddress,
+ eKindStepThrough,
+ eKindStepUntil,
+ eKindTestCondition
+
+ } ThreadPlanKind;
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ThreadPlan (ThreadPlanKind kind,
+ const char *name,
+ Thread &thread,
+ Vote stop_vote,
+ Vote run_vote);
+
+ virtual
+ ~ThreadPlan();
+
+ //------------------------------------------------------------------
+ /// Returns the name of this thread plan.
+ ///
+ /// @return
+ /// A const char * pointer to the thread plan's name.
+ //------------------------------------------------------------------
+ const char *
+ GetName () const
+ {
+ return m_name.c_str();
+ }
+
+ //------------------------------------------------------------------
+ /// Returns the Thread that is using this thread plan.
+ ///
+ /// @return
+ /// A pointer to the thread plan's owning thread.
+ //------------------------------------------------------------------
+ Thread &
+ GetThread()
+ {
+ return m_thread;
+ }
+
+ const Thread &
+ GetThread() const
+ {
+ return m_thread;
+ }
+
+ Target &
+ GetTarget()
+ {
+ return m_thread.GetProcess()->GetTarget();
+ }
+
+ const Target &
+ GetTarget() const
+ {
+ return m_thread.GetProcess()->GetTarget();
+ }
+
+ //------------------------------------------------------------------
+ /// Print a description of this thread to the stream \a s.
+ /// \a thread.
+ ///
+ /// @param[in] s
+ /// The stream to which to print the description.
+ ///
+ /// @param[in] level
+ /// The level of description desired. Note that eDescriptionLevelBrief
+ /// will be used in the stop message printed when the plan is complete.
+ //------------------------------------------------------------------
+ virtual void
+ GetDescription (Stream *s,
+ lldb::DescriptionLevel level) = 0;
+
+ //------------------------------------------------------------------
+ /// Returns whether this plan could be successfully created.
+ ///
+ /// @param[in] error
+ /// A stream to which to print some reason why the plan could not be created.
+ /// Can be NULL.
+ ///
+ /// @return
+ /// \b true if the plan should be queued, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ ValidatePlan (Stream *error) = 0;
+
+ bool
+ TracerExplainsStop ()
+ {
+ if (!m_tracer_sp)
+ return false;
+ else
+ return m_tracer_sp->TracerExplainsStop();
+ }
+
+
+ lldb::StateType
+ RunState ();
+
+ bool
+ PlanExplainsStop (Event *event_ptr);
+
+ virtual bool
+ ShouldStop (Event *event_ptr) = 0;
+
+ virtual bool
+ ShouldAutoContinue (Event *event_ptr)
+ {
+ return false;
+ }
+
+ // Whether a "stop class" event should be reported to the "outside world". In general
+ // if a thread plan is active, events should not be reported.
+
+ virtual Vote
+ ShouldReportStop (Event *event_ptr);
+
+ virtual Vote
+ ShouldReportRun (Event *event_ptr);
+
+ virtual void
+ SetStopOthers (bool new_value);
+
+ virtual bool
+ StopOthers ();
+
+ // This is the wrapper for DoWillResume that does generic ThreadPlan logic, then
+ // calls DoWillResume.
+ bool
+ WillResume (lldb::StateType resume_state, bool current_plan);
+
+ virtual bool
+ WillStop () = 0;
+
+ bool
+ IsMasterPlan()
+ {
+ return m_is_master_plan;
+ }
+
+ bool
+ SetIsMasterPlan (bool value)
+ {
+ bool old_value = m_is_master_plan;
+ m_is_master_plan = value;
+ return old_value;
+ }
+
+ virtual bool
+ OkayToDiscard();
+
+ void
+ SetOkayToDiscard (bool value)
+ {
+ m_okay_to_discard = value;
+ }
+
+ // The base class MischiefManaged does some cleanup - so you have to call it
+ // in your MischiefManaged derived class.
+ virtual bool
+ MischiefManaged ();
+
+ virtual void
+ ThreadDestroyed ()
+ {
+ // Any cleanup that a plan might want to do in case the thread goes away
+ // in the middle of the plan being queued on a thread can be done here.
+ }
+
+ bool
+ GetPrivate ()
+ {
+ return m_plan_private;
+ }
+
+ void
+ SetPrivate (bool input)
+ {
+ m_plan_private = input;
+ }
+
+ virtual void
+ DidPush();
+
+ virtual void
+ WillPop();
+
+ // This pushes a plan onto the plan stack of the current plan's thread.
+ void
+ PushPlan (lldb::ThreadPlanSP &thread_plan_sp)
+ {
+ m_thread.PushPlan (thread_plan_sp);
+ }
+
+ ThreadPlanKind GetKind() const
+ {
+ return m_kind;
+ }
+
+ bool
+ IsPlanComplete();
+
+ void
+ SetPlanComplete (bool success = true);
+
+ virtual bool
+ IsPlanStale ()
+ {
+ return false;
+ }
+
+ bool
+ PlanSucceeded ()
+ {
+ return m_plan_succeeded;
+ }
+
+ virtual bool
+ IsBasePlan()
+ {
+ return false;
+ }
+
+ lldb::ThreadPlanTracerSP &
+ GetThreadPlanTracer()
+ {
+ return m_tracer_sp;
+ }
+
+ void
+ SetThreadPlanTracer (lldb::ThreadPlanTracerSP new_tracer_sp)
+ {
+ m_tracer_sp = new_tracer_sp;
+ }
+
+ void
+ DoTraceLog ()
+ {
+ if (m_tracer_sp && m_tracer_sp->TracingEnabled())
+ m_tracer_sp->Log();
+ }
+
+ // Some thread plans hide away the actual stop info which caused any particular stop. For
+ // instance the ThreadPlanCallFunction restores the original stop reason so that stopping and
+ // calling a few functions won't lose the history of the run.
+ // This call can be implemented to get you back to the real stop info.
+ virtual lldb::StopInfoSP
+ GetRealStopInfo ()
+ {
+ return m_thread.GetStopInfo ();
+ }
+
+ virtual lldb::ValueObjectSP
+ GetReturnValueObject ()
+ {
+ return lldb::ValueObjectSP();
+ }
+
+ // If a thread plan stores the state before it was run, then you might
+ // want to restore the state when it is done. This will do that job.
+ // This is mostly useful for artificial plans like CallFunction plans.
+
+ virtual bool
+ RestoreThreadState()
+ {
+ // Nothing to do in general.
+ return true;
+ }
+
+ virtual bool
+ IsVirtualStep()
+ {
+ return false;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from ThreadPlan can see and modify these
+ //------------------------------------------------------------------
+
+ virtual bool
+ DoWillResume (lldb::StateType resume_state, bool current_plan) { return true; };
+
+ virtual bool
+ DoPlanExplainsStop (Event *event_ptr) = 0;
+
+ // This gets the previous plan to the current plan (for forwarding requests).
+ // This is mostly a formal requirement, it allows us to make the Thread's
+ // GetPreviousPlan protected, but only friend ThreadPlan to thread.
+
+ ThreadPlan *
+ GetPreviousPlan ()
+ {
+ return m_thread.GetPreviousPlan (this);
+ }
+
+ // This forwards the private Thread::GetPrivateStopInfo which is generally what
+ // ThreadPlan's need to know.
+
+ lldb::StopInfoSP
+ GetPrivateStopInfo()
+ {
+ return m_thread.GetPrivateStopInfo ();
+ }
+
+ void
+ SetStopInfo (lldb::StopInfoSP stop_reason_sp)
+ {
+ m_thread.SetStopInfo (stop_reason_sp);
+ }
+
+ void
+ CachePlanExplainsStop (bool does_explain)
+ {
+ m_cached_plan_explains_stop = does_explain ? eLazyBoolYes : eLazyBoolNo;
+ }
+
+ LazyBool
+ GetCachedPlanExplainsStop () const
+ {
+ return m_cached_plan_explains_stop;
+ }
+
+ virtual lldb::StateType
+ GetPlanRunState () = 0;
+
+ Thread &m_thread;
+ Vote m_stop_vote;
+ Vote m_run_vote;
+
+private:
+ //------------------------------------------------------------------
+ // For ThreadPlan only
+ //------------------------------------------------------------------
+ static lldb::user_id_t GetNextID ();
+
+ ThreadPlanKind m_kind;
+ std::string m_name;
+ Mutex m_plan_complete_mutex;
+ LazyBool m_cached_plan_explains_stop;
+ bool m_plan_complete;
+ bool m_plan_private;
+ bool m_okay_to_discard;
+ bool m_is_master_plan;
+ bool m_plan_succeeded;
+
+ lldb::ThreadPlanTracerSP m_tracer_sp;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ThreadPlan);
+};
+
+//----------------------------------------------------------------------
+// ThreadPlanNull:
+// Threads are assumed to always have at least one plan on the plan stack.
+// This is put on the plan stack when a thread is destroyed so that if you
+// accidentally access a thread after it is destroyed you won't crash.
+// But asking questions of the ThreadPlanNull is definitely an error.
+//----------------------------------------------------------------------
+
+class ThreadPlanNull : public ThreadPlan
+{
+public:
+ ThreadPlanNull (Thread &thread);
+ virtual ~ThreadPlanNull ();
+
+ virtual void
+ GetDescription (Stream *s,
+ lldb::DescriptionLevel level);
+
+ virtual bool
+ ValidatePlan (Stream *error);
+
+ virtual bool
+ ShouldStop (Event *event_ptr);
+
+ virtual bool
+ MischiefManaged ();
+
+ virtual bool
+ WillStop ();
+
+ virtual bool
+ IsBasePlan()
+ {
+ return true;
+ }
+
+ virtual bool
+ OkayToDiscard ()
+ {
+ return false;
+ }
+
+protected:
+ virtual bool
+ DoPlanExplainsStop (Event *event_ptr);
+
+ virtual lldb::StateType
+ GetPlanRunState ();
+
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlan_h_
diff --git a/include/lldb/Target/ThreadPlanBase.h b/include/lldb/Target/ThreadPlanBase.h
new file mode 100644
index 000000000000..69959e12f848
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanBase.h
@@ -0,0 +1,71 @@
+//===-- ThreadPlanBase.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanFundamental_h_
+#define liblldb_ThreadPlanFundamental_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+
+//------------------------------------------------------------------
+// Base thread plans:
+// This is the generic version of the bottom most plan on the plan stack. It should
+// be able to handle generic breakpoint hitting, and signals and exceptions.
+//------------------------------------------------------------------
+
+class ThreadPlanBase : public ThreadPlan
+{
+friend class Process; // RunThreadPlan manages "stopper" base plans.
+public:
+ virtual ~ThreadPlanBase ();
+
+ virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
+ virtual bool ValidatePlan (Stream *error);
+ virtual bool ShouldStop (Event *event_ptr);
+ virtual Vote ShouldReportStop (Event *event_ptr);
+ virtual bool StopOthers ();
+ virtual lldb::StateType GetPlanRunState ();
+ virtual bool WillStop ();
+ virtual bool MischiefManaged ();
+
+ virtual bool OkayToDiscard()
+ {
+ return false;
+ }
+
+ virtual bool
+ IsBasePlan()
+ {
+ return true;
+ }
+
+protected:
+ virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan);
+ virtual bool DoPlanExplainsStop (Event *event_ptr);
+ ThreadPlanBase (Thread &thread);
+
+private:
+ friend lldb::ThreadPlanSP
+ Thread::QueueFundamentalPlan(bool abort_other_plans);
+
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanBase);
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanFundamental_h_
diff --git a/include/lldb/Target/ThreadPlanCallFunction.h b/include/lldb/Target/ThreadPlanCallFunction.h
new file mode 100644
index 000000000000..d747706c6393
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanCallFunction.h
@@ -0,0 +1,193 @@
+//===-- ThreadPlanCallFunction.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanCallFunction_h_
+#define liblldb_ThreadPlanCallFunction_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+class ThreadPlanCallFunction : public ThreadPlan
+{
+ // Create a thread plan to call a function at the address passed in the "function"
+ // argument. If you plan to call GetReturnValueObject, then pass in the
+ // return type, otherwise just pass in an invalid ClangASTType.
+public:
+ ThreadPlanCallFunction (Thread &thread,
+ const Address &function,
+ const ClangASTType &return_type,
+ lldb::addr_t arg,
+ bool stop_other_threads,
+ bool unwind_on_error = true,
+ bool ignore_breakpoints = false,
+ lldb::addr_t *this_arg = 0,
+ lldb::addr_t *cmd_arg = 0);
+
+ ThreadPlanCallFunction (Thread &thread,
+ const Address &function,
+ const ClangASTType &return_type,
+ bool stop_other_threads,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
+ lldb::addr_t *arg1_ptr = NULL,
+ lldb::addr_t *arg2_ptr = NULL,
+ lldb::addr_t *arg3_ptr = NULL,
+ lldb::addr_t *arg4_ptr = NULL,
+ lldb::addr_t *arg5_ptr = NULL,
+ lldb::addr_t *arg6_ptr = NULL);
+
+ virtual
+ ~ThreadPlanCallFunction ();
+
+ virtual void
+ GetDescription (Stream *s, lldb::DescriptionLevel level);
+
+ virtual bool
+ ValidatePlan (Stream *error);
+
+ virtual bool
+ ShouldStop (Event *event_ptr);
+
+ virtual Vote
+ ShouldReportStop(Event *event_ptr);
+
+ virtual bool
+ StopOthers ();
+
+ virtual void
+ SetStopOthers (bool new_value);
+
+ virtual lldb::StateType
+ GetPlanRunState ();
+
+ virtual void
+ DidPush ();
+
+ virtual bool
+ WillStop ();
+
+ virtual bool
+ MischiefManaged ();
+
+ // To get the return value from a function call you must create a
+ // lldb::ValueSP that contains a valid clang type in its context and call
+ // RequestReturnValue. The ValueSP will be stored and when the function is
+ // done executing, the object will check if there is a requested return
+ // value. If there is, the return value will be retrieved using the
+ // ABI::GetReturnValue() for the ABI in the process. Then after the thread
+ // plan is complete, you can call "GetReturnValue()" to retrieve the value
+ // that was extracted.
+
+ virtual lldb::ValueObjectSP
+ GetReturnValueObject ()
+ {
+ return m_return_valobj_sp;
+ }
+
+ // Return the stack pointer that the function received
+ // on entry. Any stack address below this should be
+ // considered invalid after the function has been
+ // cleaned up.
+ lldb::addr_t
+ GetFunctionStackPointer()
+ {
+ return m_function_sp;
+ }
+
+ // Classes that derive from ClangFunction, and implement
+ // their own WillPop methods should call this so that the
+ // thread state gets restored if the plan gets discarded.
+ virtual void
+ WillPop ();
+
+ // If the thread plan stops mid-course, this will be the stop reason that interrupted us.
+ // Once DoTakedown is called, this will be the real stop reason at the end of the function call.
+ // If it hasn't been set for one or the other of these reasons, we'll return the PrivateStopReason.
+ // This is needed because we want the CallFunction thread plans not to show up as the stop reason.
+ // But if something bad goes wrong, it is nice to be able to tell the user what really happened.
+
+ virtual lldb::StopInfoSP
+ GetRealStopInfo()
+ {
+ if (m_real_stop_info_sp)
+ return m_real_stop_info_sp;
+ else
+ return GetPrivateStopInfo ();
+ }
+
+ lldb::addr_t
+ GetStopAddress ()
+ {
+ return m_stop_address;
+ }
+
+ virtual bool
+ RestoreThreadState();
+
+protected:
+ void ReportRegisterState (const char *message);
+
+ virtual bool
+ DoPlanExplainsStop (Event *event_ptr);
+
+private:
+
+ bool
+ ConstructorSetup (Thread &thread,
+ ABI *& abi,
+ lldb::addr_t &start_load_addr,
+ lldb::addr_t &function_load_addr);
+
+ void
+ DoTakedown (bool success);
+
+ void
+ SetBreakpoints ();
+
+ void
+ ClearBreakpoints ();
+
+ bool
+ BreakpointsExplainStop ();
+
+ bool m_valid;
+ bool m_stop_other_threads;
+ Address m_function_addr;
+ Address m_start_addr;
+ lldb::addr_t m_function_sp;
+ Thread::RegisterCheckpoint m_register_backup;
+ lldb::ThreadPlanSP m_subplan_sp;
+ LanguageRuntime *m_cxx_language_runtime;
+ LanguageRuntime *m_objc_language_runtime;
+ Thread::ThreadStateCheckpoint m_stored_thread_state;
+ lldb::StopInfoSP m_real_stop_info_sp; // In general we want to hide call function
+ // thread plans, but for reporting purposes,
+ // it's nice to know the real stop reason.
+ // This gets set in DoTakedown.
+ StreamString m_constructor_errors;
+ ClangASTType m_return_type;
+ lldb::ValueObjectSP m_return_valobj_sp; // If this contains a valid pointer, use the ABI to extract values when complete
+ bool m_takedown_done; // We want to ensure we only do the takedown once. This ensures that.
+ lldb::addr_t m_stop_address; // This is the address we stopped at. Also set in DoTakedown;
+ bool m_unwind_on_error;
+ bool m_ignore_breakpoints;
+
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallFunction);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanCallFunction_h_
diff --git a/include/lldb/Target/ThreadPlanCallUserExpression.h b/include/lldb/Target/ThreadPlanCallUserExpression.h
new file mode 100644
index 000000000000..7a7ec33049e0
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanCallUserExpression.h
@@ -0,0 +1,65 @@
+//===-- ThreadPlanCallUserExpression.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanCallUserExpression_h_
+#define liblldb_ThreadPlanCallUserExpression_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
+
+namespace lldb_private {
+
+class ThreadPlanCallUserExpression : public ThreadPlanCallFunction
+{
+public:
+ ThreadPlanCallUserExpression (Thread &thread,
+ Address &function,
+ lldb::addr_t arg,
+ bool stop_other_threads,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
+ lldb::addr_t *this_arg,
+ lldb::addr_t *cmd_arg,
+ ClangUserExpression::ClangUserExpressionSP &user_expression_sp);
+
+ virtual
+ ~ThreadPlanCallUserExpression ();
+
+ virtual void
+ GetDescription (Stream *s, lldb::DescriptionLevel level);
+
+ virtual void
+ WillPop ()
+ {
+ ThreadPlanCallFunction::WillPop();
+ if (m_user_expression_sp)
+ m_user_expression_sp.reset();
+ }
+
+ virtual lldb::StopInfoSP
+ GetRealStopInfo();
+
+protected:
+private:
+ ClangUserExpression::ClangUserExpressionSP m_user_expression_sp; // This is currently just used to ensure the
+ // User expression the initiated this ThreadPlan
+ // lives as long as the thread plan does.
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallUserExpression);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanCallUserExpression_h_
diff --git a/include/lldb/Target/ThreadPlanRunToAddress.h b/include/lldb/Target/ThreadPlanRunToAddress.h
new file mode 100644
index 000000000000..d94820668017
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanRunToAddress.h
@@ -0,0 +1,85 @@
+//===-- ThreadPlanRunToAddress.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanRunToAddress_h_
+#define liblldb_ThreadPlanRunToAddress_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+class ThreadPlanRunToAddress : public ThreadPlan
+{
+public:
+ ThreadPlanRunToAddress (Thread &thread,
+ Address &address,
+ bool stop_others);
+
+ ThreadPlanRunToAddress (Thread &thread,
+ lldb::addr_t address,
+ bool stop_others);
+
+ ThreadPlanRunToAddress (Thread &thread,
+ const std::vector<lldb::addr_t> &addresses,
+ bool stop_others);
+
+
+ virtual
+ ~ThreadPlanRunToAddress ();
+
+ virtual void
+ GetDescription (Stream *s, lldb::DescriptionLevel level);
+
+ virtual bool
+ ValidatePlan (Stream *error);
+
+ virtual bool
+ ShouldStop (Event *event_ptr);
+
+ virtual bool
+ StopOthers ();
+
+ virtual void
+ SetStopOthers (bool new_value);
+
+ virtual lldb::StateType
+ GetPlanRunState ();
+
+ virtual bool
+ WillStop ();
+
+ virtual bool
+ MischiefManaged ();
+
+protected:
+ virtual bool
+ DoPlanExplainsStop (Event *event_ptr);
+
+ void SetInitialBreakpoints();
+ bool AtOurAddress();
+private:
+ bool m_stop_others;
+ std::vector<lldb::addr_t> m_addresses; // This is the address we are going to run to.
+ // TODO: Would it be useful to have multiple addresses?
+ std::vector<lldb::break_id_t> m_break_ids; // This is the breakpoint we are using to stop us at m_address.
+
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanRunToAddress);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanRunToAddress_h_
diff --git a/include/lldb/Target/ThreadPlanShouldStopHere.h b/include/lldb/Target/ThreadPlanShouldStopHere.h
new file mode 100644
index 000000000000..62068b78ae4e
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanShouldStopHere.h
@@ -0,0 +1,94 @@
+//===-- ThreadPlanShouldStopHere.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanShouldStopHere_h_
+#define liblldb_ThreadPlanShouldStopHere_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+// This is an interface that ThreadPlans can adopt to allow flexible modifications of the behavior
+// when a thread plan comes to a place where it would ordinarily stop. If such modification makes
+// sense for your plan, inherit from this class, and when you would be about to stop (in your ShouldStop
+// method), call InvokeShouldStopHereCallback, and if that returns a non-NULL plan, execute that
+// plan instead of stopping.
+//
+// The classic example of the use of this is ThreadPlanStepInRange not stopping in frames that have
+// no debug information.
+//
+// This class also defines a set of flags to control general aspects of this "ShouldStop" behavior.
+// A class implementing this protocol needs to define a default set of flags, and can provide access to
+// changing that default flag set if it wishes.
+
+class ThreadPlanShouldStopHere
+{
+public:
+ enum
+ {
+ eNone = 0,
+ eAvoidInlines = (1 << 0),
+ eAvoidNoDebug = (1 << 1)
+ };
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ThreadPlanShouldStopHere (ThreadPlan *owner,
+ ThreadPlanShouldStopHereCallback callback = NULL,
+ void *baton = NULL);
+ virtual
+ ~ThreadPlanShouldStopHere();
+
+ void
+ SetShouldStopHereCallback (ThreadPlanShouldStopHereCallback callback, void *baton);
+
+ lldb::ThreadPlanSP
+ InvokeShouldStopHereCallback ();
+
+ lldb_private::Flags &
+ GetFlags ()
+ {
+ return m_flags;
+ }
+
+ const lldb_private::Flags &
+ GetFlags () const
+ {
+ return m_flags;
+ }
+
+protected:
+ // Implement this, and call it in the plan's constructor to set the default flags.
+ virtual void SetFlagsToDefault () = 0;
+
+ //------------------------------------------------------------------
+ // Classes that inherit from ThreadPlanShouldStopHere can see and modify these
+ //------------------------------------------------------------------
+ ThreadPlanShouldStopHereCallback m_callback;
+ void * m_baton;
+ ThreadPlan *m_owner;
+ lldb_private::Flags m_flags;
+
+private:
+ //------------------------------------------------------------------
+ // For ThreadPlanShouldStopHere only
+ //------------------------------------------------------------------
+
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanShouldStopHere);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanShouldStopHere_h_
diff --git a/include/lldb/Target/ThreadPlanStepInRange.h b/include/lldb/Target/ThreadPlanStepInRange.h
new file mode 100644
index 000000000000..dbc8446b2e18
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanStepInRange.h
@@ -0,0 +1,110 @@
+//===-- ThreadPlanStepInRange.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepInRange_h_
+#define liblldb_ThreadPlanStepInRange_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Target/StackID.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanStepRange.h"
+#include "lldb/Target/ThreadPlanShouldStopHere.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepInRange :
+ public ThreadPlanStepRange,
+ public ThreadPlanShouldStopHere
+{
+public:
+ ThreadPlanStepInRange (Thread &thread,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_others);
+
+ ThreadPlanStepInRange (Thread &thread,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ const char *step_into_function_name,
+ lldb::RunMode stop_others);
+
+ virtual
+ ~ThreadPlanStepInRange ();
+
+ virtual void
+ GetDescription (Stream *s, lldb::DescriptionLevel level);
+
+ virtual bool
+ ShouldStop (Event *event_ptr);
+
+ void SetAvoidRegexp(const char *name);
+
+ void SetStepInTarget (const char *target)
+ {
+ m_step_into_target.SetCString(target);
+ }
+
+ static lldb::ThreadPlanSP
+ DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton);
+
+ static void
+ SetDefaultFlagValue (uint32_t new_value);
+
+ bool
+ IsVirtualStep();
+
+protected:
+ virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan);
+
+ virtual bool
+ DoPlanExplainsStop (Event *event_ptr);
+
+ virtual void
+ SetFlagsToDefault ();
+
+ bool
+ FrameMatchesAvoidRegexp ();
+
+private:
+
+ friend lldb::ThreadPlanSP
+ Thread::QueueThreadPlanForStepOverRange (bool abort_other_plans,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_others);
+ friend lldb::ThreadPlanSP
+ Thread::QueueThreadPlanForStepInRange (bool abort_other_plans,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ const char *step_in_target,
+ lldb::RunMode stop_others,
+ bool avoid_code_without_debug_info);
+
+
+ // Need an appropriate marker for the current stack so we can tell step out
+ // from step in.
+
+ static uint32_t s_default_flag_values;
+ lldb::ThreadPlanSP m_sub_plan_sp; // Keep track of the last plan we were running. If it fails, we should stop.
+ std::unique_ptr<RegularExpression> m_avoid_regexp_ap;
+ bool m_step_past_prologue; // FIXME: For now hard-coded to true, we could put a switch in for this if there's
+ // demand for that.
+ bool m_virtual_step; // true if we've just done a "virtual step", i.e. just moved the inline stack depth.
+ ConstString m_step_into_target;
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepInRange);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepInRange_h_
diff --git a/include/lldb/Target/ThreadPlanStepInstruction.h b/include/lldb/Target/ThreadPlanStepInstruction.h
new file mode 100644
index 000000000000..eb4a64bcbc84
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanStepInstruction.h
@@ -0,0 +1,64 @@
+//===-- ThreadPlanStepInstruction.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepInstruction_h_
+#define liblldb_ThreadPlanStepInstruction_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepInstruction : public ThreadPlan
+{
+public:
+ virtual ~ThreadPlanStepInstruction ();
+
+ virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
+ virtual bool ValidatePlan (Stream *error);
+ virtual bool ShouldStop (Event *event_ptr);
+ virtual bool StopOthers ();
+ virtual lldb::StateType GetPlanRunState ();
+ virtual bool WillStop ();
+ virtual bool MischiefManaged ();
+
+protected:
+ virtual bool DoPlanExplainsStop (Event *event_ptr);
+
+ ThreadPlanStepInstruction (Thread &thread,
+ bool step_over,
+ bool stop_others,
+ Vote stop_vote,
+ Vote run_vote);
+
+private:
+ friend lldb::ThreadPlanSP
+ Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads);
+
+ lldb::addr_t m_instruction_addr;
+ bool m_stop_other_threads;
+ bool m_step_over;
+ // These two are used only for the step over case.
+ bool m_start_has_symbol;
+ StackID m_stack_id;
+ StackID m_parent_frame_id;
+
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepInstruction);
+
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepInstruction_h_
diff --git a/include/lldb/Target/ThreadPlanStepOut.h b/include/lldb/Target/ThreadPlanStepOut.h
new file mode 100644
index 000000000000..2737978a4edc
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanStepOut.h
@@ -0,0 +1,90 @@
+//===-- ThreadPlanStepOut.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepOut_h_
+#define liblldb_ThreadPlanStepOut_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepOut : public ThreadPlan
+{
+public:
+ ThreadPlanStepOut (Thread &thread,
+ SymbolContext *addr_context,
+ bool first_insn,
+ bool stop_others,
+ Vote stop_vote,
+ Vote run_vote,
+ uint32_t frame_idx);
+
+ virtual ~ThreadPlanStepOut ();
+
+ virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
+ virtual bool ValidatePlan (Stream *error);
+ virtual bool ShouldStop (Event *event_ptr);
+ virtual bool StopOthers ();
+ virtual lldb::StateType GetPlanRunState ();
+ virtual bool WillStop ();
+ virtual bool MischiefManaged ();
+ virtual void DidPush();
+ virtual bool IsPlanStale();
+
+ virtual lldb::ValueObjectSP GetReturnValueObject()
+ {
+ return m_return_valobj_sp;
+ }
+
+protected:
+ virtual bool DoPlanExplainsStop (Event *event_ptr);
+ virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan);
+ bool QueueInlinedStepPlan (bool queue_now);
+
+private:
+ SymbolContext *m_step_from_context;
+ lldb::addr_t m_step_from_insn;
+ StackID m_step_out_to_id;
+ StackID m_immediate_step_from_id;
+ lldb::break_id_t m_return_bp_id;
+ lldb::addr_t m_return_addr;
+ bool m_first_insn;
+ bool m_stop_others;
+ lldb::ThreadPlanSP m_step_through_inline_plan_sp;
+ lldb::ThreadPlanSP m_step_out_plan_sp;
+ Function *m_immediate_step_from_function;
+ lldb::ValueObjectSP m_return_valobj_sp;
+
+ friend lldb::ThreadPlanSP
+ Thread::QueueThreadPlanForStepOut (bool abort_other_plans,
+ SymbolContext *addr_context,
+ bool first_insn,
+ bool stop_others,
+ Vote stop_vote,
+ Vote run_vote,
+ uint32_t frame_idx);
+
+ // Need an appropriate marker for the current stack so we can tell step out
+ // from step in.
+
+ void
+ CalculateReturnValue();
+
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOut);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepOut_h_
diff --git a/include/lldb/Target/ThreadPlanStepOverBreakpoint.h b/include/lldb/Target/ThreadPlanStepOverBreakpoint.h
new file mode 100644
index 000000000000..41cac5c9b0b4
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanStepOverBreakpoint.h
@@ -0,0 +1,57 @@
+//===-- ThreadPlanStepOverBreakpoint.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepOverBreakpoint_h_
+#define liblldb_ThreadPlanStepOverBreakpoint_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepOverBreakpoint : public ThreadPlan
+{
+public:
+ virtual ~ThreadPlanStepOverBreakpoint ();
+
+ ThreadPlanStepOverBreakpoint (Thread &thread);
+ virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
+ virtual bool ValidatePlan (Stream *error);
+ virtual bool ShouldStop (Event *event_ptr);
+ virtual bool StopOthers ();
+ virtual lldb::StateType GetPlanRunState ();
+ virtual bool WillStop ();
+ virtual bool MischiefManaged ();
+ virtual void ThreadDestroyed ();
+ void SetAutoContinue (bool do_it);
+ virtual bool ShouldAutoContinue(Event *event_ptr);
+
+protected:
+ virtual bool DoPlanExplainsStop (Event *event_ptr);
+ virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan);
+
+ void ReenableBreakpointSite ();
+private:
+
+ lldb::addr_t m_breakpoint_addr;
+ lldb::user_id_t m_breakpoint_site_id;
+ bool m_auto_continue;
+ bool m_reenabled_breakpoint_site;
+
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOverBreakpoint);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepOverBreakpoint_h_
diff --git a/include/lldb/Target/ThreadPlanStepOverRange.h b/include/lldb/Target/ThreadPlanStepOverRange.h
new file mode 100644
index 000000000000..de9e66829dc7
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanStepOverRange.h
@@ -0,0 +1,52 @@
+//===-- ThreadPlanStepOverRange.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepOverRange_h_
+#define liblldb_ThreadPlanStepOverRange_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Target/StackID.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanStepRange.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepOverRange : public ThreadPlanStepRange
+{
+public:
+
+ ThreadPlanStepOverRange (Thread &thread,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_others);
+
+ virtual ~ThreadPlanStepOverRange ();
+
+ virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
+ virtual bool ShouldStop (Event *event_ptr);
+
+protected:
+ virtual bool DoPlanExplainsStop (Event *event_ptr);
+ virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan);
+
+private:
+
+ bool m_first_resume;
+
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOverRange);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepOverRange_h_
diff --git a/include/lldb/Target/ThreadPlanStepRange.h b/include/lldb/Target/ThreadPlanStepRange.h
new file mode 100644
index 000000000000..486fd6528390
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanStepRange.h
@@ -0,0 +1,94 @@
+//===-- ThreadPlanStepRange.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepRange_h_
+#define liblldb_ThreadPlanStepRange_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Target/StackID.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanShouldStopHere.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepRange : public ThreadPlan
+{
+public:
+ ThreadPlanStepRange (ThreadPlanKind kind,
+ const char *name,
+ Thread &thread,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_others);
+
+ virtual ~ThreadPlanStepRange ();
+
+ virtual void GetDescription (Stream *s, lldb::DescriptionLevel level) = 0;
+ virtual bool ValidatePlan (Stream *error);
+ virtual bool ShouldStop (Event *event_ptr) = 0;
+ virtual Vote ShouldReportStop (Event *event_ptr);
+ virtual bool StopOthers ();
+ virtual lldb::StateType GetPlanRunState ();
+ virtual bool WillStop ();
+ virtual bool MischiefManaged ();
+ virtual void DidPush ();
+ virtual bool IsPlanStale ();
+
+
+ void AddRange(const AddressRange &new_range);
+
+protected:
+
+ bool InRange();
+ lldb::FrameComparison CompareCurrentFrameToStartFrame();
+ bool InSymbol();
+ void DumpRanges (Stream *s);
+
+ Disassembler *
+ GetDisassembler ();
+
+ InstructionList *
+ GetInstructionsForAddress(lldb::addr_t addr, size_t &range_index, size_t &insn_offset);
+
+ // Pushes a plan to proceed through the next section of instructions in the range - usually just a RunToAddress
+ // plan to run to the next branch. Returns true if it pushed such a plan. If there was no available 'quick run'
+ // plan, then just single step.
+ bool
+ SetNextBranchBreakpoint ();
+
+ void
+ ClearNextBranchBreakpoint();
+
+ bool
+ NextRangeBreakpointExplainsStop (lldb::StopInfoSP stop_info_sp);
+
+ SymbolContext m_addr_context;
+ std::vector<AddressRange> m_address_ranges;
+ lldb::RunMode m_stop_others;
+ StackID m_stack_id; // Use the stack ID so we can tell step out from step in.
+ bool m_no_more_plans; // Need this one so we can tell if we stepped into a call,
+ // but can't continue, in which case we are done.
+ bool m_first_run_event; // We want to broadcast only one running event, our first.
+ lldb::BreakpointSP m_next_branch_bp_sp;
+ bool m_use_fast_step;
+
+private:
+ std::vector<lldb::DisassemblerSP> m_instruction_ranges;
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepRange);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepRange_h_
diff --git a/include/lldb/Target/ThreadPlanStepThrough.h b/include/lldb/Target/ThreadPlanStepThrough.h
new file mode 100644
index 000000000000..16979663eb1b
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanStepThrough.h
@@ -0,0 +1,71 @@
+//===-- ThreadPlanStepThrough.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepThrough_h_
+#define liblldb_ThreadPlanStepThrough_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+class ThreadPlanStepThrough : public ThreadPlan
+{
+public:
+ virtual ~ThreadPlanStepThrough ();
+
+ virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
+ virtual bool ValidatePlan (Stream *error);
+ virtual bool ShouldStop (Event *event_ptr);
+ virtual bool StopOthers ();
+ virtual lldb::StateType GetPlanRunState ();
+ virtual bool WillStop ();
+ virtual bool MischiefManaged ();
+ virtual void DidPush();
+
+protected:
+ virtual bool DoPlanExplainsStop (Event *event_ptr);
+ virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan);
+
+ ThreadPlanStepThrough (Thread &thread,
+ StackID &return_stack_id,
+ bool stop_others);
+
+ void
+ LookForPlanToStepThroughFromCurrentPC ();
+
+ bool
+ HitOurBackstopBreakpoint();
+
+private:
+ friend lldb::ThreadPlanSP
+ Thread::QueueThreadPlanForStepThrough (StackID &return_stack_id,
+ bool abort_other_plans,
+ bool stop_others);
+
+ void ClearBackstopBreakpoint();
+
+ lldb::ThreadPlanSP m_sub_plan_sp;
+ lldb::addr_t m_start_address;
+ lldb::break_id_t m_backstop_bkpt_id;
+ lldb::addr_t m_backstop_addr;
+ StackID m_return_stack_id;
+ bool m_stop_others;
+
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepThrough);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepThrough_h_
diff --git a/include/lldb/Target/ThreadPlanStepUntil.h b/include/lldb/Target/ThreadPlanStepUntil.h
new file mode 100644
index 000000000000..5aa3876df53c
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanStepUntil.h
@@ -0,0 +1,80 @@
+//===-- ThreadPlanStepUntil.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanStepUntil_h_
+#define liblldb_ThreadPlanStepUntil_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+
+namespace lldb_private {
+
+
+class ThreadPlanStepUntil : public ThreadPlan
+{
+public:
+ virtual ~ThreadPlanStepUntil ();
+
+ virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
+ virtual bool ValidatePlan (Stream *error);
+ virtual bool ShouldStop (Event *event_ptr);
+ virtual bool StopOthers ();
+ virtual lldb::StateType GetPlanRunState ();
+ virtual bool WillStop ();
+ virtual bool MischiefManaged ();
+
+protected:
+ virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan);
+ virtual bool DoPlanExplainsStop (Event *event_ptr);
+
+ ThreadPlanStepUntil (Thread &thread,
+ lldb::addr_t *address_list,
+ size_t num_addresses,
+ bool stop_others,
+ uint32_t frame_idx = 0);
+ void AnalyzeStop(void);
+
+private:
+
+ StackID m_stack_id;
+ lldb::addr_t m_step_from_insn;
+ lldb::break_id_t m_return_bp_id;
+ lldb::addr_t m_return_addr;
+ bool m_stepped_out;
+ bool m_should_stop;
+ bool m_ran_analyze;
+ bool m_explains_stop;
+
+ typedef std::map<lldb::addr_t,lldb::break_id_t> until_collection;
+ until_collection m_until_points;
+ bool m_stop_others;
+
+ void Clear();
+
+ friend lldb::ThreadPlanSP
+ Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
+ lldb::addr_t *address_list,
+ size_t num_addresses,
+ bool stop_others,
+ uint32_t frame_idx);
+
+ // Need an appropriate marker for the current stack so we can tell step out
+ // from step in.
+
+ DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepUntil);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanStepUntil_h_
diff --git a/include/lldb/Target/ThreadPlanTracer.h b/include/lldb/Target/ThreadPlanTracer.h
new file mode 100644
index 000000000000..4eb0c783e57d
--- /dev/null
+++ b/include/lldb/Target/ThreadPlanTracer.h
@@ -0,0 +1,131 @@
+//===-- ThreadPlanTracer.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanTracer_h_
+#define liblldb_ThreadPlanTracer_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/Target/Thread.h"
+
+namespace lldb_private {
+
+class ThreadPlanTracer
+{
+friend class ThreadPlan;
+
+public:
+
+ typedef enum ThreadPlanTracerStyle
+ {
+ eLocation = 0,
+ eStateChange,
+ eCheckFrames,
+ ePython
+ } ThreadPlanTracerStyle;
+ ThreadPlanTracer (Thread &thread, lldb::StreamSP &stream_sp);
+ ThreadPlanTracer (Thread &thread);
+
+ virtual ~ThreadPlanTracer()
+ {
+ }
+
+ virtual void TracingStarted ()
+ {
+
+ }
+
+ virtual void TracingEnded ()
+ {
+
+ }
+
+ bool
+ EnableTracing(bool value)
+ {
+ bool old_value = m_enabled;
+ m_enabled = value;
+ if (old_value == false && value == true)
+ TracingStarted();
+ else if (old_value == true && value == false)
+ TracingEnded();
+
+ return old_value;
+ }
+
+ bool
+ TracingEnabled()
+ {
+ return m_enabled;
+ }
+
+ bool
+ EnableSingleStep (bool value)
+ {
+ bool old_value = m_single_step;
+ m_single_step = value;
+ return old_value;
+ }
+
+ bool
+ SingleStepEnabled ()
+ {
+ return m_single_step;
+ }
+
+protected:
+ Thread &m_thread;
+
+ Stream *
+ GetLogStream ();
+
+
+
+ virtual void Log();
+
+private:
+ bool
+ TracerExplainsStop ();
+
+ bool m_single_step;
+ bool m_enabled;
+ lldb::StreamSP m_stream_sp;
+};
+
+class ThreadPlanAssemblyTracer : public ThreadPlanTracer
+{
+public:
+ ThreadPlanAssemblyTracer (Thread &thread, lldb::StreamSP &stream_sp);
+ ThreadPlanAssemblyTracer (Thread &thread);
+ virtual ~ThreadPlanAssemblyTracer ();
+ virtual void TracingStarted ();
+ virtual void TracingEnded ();
+ virtual void Log();
+private:
+
+ Disassembler *
+ GetDisassembler ();
+
+ TypeFromUser
+ GetIntPointerType();
+
+ lldb::DisassemblerSP m_disassembler_sp;
+ TypeFromUser m_intptr_type;
+ std::vector<RegisterValue> m_register_values;
+ lldb::DataBufferSP m_buffer_sp;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadPlanTracer_h_
diff --git a/include/lldb/Target/ThreadSpec.h b/include/lldb/Target/ThreadSpec.h
new file mode 100644
index 000000000000..e0d30934f373
--- /dev/null
+++ b/include/lldb/Target/ThreadSpec.h
@@ -0,0 +1,155 @@
+//===-- ThreadSpec.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadSpec_h_
+#define liblldb_ThreadSpec_h_
+
+#include <map>
+#include <string>
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// Note: For now the thread spec has only fixed elements -
+// Thread ID
+// Thread Index
+// Thread Name
+// Thread Queue Name
+//
+// But if we need more generality, we can hang a key/value map off of this structure.
+// That's why the thread matches spec test is done as a virtual method in Thread::MatchesSpec,
+// since it is the native thread that would know how to interpret the keys.
+// I was going to do the Queue Name this way out of sheer orneriness, but that seems a
+// sufficiently general concept, so I put it in here on its own.
+
+class ThreadSpec
+{
+public:
+ ThreadSpec ();
+
+ ThreadSpec (const ThreadSpec &rhs);
+
+ const ThreadSpec &
+ operator=(const ThreadSpec &rhs);
+
+ void
+ SetIndex (uint32_t index)
+ {
+ m_index = index;
+ }
+
+ void
+ SetTID (lldb::tid_t tid)
+ {
+ m_tid = tid;
+ }
+
+ void
+ SetName (const char *name)
+ {
+ m_name = name;
+ }
+
+ void
+ SetQueueName (const char *queue_name)
+ {
+ m_queue_name = queue_name;
+ }
+
+ uint32_t
+ GetIndex () const
+ {
+ return m_index;
+ }
+
+ lldb::tid_t
+ GetTID () const
+ {
+ return m_tid;
+ }
+
+ const char *
+ GetName () const;
+
+ const char *
+ GetQueueName () const;
+
+ bool
+ TIDMatches (lldb::tid_t thread_id) const
+ {
+ if (m_tid == LLDB_INVALID_THREAD_ID || thread_id == LLDB_INVALID_THREAD_ID)
+ return true;
+ else
+ return thread_id == m_tid;
+ }
+
+ bool
+ TIDMatches (Thread &thread) const;
+
+ bool
+ IndexMatches (uint32_t index) const
+ {
+ if (m_index == UINT32_MAX || index == UINT32_MAX)
+ return true;
+ else
+ return index == m_index;
+ }
+
+ bool
+ IndexMatches (Thread &thread) const;
+
+ bool
+ NameMatches (const char *name) const
+ {
+ if (m_name.empty())
+ return true;
+ else if (name == NULL)
+ return false;
+ else
+ return m_name == name;
+ }
+
+ bool
+ NameMatches (Thread &thread) const;
+
+ bool
+ QueueNameMatches (const char *queue_name) const
+ {
+ if (m_queue_name.empty())
+ return true;
+ else if (queue_name == NULL)
+ return false;
+ else
+ return m_queue_name == queue_name;
+ }
+
+ bool
+ QueueNameMatches (Thread &thread) const;
+
+ bool
+ ThreadPassesBasicTests (Thread &thread) const;
+
+ bool
+ HasSpecification () const;
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+protected:
+private:
+ uint32_t m_index;
+ lldb::tid_t m_tid;
+ std::string m_name;
+ std::string m_queue_name;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadSpec_h_
diff --git a/include/lldb/Target/UnixSignals.h b/include/lldb/Target/UnixSignals.h
new file mode 100644
index 000000000000..f47a90bbf545
--- /dev/null
+++ b/include/lldb/Target/UnixSignals.h
@@ -0,0 +1,144 @@
+//===-- UnixSignals.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_UnixSignals_h_
+#define lldb_UnixSignals_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <map>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ConstString.h"
+
+namespace lldb_private
+{
+
+class UnixSignals
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ UnixSignals();
+
+ virtual
+ ~UnixSignals();
+
+ const char *
+ GetSignalAsCString (int32_t signo) const;
+
+ bool
+ SignalIsValid (int32_t signo) const;
+
+ int32_t
+ GetSignalNumberFromName (const char *name) const;
+
+ const char *
+ GetSignalInfo (int32_t signo,
+ bool &should_suppress,
+ bool &should_stop,
+ bool &should_notify) const;
+
+ bool
+ GetShouldSuppress (int32_t signo) const;
+
+ bool
+ SetShouldSuppress (int32_t signo,
+ bool value);
+
+ bool
+ SetShouldSuppress (const char *signal_name,
+ bool value);
+
+ bool
+ GetShouldStop (int32_t signo) const;
+
+ bool
+ SetShouldStop (int32_t signo,
+ bool value);
+ bool
+ SetShouldStop (const char *signal_name,
+ bool value);
+
+ bool
+ GetShouldNotify (int32_t signo) const;
+
+ bool
+ SetShouldNotify (int32_t signo, bool value);
+
+ bool
+ SetShouldNotify (const char *signal_name,
+ bool value);
+
+ // These provide an iterator through the signals available on this system.
+ // Call GetFirstSignalNumber to get the first entry, then iterate on GetNextSignalNumber
+ // till you get back LLDB_INVALID_SIGNAL_NUMBER.
+ int32_t
+ GetFirstSignalNumber () const;
+
+ int32_t
+ GetNextSignalNumber (int32_t current_signal) const;
+
+ // We assume that the elements of this object are constant once it is constructed,
+ // since a process should never need to add or remove symbols as it runs. So don't
+ // call these functions anywhere but the constructor of your subclass of UnixSignals or in
+ // your Process Plugin's GetUnixSignals method before you return the UnixSignal object.
+
+ void
+ AddSignal (int signo,
+ const char *name,
+ const char *short_name,
+ bool default_suppress,
+ bool default_stop,
+ bool default_notify,
+ const char *description);
+
+ void
+ RemoveSignal (int signo);
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from UnixSignals can see and modify these
+ //------------------------------------------------------------------
+
+ struct Signal
+ {
+ ConstString m_name;
+ ConstString m_short_name;
+ std::string m_description;
+ bool m_suppress:1,
+ m_stop:1,
+ m_notify:1;
+
+ Signal (const char *name,
+ const char *short_name,
+ bool default_suppress,
+ bool default_stop,
+ bool default_notify,
+ const char *description);
+
+ ~Signal () {}
+ };
+
+ void
+ Reset ();
+
+ typedef std::map <int32_t, Signal> collection;
+
+ collection m_signals;
+
+ DISALLOW_COPY_AND_ASSIGN (UnixSignals);
+};
+
+} // Namespace lldb
+#endif // lldb_UnixSignals_h_
diff --git a/include/lldb/Target/Unwind.h b/include/lldb/Target/Unwind.h
new file mode 100644
index 000000000000..7cda4aeb2e18
--- /dev/null
+++ b/include/lldb/Target/Unwind.h
@@ -0,0 +1,120 @@
+//===-- Unwind.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Unwind_h_
+#define liblldb_Unwind_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+class Unwind
+{
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from Unwind can see and modify these
+ //------------------------------------------------------------------
+ Unwind(Thread &thread) :
+ m_thread (thread),
+ m_unwind_mutex()
+ {
+ }
+
+public:
+ virtual
+ ~Unwind()
+ {
+ }
+
+ void
+ Clear()
+ {
+ Mutex::Locker locker(m_unwind_mutex);
+ DoClear();
+
+ }
+
+ uint32_t
+ GetFrameCount()
+ {
+ Mutex::Locker locker(m_unwind_mutex);
+ return DoGetFrameCount();
+ }
+
+ uint32_t
+ GetFramesUpTo (uint32_t end_idx)
+ {
+ lldb::addr_t cfa;
+ lldb::addr_t pc;
+ uint32_t idx;
+
+ for (idx = 0; idx < end_idx; idx++)
+ {
+ if (!DoGetFrameInfoAtIndex (idx, cfa, pc))
+ {
+ break;
+ }
+ }
+ return idx;
+ }
+
+ bool
+ GetFrameInfoAtIndex (uint32_t frame_idx,
+ lldb::addr_t& cfa,
+ lldb::addr_t& pc)
+ {
+ Mutex::Locker locker(m_unwind_mutex);
+ return DoGetFrameInfoAtIndex (frame_idx, cfa, pc);
+ }
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame (StackFrame *frame)
+ {
+ Mutex::Locker locker(m_unwind_mutex);
+ return DoCreateRegisterContextForFrame (frame);
+ }
+
+ Thread &
+ GetThread()
+ {
+ return m_thread;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from Unwind can see and modify these
+ //------------------------------------------------------------------
+ virtual void
+ DoClear() = 0;
+
+ virtual uint32_t
+ DoGetFrameCount() = 0;
+
+ virtual bool
+ DoGetFrameInfoAtIndex (uint32_t frame_idx,
+ lldb::addr_t& cfa,
+ lldb::addr_t& pc) = 0;
+
+ virtual lldb::RegisterContextSP
+ DoCreateRegisterContextForFrame (StackFrame *frame) = 0;
+
+ Thread &m_thread;
+ Mutex m_unwind_mutex;
+private:
+ DISALLOW_COPY_AND_ASSIGN (Unwind);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Unwind_h_
diff --git a/include/lldb/Target/UnwindAssembly.h b/include/lldb/Target/UnwindAssembly.h
new file mode 100644
index 000000000000..6a4ae0c30f27
--- /dev/null
+++ b/include/lldb/Target/UnwindAssembly.h
@@ -0,0 +1,58 @@
+//===-- UnwindAssembly.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_UnwindAssembly_h_
+#define utility_UnwindAssembly_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/PluginInterface.h"
+
+namespace lldb_private {
+
+class UnwindAssembly :
+ public PluginInterface
+{
+public:
+ static UnwindAssembly*
+ FindPlugin (const ArchSpec &arch);
+
+ virtual
+ ~UnwindAssembly();
+
+ virtual bool
+ GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func,
+ Thread& thread,
+ UnwindPlan& unwind_plan) = 0;
+
+ virtual bool
+ GetFastUnwindPlan (AddressRange& func,
+ Thread& thread,
+ UnwindPlan &unwind_plan) = 0;
+
+ // thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
+ virtual bool
+ FirstNonPrologueInsn (AddressRange& func,
+ const lldb_private::ExecutionContext &exe_ctx,
+ Address& first_non_prologue_insn) = 0;
+
+protected:
+ UnwindAssembly (const ArchSpec &arch);
+ ArchSpec m_arch;
+
+private:
+ UnwindAssembly(); // Outlaw default constructor
+ DISALLOW_COPY_AND_ASSIGN (UnwindAssembly);
+};
+
+} // namespace lldb_private
+
+#endif //utility_UnwindAssembly_h_
+
+
diff --git a/include/lldb/Utility/AnsiTerminal.h b/include/lldb/Utility/AnsiTerminal.h
new file mode 100644
index 000000000000..036950c1bd45
--- /dev/null
+++ b/include/lldb/Utility/AnsiTerminal.h
@@ -0,0 +1,156 @@
+//===---------------------AnsiTerminal.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+
+#define ANSI_FG_COLOR_BLACK 30
+#define ANSI_FG_COLOR_RED 31
+#define ANSI_FG_COLOR_GREEN 32
+#define ANSI_FG_COLOR_YELLOW 33
+#define ANSI_FG_COLOR_BLUE 34
+#define ANSI_FG_COLOR_PURPLE 35
+#define ANSI_FG_COLOR_CYAN 36
+#define ANSI_FG_COLOR_WHITE 37
+
+#define ANSI_BG_COLOR_BLACK 40
+#define ANSI_BG_COLOR_RED 41
+#define ANSI_BG_COLOR_GREEN 42
+#define ANSI_BG_COLOR_YELLOW 43
+#define ANSI_BG_COLOR_BLUE 44
+#define ANSI_BG_COLOR_PURPLE 45
+#define ANSI_BG_COLOR_CYAN 46
+#define ANSI_BG_COLOR_WHITE 47
+
+#define ANSI_SPECIAL_FRAMED 51
+#define ANSI_SPECIAL_ENCIRCLED 52
+
+#define ANSI_CTRL_NORMAL 0
+#define ANSI_CTRL_BOLD 1
+#define ANSI_CTRL_FAINT 2
+#define ANSI_CTRL_ITALIC 3
+#define ANSI_CTRL_UNDERLINE 4
+#define ANSI_CTRL_SLOW_BLINK 5
+#define ANSI_CTRL_FAST_BLINK 6
+#define ANSI_CTRL_IMAGE_NEGATIVE 7
+#define ANSI_CTRL_CONCEAL 8
+#define ANSI_CTRL_CROSSED_OUT 9
+
+#define ANSI_ESC_START "\033["
+#define ANSI_ESC_END "m"
+
+#define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END
+#define ANSI_2_CTRL(ctrl1,ctrl2) "\033["##ctrl1";"##ctrl2 ANSI_ESC_END
+
+namespace lldb_utility {
+
+ namespace ansi {
+ const char *k_escape_start = "\033[";
+ const char *k_escape_end = "m";
+
+ const char *k_fg_black = "30";
+ const char *k_fg_red = "31";
+ const char *k_fg_green = "32";
+ const char *k_fg_yellow = "33";
+ const char *k_fg_blue = "34";
+ const char *k_fg_purple = "35";
+ const char *k_fg_cyan = "36";
+ const char *k_fg_white = "37";
+
+ const char *k_bg_black = "40";
+ const char *k_bg_red = "41";
+ const char *k_bg_green = "42";
+ const char *k_bg_yellow = "43";
+ const char *k_bg_blue = "44";
+ const char *k_bg_purple = "45";
+ const char *k_bg_cyan = "46";
+ const char *k_bg_white = "47";
+
+ const char *k_ctrl_normal = "0";
+ const char *k_ctrl_bold = "1";
+ const char *k_ctrl_faint = "2";
+ const char *k_ctrl_italic = "3";
+ const char *k_ctrl_underline = "4";
+ const char *k_ctrl_slow_blink = "5";
+ const char *k_ctrl_fast_blink = "6";
+ const char *k_ctrl_negative = "7";
+ const char *k_ctrl_conceal = "8";
+ const char *k_ctrl_crossed_out = "9";
+
+ inline std::string
+ FormatAnsiTerminalCodes(const char *format, bool do_color = true)
+ {
+ // Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is false.
+ static const struct
+ {
+ const char *name;
+ const char *value;
+ } g_color_tokens[] =
+ {
+ #define _TO_STR2(_val) #_val
+ #define _TO_STR(_val) _TO_STR2(_val)
+ { "fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END },
+ { "fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END },
+ { "fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END },
+ { "fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END },
+ { "fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END },
+ { "fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END },
+ { "fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END },
+ { "fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END },
+ { "bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END },
+ { "bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END },
+ { "bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END },
+ { "bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END },
+ { "bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END },
+ { "bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END },
+ { "bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END },
+ { "bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END },
+ { "normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END },
+ { "bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END },
+ { "faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END },
+ { "italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END },
+ { "underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END },
+ { "slow-blink}", ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END },
+ { "fast-blink}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END },
+ { "negative}", ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END },
+ { "conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END },
+ { "crossed-out}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END },
+ #undef _TO_STR
+ #undef _TO_STR2
+ };
+ static const char tok_hdr[] = "${ansi.";
+
+ std::string fmt;
+ for (const char *p = format; *p; ++p)
+ {
+ const char *tok_start = strstr (p, tok_hdr);
+ if (!tok_start)
+ {
+ fmt.append (p, strlen(p));
+ break;
+ }
+
+ fmt.append (p, tok_start - p);
+ p = tok_start;
+
+ const char *tok_str = tok_start + sizeof(tok_hdr) - 1;
+ for (size_t i = 0; i < sizeof(g_color_tokens) / sizeof(g_color_tokens[0]); ++i)
+ {
+ if (!strncmp (tok_str, g_color_tokens[i].name, strlen(g_color_tokens[i].name)))
+ {
+ if (do_color)
+ fmt.append (g_color_tokens[i].value);
+ p = tok_str + strlen (g_color_tokens[i].name) - 1;
+ break;
+ }
+ }
+ }
+ return fmt;
+ }
+ }
+}
diff --git a/include/lldb/Utility/CleanUp.h b/include/lldb/Utility/CleanUp.h
new file mode 100644
index 000000000000..ab15d1999b7d
--- /dev/null
+++ b/include/lldb/Utility/CleanUp.h
@@ -0,0 +1,322 @@
+//===-- CleanUp.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CleanUp_h_
+#define liblldb_CleanUp_h_
+
+#include "lldb/lldb-public.h"
+
+namespace lldb_utility {
+
+//----------------------------------------------------------------------
+// Templated class that guarantees that a cleanup callback function will
+// be called. The cleanup function will be called once under the
+// following conditions:
+// - when the object goes out of scope
+// - when the user explicitly calls clean.
+// - the current value will be cleaned up when a new value is set using
+// set(T value) as long as the current value hasn't already been cleaned.
+//
+// This class is designed to be used with simple types for type T (like
+// file descriptors, opaque handles, pointers, etc). If more complex
+// type T objects are desired, we need to probably specialize this class
+// to take "const T&" for all input T parameters. Yet if a type T is
+// complex already it might be better to build the cleanup funcionality
+// into T.
+//
+// The cleanup function must take one argument that is of type T.
+// The calback function return type is R. The return value is currently
+// needed for "CallbackType". If there is an easy way to get around the
+// need for the return value we can change this class.
+//
+// The two template parameters are:
+// T - The variable type of value that will be stored and used as the
+// sole argument for the cleanup callback.
+// R - The return type for the cleanup function.
+//
+// EXAMPLES
+// // Use with file handles that get opened where you want to close
+// // them. Below we use "int open(const char *path, int oflag, ...)"
+// // which returns an integer file descriptor. -1 is the invalid file
+// // descriptor so to make an object that will call "int close(int fd)"
+// // automatically we can use:
+//
+// CleanUp <int, int> fd(open("/tmp/a.txt", O_RDONLY, 0), -1, close);
+//
+// // malloc/free example
+// CleanUp <void *, void> malloced_bytes(malloc(32), NULL, free);
+//----------------------------------------------------------------------
+template <typename T, typename R = void>
+class CleanUp
+{
+public:
+ typedef T value_type;
+ typedef R (*CallbackType)(value_type);
+
+ //----------------------------------------------------------------------
+ // Constructor that sets the current value only. No values are
+ // considered to be invalid and the cleanup function will be called
+ // regardless of the value of m_current_value.
+ //----------------------------------------------------------------------
+ CleanUp (value_type value, CallbackType callback) :
+ m_current_value (value),
+ m_invalid_value (),
+ m_callback (callback),
+ m_callback_called (false),
+ m_invalid_value_is_valid (false)
+ {
+ }
+
+ //----------------------------------------------------------------------
+ // Constructor that sets the current value and also the invalid value.
+ // The cleanup function will be called on "m_value" as long as it isn't
+ // equal to "m_invalid_value".
+ //----------------------------------------------------------------------
+ CleanUp (value_type value, value_type invalid, CallbackType callback) :
+ m_current_value (value),
+ m_invalid_value (invalid),
+ m_callback (callback),
+ m_callback_called (false),
+ m_invalid_value_is_valid (true)
+ {
+ }
+
+ //----------------------------------------------------------------------
+ // Automatically cleanup when this object goes out of scope.
+ //----------------------------------------------------------------------
+ ~CleanUp ()
+ {
+ clean();
+ }
+
+ //----------------------------------------------------------------------
+ // Access the value stored in this class
+ //----------------------------------------------------------------------
+ value_type get()
+ {
+ return m_current_value;
+ }
+
+ //----------------------------------------------------------------------
+ // Access the value stored in this class
+ //----------------------------------------------------------------------
+ const value_type
+ get() const
+ {
+ return m_current_value;
+ }
+
+ //----------------------------------------------------------------------
+ // Reset the owned value to "value". If a current value is valid and
+ // the cleanup callback hasn't been called, the previous value will
+ // be cleaned up (see void CleanUp::clean()).
+ //----------------------------------------------------------------------
+ void
+ set (const value_type value)
+ {
+ // Cleanup the current value if needed
+ clean ();
+ // Now set the new value and mark our callback as not called
+ m_callback_called = false;
+ m_current_value = value;
+ }
+
+ //----------------------------------------------------------------------
+ // Checks is "m_current_value" is valid. The value is considered valid
+ // no invalid value was supplied during construction of this object or
+ // if an invalid value was supplied and "m_current_value" is not equal
+ // to "m_invalid_value".
+ //
+ // Returns true if "m_current_value" is valid, false otherwise.
+ //----------------------------------------------------------------------
+ bool
+ is_valid() const
+ {
+ if (m_invalid_value_is_valid)
+ return m_current_value != m_invalid_value;
+ return true;
+ }
+
+ //----------------------------------------------------------------------
+ // This function will call the cleanup callback provided in the
+ // constructor one time if the value is considered valid (See is_valid()).
+ // This function sets m_callback_called to true so we don't call the
+ // cleanup callback multiple times on the same value.
+ //----------------------------------------------------------------------
+ void
+ clean()
+ {
+ if (m_callback && !m_callback_called)
+ {
+ m_callback_called = true;
+ if (is_valid())
+ m_callback(m_current_value);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Cancels the cleanup that would have been called on "m_current_value"
+ // if it was valid. This function can be used to release the value
+ // contained in this object so ownership can be transfered to the caller.
+ //----------------------------------------------------------------------
+ value_type
+ release ()
+ {
+ m_callback_called = true;
+ return m_current_value;
+ }
+
+private:
+ value_type m_current_value;
+ const value_type m_invalid_value;
+ CallbackType m_callback;
+ bool m_callback_called;
+ bool m_invalid_value_is_valid;
+
+ // Outlaw default constructor, copy constructor and the assignment operator
+ DISALLOW_COPY_AND_ASSIGN (CleanUp);
+};
+
+template <typename T, typename R, typename A0>
+class CleanUp2
+{
+public:
+ typedef T value_type;
+ typedef R (*CallbackType)(value_type, A0);
+
+ //----------------------------------------------------------------------
+ // Constructor that sets the current value only. No values are
+ // considered to be invalid and the cleanup function will be called
+ // regardless of the value of m_current_value.
+ //----------------------------------------------------------------------
+ CleanUp2 (value_type value, CallbackType callback, A0 arg) :
+ m_current_value (value),
+ m_invalid_value (),
+ m_callback (callback),
+ m_callback_called (false),
+ m_invalid_value_is_valid (false),
+ m_argument(arg)
+ {
+ }
+
+ //----------------------------------------------------------------------
+ // Constructor that sets the current value and also the invalid value.
+ // The cleanup function will be called on "m_value" as long as it isn't
+ // equal to "m_invalid_value".
+ //----------------------------------------------------------------------
+ CleanUp2 (value_type value, value_type invalid, CallbackType callback, A0 arg) :
+ m_current_value (value),
+ m_invalid_value (invalid),
+ m_callback (callback),
+ m_callback_called (false),
+ m_invalid_value_is_valid (true),
+ m_argument(arg)
+ {
+ }
+
+ //----------------------------------------------------------------------
+ // Automatically cleanup when this object goes out of scope.
+ //----------------------------------------------------------------------
+ ~CleanUp2 ()
+ {
+ clean();
+ }
+
+ //----------------------------------------------------------------------
+ // Access the value stored in this class
+ //----------------------------------------------------------------------
+ value_type get()
+ {
+ return m_current_value;
+ }
+
+ //----------------------------------------------------------------------
+ // Access the value stored in this class
+ //----------------------------------------------------------------------
+ const value_type
+ get() const
+ {
+ return m_current_value;
+ }
+
+ //----------------------------------------------------------------------
+ // Reset the owned value to "value". If a current value is valid and
+ // the cleanup callback hasn't been called, the previous value will
+ // be cleaned up (see void CleanUp::clean()).
+ //----------------------------------------------------------------------
+ void
+ set (const value_type value)
+ {
+ // Cleanup the current value if needed
+ clean ();
+ // Now set the new value and mark our callback as not called
+ m_callback_called = false;
+ m_current_value = value;
+ }
+
+ //----------------------------------------------------------------------
+ // Checks is "m_current_value" is valid. The value is considered valid
+ // no invalid value was supplied during construction of this object or
+ // if an invalid value was supplied and "m_current_value" is not equal
+ // to "m_invalid_value".
+ //
+ // Returns true if "m_current_value" is valid, false otherwise.
+ //----------------------------------------------------------------------
+ bool
+ is_valid() const
+ {
+ if (m_invalid_value_is_valid)
+ return m_current_value != m_invalid_value;
+ return true;
+ }
+
+ //----------------------------------------------------------------------
+ // This function will call the cleanup callback provided in the
+ // constructor one time if the value is considered valid (See is_valid()).
+ // This function sets m_callback_called to true so we don't call the
+ // cleanup callback multiple times on the same value.
+ //----------------------------------------------------------------------
+ void
+ clean()
+ {
+ if (m_callback && !m_callback_called)
+ {
+ m_callback_called = true;
+ if (is_valid())
+ m_callback(m_current_value, m_argument);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Cancels the cleanup that would have been called on "m_current_value"
+ // if it was valid. This function can be used to release the value
+ // contained in this object so ownership can be transfered to the caller.
+ //----------------------------------------------------------------------
+ value_type
+ release ()
+ {
+ m_callback_called = true;
+ return m_current_value;
+ }
+
+private:
+ value_type m_current_value;
+ const value_type m_invalid_value;
+ CallbackType m_callback;
+ bool m_callback_called;
+ bool m_invalid_value_is_valid;
+ A0 m_argument;
+
+ // Outlaw default constructor, copy constructor and the assignment operator
+ DISALLOW_COPY_AND_ASSIGN (CleanUp2);
+};
+
+} // namespace lldb_utility
+
+#endif // #ifndef liblldb_CleanUp_h_
diff --git a/include/lldb/Utility/PriorityPointerPair.h b/include/lldb/Utility/PriorityPointerPair.h
new file mode 100644
index 000000000000..49f0765d0f96
--- /dev/null
+++ b/include/lldb/Utility/PriorityPointerPair.h
@@ -0,0 +1,150 @@
+//===-- PriorityPointerPair.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_PriorityPointerPair_h_
+#define liblldb_PriorityPointerPair_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Utility/SharingPtr.h"
+
+namespace lldb_utility {
+
+//----------------------------------------------------------------------
+// A prioritized pair of SharedPtr<T>. One of the two pointers is high
+// priority, the other is low priority.
+// The Get() method always returns high, if *high != NULL,
+// otherwise, low is returned (even if *low == NULL)
+//----------------------------------------------------------------------
+
+template<typename T>
+class PriorityPointerPair
+{
+public:
+
+ typedef T& reference_type;
+ typedef T* pointer_type;
+
+ typedef typename std::shared_ptr<T> T_SP;
+
+ PriorityPointerPair() :
+ m_high(),
+ m_low()
+ {}
+
+ PriorityPointerPair(pointer_type high,
+ pointer_type low) :
+ m_high(high),
+ m_low(low)
+ {}
+
+ PriorityPointerPair(pointer_type low) :
+ m_high(),
+ m_low(low)
+ {}
+
+ PriorityPointerPair(T_SP& high,
+ T_SP& low) :
+ m_high(high),
+ m_low(low)
+ {}
+
+ PriorityPointerPair(T_SP& low) :
+ m_high(),
+ m_low(low)
+ {}
+
+ void
+ SwapLow(pointer_type l)
+ {
+ m_low.swap(l);
+ }
+
+ void
+ SwapHigh(pointer_type h)
+ {
+ m_high.swap(h);
+ }
+
+ void
+ SwapLow(T_SP l)
+ {
+ m_low.swap(l);
+ }
+
+ void
+ SwapHigh(T_SP h)
+ {
+ m_high.swap(h);
+ }
+
+ T_SP
+ GetLow()
+ {
+ return m_low;
+ }
+
+ T_SP
+ GetHigh()
+ {
+ return m_high;
+ }
+
+ T_SP
+ Get()
+ {
+ if (m_high.get())
+ return m_high;
+ return m_low;
+ }
+
+ void
+ ResetHigh()
+ {
+ m_high.reset();
+ }
+
+ void
+ ResetLow()
+ {
+ m_low.reset();
+ }
+
+ void
+ Reset()
+ {
+ ResetLow();
+ ResetHigh();
+ }
+
+ reference_type
+ operator*() const
+ {
+ return Get().operator*();
+ }
+
+ pointer_type
+ operator->() const
+ {
+ return Get().operator->();
+ }
+
+ ~PriorityPointerPair();
+
+private:
+
+ T_SP m_high;
+ T_SP m_low;
+
+ DISALLOW_COPY_AND_ASSIGN (PriorityPointerPair);
+
+};
+
+} // namespace lldb_utility
+
+#endif // #ifndef liblldb_PriorityPointerPair_h_
diff --git a/include/lldb/Utility/PseudoTerminal.h b/include/lldb/Utility/PseudoTerminal.h
new file mode 100644
index 000000000000..c79800fab75c
--- /dev/null
+++ b/include/lldb/Utility/PseudoTerminal.h
@@ -0,0 +1,266 @@
+//===-- PseudoTerminal.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_PseudoTerminal_h_
+#define liblldb_PseudoTerminal_h_
+#if defined(__cplusplus)
+
+
+#include <fcntl.h>
+#include <string>
+
+#include "lldb/lldb-defines.h"
+
+namespace lldb_utility {
+
+//----------------------------------------------------------------------
+/// @class PseudoTerminal PseudoTerminal.h "lldb/Core/PseudoTerminal.h"
+/// @brief A pseudo terminal helper class.
+///
+/// The pseudo terminal class abtracts the use of pseudo terminals on
+/// the host system.
+//----------------------------------------------------------------------
+class PseudoTerminal
+{
+public:
+ enum
+ {
+ invalid_fd = -1 ///< Invalid file descriptor value
+ };
+
+ //------------------------------------------------------------------
+ /// Default constructor
+ ///
+ /// Constructs this object with invalid master and slave file
+ /// descriptors.
+ //------------------------------------------------------------------
+ PseudoTerminal ();
+
+ //------------------------------------------------------------------
+ /// Destructor
+ ///
+ /// The destructor will close the master and slave file descriptors
+ /// if they are valid and ownwership has not been released using
+ /// one of:
+ /// @li PseudoTerminal::ReleaseMasterFileDescriptor()
+ /// @li PseudoTerminal::ReleaseSaveFileDescriptor()
+ //------------------------------------------------------------------
+ ~PseudoTerminal ();
+
+ //------------------------------------------------------------------
+ /// Close the master file descriptor if it is valid.
+ //------------------------------------------------------------------
+ void
+ CloseMasterFileDescriptor ();
+
+ //------------------------------------------------------------------
+ /// Close the slave file descriptor if it is valid.
+ //------------------------------------------------------------------
+ void
+ CloseSlaveFileDescriptor ();
+
+ //------------------------------------------------------------------
+ /// Fork a child process that uses pseudo terminals for its stdio.
+ ///
+ /// In the parent process, a call to this function results in a pid
+ /// being returned. If the pid is valid, the master file descriptor
+ /// can be used for read/write access to stdio of the child process.
+ ///
+ /// In the child process the stdin/stdout/stderr will already be
+ /// routed to the slave pseudo terminal and the master file
+ /// descriptor will be closed as it is no longer needed by the child
+ /// process.
+ ///
+ /// This class will close the file descriptors for the master/slave
+ /// when the destructor is called. The file handles can be released
+ /// using either:
+ /// @li PseudoTerminal::ReleaseMasterFileDescriptor()
+ /// @li PseudoTerminal::ReleaseSaveFileDescriptor()
+ ///
+ /// @param[out] error
+ /// An pointer to an error that can describe any errors that
+ /// occur. This can be NULL if no error status is desired.
+ ///
+ /// @return
+ /// @li \b Parent process: a child process ID that is greater
+ /// than zero, or -1 if the fork fails.
+ /// @li \b Child process: zero.
+ //------------------------------------------------------------------
+ lldb::pid_t
+ Fork (char *error_str, size_t error_len);
+
+ //------------------------------------------------------------------
+ /// The master file descriptor accessor.
+ ///
+ /// This object retains ownership of the master file descriptor when
+ /// this accessor is used. Users can call the member function
+ /// PseudoTerminal::ReleaseMasterFileDescriptor() if this
+ /// object should release ownership of the slave file descriptor.
+ ///
+ /// @return
+ /// The master file descriptor, or PseudoTerminal::invalid_fd
+ /// if the master file descriptor is not currently valid.
+ ///
+ /// @see PseudoTerminal::ReleaseMasterFileDescriptor()
+ //------------------------------------------------------------------
+ int
+ GetMasterFileDescriptor () const;
+
+ //------------------------------------------------------------------
+ /// The slave file descriptor accessor.
+ ///
+ /// This object retains ownership of the slave file descriptor when
+ /// this accessor is used. Users can call the member function
+ /// PseudoTerminal::ReleaseSlaveFileDescriptor() if this
+ /// object should release ownership of the slave file descriptor.
+ ///
+ /// @return
+ /// The slave file descriptor, or PseudoTerminal::invalid_fd
+ /// if the slave file descriptor is not currently valid.
+ ///
+ /// @see PseudoTerminal::ReleaseSlaveFileDescriptor()
+ //------------------------------------------------------------------
+ int
+ GetSlaveFileDescriptor () const;
+
+ //------------------------------------------------------------------
+ /// Get the name of the slave pseudo terminal.
+ ///
+ /// A master pseudo terminal should already be valid prior to
+ /// calling this function.
+ ///
+ /// @param[out] error
+ /// An pointer to an error that can describe any errors that
+ /// occur. This can be NULL if no error status is desired.
+ ///
+ /// @return
+ /// The name of the slave pseudo terminal as a NULL terminated
+ /// C. This string that comes from static memory, so a copy of
+ /// the string should be made as subsequent calls can change
+ /// this value. NULL is returned if this object doesn't have
+ /// a valid master pseudo terminal opened or if the call to
+ /// \c ptsname() fails.
+ ///
+ /// @see PseudoTerminal::OpenFirstAvailableMaster()
+ //------------------------------------------------------------------
+ const char*
+ GetSlaveName (char *error_str, size_t error_len) const;
+
+ //------------------------------------------------------------------
+ /// Open the first available pseudo terminal.
+ ///
+ /// Opens the first available pseudo terminal with \a oflag as the
+ /// permissions. The opened master file descriptor is stored in this
+ /// object and can be accessed by calling the
+ /// PseudoTerminal::GetMasterFileDescriptor() accessor. Clients
+ /// can call the PseudoTerminal::ReleaseMasterFileDescriptor()
+ /// accessor function if they wish to use the master file descriptor
+ /// beyond the lifespan of this object.
+ ///
+ /// If this object still has a valid master file descriptor when its
+ /// destructor is called, it will close it.
+ ///
+ /// @param[in] oflag
+ /// Flags to use when calling \c posix_openpt(\a oflag).
+ /// A value of "O_RDWR|O_NOCTTY" is suggested.
+ ///
+ /// @param[out] error
+ /// An pointer to an error that can describe any errors that
+ /// occur. This can be NULL if no error status is desired.
+ ///
+ /// @return
+ /// @li \b true when the a master files descriptor is
+ /// successfully opened.
+ /// @li \b false if anything goes wrong.
+ ///
+ /// @see PseudoTerminal::GetMasterFileDescriptor()
+ /// @see PseudoTerminal::ReleaseMasterFileDescriptor()
+ //------------------------------------------------------------------
+ bool
+ OpenFirstAvailableMaster (int oflag, char *error_str, size_t error_len);
+
+ //------------------------------------------------------------------
+ /// Open the slave for the current master pseudo terminal.
+ ///
+ /// A master pseudo terminal should already be valid prior to
+ /// calling this function. The opened slave file descriptor is
+ /// stored in this object and can be accessed by calling the
+ /// PseudoTerminal::GetSlaveFileDescriptor() accessor. Clients
+ /// can call the PseudoTerminal::ReleaseSlaveFileDescriptor()
+ /// accessor function if they wish to use the slave file descriptor
+ /// beyond the lifespan of this object.
+ ///
+ /// If this object still has a valid slave file descriptor when its
+ /// destructor is called, it will close it.
+ ///
+ /// @param[in] oflag
+ /// Flags to use when calling \c open(\a oflag).
+ ///
+ /// @param[out] error
+ /// An pointer to an error that can describe any errors that
+ /// occur. This can be NULL if no error status is desired.
+ ///
+ /// @return
+ /// @li \b true when the a master files descriptor is
+ /// successfully opened.
+ /// @li \b false if anything goes wrong.
+ ///
+ /// @see PseudoTerminal::OpenFirstAvailableMaster()
+ /// @see PseudoTerminal::GetSlaveFileDescriptor()
+ /// @see PseudoTerminal::ReleaseSlaveFileDescriptor()
+ //------------------------------------------------------------------
+ bool
+ OpenSlave (int oflag, char *error_str, size_t error_len);
+
+ //------------------------------------------------------------------
+ /// Release the master file descriptor.
+ ///
+ /// Releases ownership of the master pseudo terminal file descriptor
+ /// without closing it. The destructor for this class will close the
+ /// master file descriptor if the ownership isn't released using this
+ /// call and the master file descriptor has been opened.
+ ///
+ /// @return
+ /// The master file descriptor, or PseudoTerminal::invalid_fd
+ /// if the mast file descriptor is not currently valid.
+ //------------------------------------------------------------------
+ int
+ ReleaseMasterFileDescriptor ();
+
+ //------------------------------------------------------------------
+ /// Release the slave file descriptor.
+ ///
+ /// Release ownership of the slave pseudo terminal file descriptor
+ /// without closing it. The destructor for this class will close the
+ /// slave file descriptor if the ownership isn't released using this
+ /// call and the slave file descriptor has been opened.
+ ///
+ /// @return
+ /// The slave file descriptor, or PseudoTerminal::invalid_fd
+ /// if the slave file descriptor is not currently valid.
+ //------------------------------------------------------------------
+ int
+ ReleaseSlaveFileDescriptor ();
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ int m_master_fd; ///< The file descriptor for the master.
+ int m_slave_fd; ///< The file descriptor for the slave.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (PseudoTerminal);
+
+};
+
+} // namespace lldb
+
+#endif // #if defined(__cplusplus)
+#endif // #ifndef liblldb_PseudoTerminal_h_
diff --git a/include/lldb/Utility/PythonPointer.h b/include/lldb/Utility/PythonPointer.h
new file mode 100644
index 000000000000..f782f7f1313c
--- /dev/null
+++ b/include/lldb/Utility/PythonPointer.h
@@ -0,0 +1,77 @@
+//===---------------------PythonPointer.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_PythonPointer_h_
+#define utility_PythonPointer_h_
+
+#include <algorithm>
+
+#if defined (__APPLE__)
+#include <Python/Python.h>
+#else
+#include <Python.h>
+#endif
+
+namespace lldb_private {
+
+template<class T>
+class PythonPointer
+{
+public:
+ typedef PyObject* element_type;
+private:
+ element_type* ptr_;
+ bool my_ref;
+public:
+
+ PythonPointer(element_type p, bool steal_ref = false) :
+ ptr_(p),
+ my_ref(!steal_ref)
+ {
+ if (my_ref)
+ Py_INCREF(ptr_);
+ }
+
+ PythonPointer(const PythonPointer& r, bool steal_ref = false) :
+ ptr_(r.ptr_),
+ my_ref(!steal_ref)
+ {
+ if (my_ref)
+ Py_INCREF(ptr_);
+ }
+
+ ~PythonPointer()
+ {
+ if (my_ref)
+ Py_XDECREF(ptr_);
+ }
+
+ PythonPointer
+ StealReference()
+ {
+ return PythonPointer(ptr_,true);
+ }
+
+ PythonPointer
+ DuplicateReference()
+ {
+ return PythonPointer(ptr_, false);
+ }
+
+ element_type get() const {return ptr_;}
+
+ bool IsNull() { return ptr_ == NULL; }
+ bool IsNone() { return ptr_ == Py_None; }
+
+ operator PyObject* () { return ptr_; }
+};
+
+} // namespace lldb
+
+#endif // utility_PythonPointer_h_
diff --git a/include/lldb/Utility/Range.h b/include/lldb/Utility/Range.h
new file mode 100644
index 000000000000..1257adb719a1
--- /dev/null
+++ b/include/lldb/Utility/Range.h
@@ -0,0 +1,89 @@
+//===--------------------- Range.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_Range_h_
+#define utility_Range_h_
+
+#include <stdint.h>
+#include <algorithm>
+
+namespace lldb_utility {
+
+class Range
+{
+public:
+
+ typedef uint64_t ValueType;
+
+ static const ValueType OPEN_END = UINT64_MAX;
+
+ Range (const Range& rng);
+
+ Range (ValueType low = 0,
+ ValueType high = OPEN_END);
+
+ Range&
+ operator = (const Range& rhs);
+
+ ValueType
+ GetLow ()
+ {
+ return m_low;
+ }
+
+ ValueType
+ GetHigh ()
+ {
+ return m_high;
+ }
+
+ void
+ SetLow (ValueType low)
+ {
+ m_low = low;
+ }
+
+ void
+ SetHigh (ValueType high)
+ {
+ m_high = high;
+ }
+
+ void
+ Flip ();
+
+ void
+ Intersection (const Range& other);
+
+ void
+ Union (const Range& other);
+
+ typedef bool (*RangeCallback)(ValueType index);
+
+ void
+ Iterate (RangeCallback callback);
+
+ ValueType
+ GetSize ();
+
+ bool
+ IsEmpty ();
+
+private:
+
+ void
+ InitRange ();
+
+ ValueType m_low;
+ ValueType m_high;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef utility_Range_h_
diff --git a/include/lldb/Utility/RefCounter.h b/include/lldb/Utility/RefCounter.h
new file mode 100644
index 000000000000..6daed5498eb8
--- /dev/null
+++ b/include/lldb/Utility/RefCounter.h
@@ -0,0 +1,56 @@
+//===-- RefCounter.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RefCounter_h_
+#define liblldb_RefCounter_h_
+
+#include "lldb/lldb-public.h"
+
+namespace lldb_utility {
+
+//----------------------------------------------------------------------
+// A simple reference counter object. You need an uint32_t* to use it
+// Once that is in place, everyone who needs to ref-count, can say
+// RefCounter ref(ptr);
+// (of course, the pointer is a shared resource, and must be accessible to
+// everyone who needs it). Synchronization is handled by RefCounter itself
+// The counter is decreased each time a RefCounter to it goes out of scope
+//----------------------------------------------------------------------
+class RefCounter
+{
+public:
+ typedef uint32_t value_type;
+
+ RefCounter(value_type* ctr);
+
+ ~RefCounter();
+
+private:
+ value_type* m_counter;
+ DISALLOW_COPY_AND_ASSIGN (RefCounter);
+
+ template <class T>
+ inline T
+ increment(T* t)
+ {
+ return __sync_fetch_and_add(t, 1);
+ }
+
+ template <class T>
+ inline T
+ decrement(T* t)
+ {
+ return __sync_fetch_and_add(t, -1);
+ }
+
+};
+
+} // namespace lldb_utility
+
+#endif // #ifndef liblldb_RefCounter_h_
diff --git a/include/lldb/Utility/SharedCluster.h b/include/lldb/Utility/SharedCluster.h
new file mode 100644
index 000000000000..991af4b4fa49
--- /dev/null
+++ b/include/lldb/Utility/SharedCluster.h
@@ -0,0 +1,108 @@
+//===------------------SharedCluster.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_SharedCluster_h_
+#define utility_SharedCluster_h_
+
+#include "lldb/Utility/SharingPtr.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+namespace imp
+{
+ template <typename T>
+ class shared_ptr_refcount : public lldb_private::imp::shared_count
+ {
+ public:
+ template<class Y> shared_ptr_refcount (Y *in) : shared_count (0), manager(in) {}
+
+ shared_ptr_refcount() : shared_count (0) {}
+
+ virtual ~shared_ptr_refcount ()
+ {
+ }
+
+ virtual void on_zero_shared ()
+ {
+ manager->DecrementRefCount();
+ }
+ private:
+ T *manager;
+ };
+
+} // namespace imp
+
+template <class T>
+class ClusterManager
+{
+public:
+ ClusterManager () :
+ m_objects(),
+ m_external_ref(0),
+ m_mutex(Mutex::eMutexTypeNormal) {}
+
+ ~ClusterManager ()
+ {
+ size_t n_items = m_objects.size();
+ for (size_t i = 0; i < n_items; i++)
+ {
+ delete m_objects[i];
+ }
+ // Decrement refcount should have been called on this ClusterManager,
+ // and it should have locked the mutex, now we will unlock it before
+ // we destroy it...
+ m_mutex.Unlock();
+ }
+
+ void ManageObject (T *new_object)
+ {
+ Mutex::Locker locker (m_mutex);
+ if (!ContainsObject(new_object))
+ m_objects.push_back (new_object);
+ }
+
+ typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object)
+ {
+ {
+ Mutex::Locker locker (m_mutex);
+ m_external_ref++;
+ assert (ContainsObject(desired_object));
+ }
+ return typename lldb_private::SharingPtr<T> (desired_object, new imp::shared_ptr_refcount<ClusterManager> (this));
+ }
+
+private:
+
+ bool ContainsObject (const T *desired_object)
+ {
+ typename std::vector<T *>::iterator pos, end = m_objects.end();
+ pos = std::find(m_objects.begin(), end, desired_object);
+ return pos != end;
+ }
+
+ void DecrementRefCount ()
+ {
+ m_mutex.Lock();
+ m_external_ref--;
+ if (m_external_ref == 0)
+ delete this;
+ else
+ m_mutex.Unlock();
+ }
+
+ friend class imp::shared_ptr_refcount<ClusterManager>;
+
+ std::vector<T *> m_objects;
+ int m_external_ref;
+ Mutex m_mutex;
+};
+
+} // namespace lldb_private
+#endif // utility_SharedCluster_h_
diff --git a/include/lldb/Utility/SharingPtr.h b/include/lldb/Utility/SharingPtr.h
new file mode 100644
index 000000000000..814b54b5cfe6
--- /dev/null
+++ b/include/lldb/Utility/SharingPtr.h
@@ -0,0 +1,816 @@
+//===---------------------SharingPtr.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_SharingPtr_h_
+#define utility_SharingPtr_h_
+
+#include <algorithm>
+#include <memory>
+
+//#define ENABLE_SP_LOGGING 1 // DON'T CHECK THIS LINE IN UNLESS COMMENTED OUT
+#if defined (ENABLE_SP_LOGGING)
+
+extern "C" void track_sp (void *sp_this, void *ptr, long count);
+
+#endif
+
+namespace lldb_private {
+
+namespace imp {
+
+template <class T>
+inline T
+increment(T& t)
+{
+ return __sync_add_and_fetch(&t, 1);
+}
+
+template <class T>
+inline T
+decrement(T& t)
+{
+ return __sync_add_and_fetch(&t, -1);
+}
+
+class shared_count
+{
+ shared_count(const shared_count&);
+ shared_count& operator=(const shared_count&);
+
+protected:
+ long shared_owners_;
+ virtual ~shared_count();
+private:
+ virtual void on_zero_shared() = 0;
+
+public:
+ explicit shared_count(long refs = 0)
+ : shared_owners_(refs) {}
+
+ void add_shared();
+ void release_shared();
+ long use_count() const {return shared_owners_ + 1;}
+};
+
+template <class T>
+class shared_ptr_pointer
+ : public shared_count
+{
+ T data_;
+public:
+ shared_ptr_pointer(T p)
+ : data_(p) {}
+
+private:
+ virtual void on_zero_shared();
+
+ // Outlaw copy constructor and assignment operator to keep effictive C++
+ // warnings down to a minumum
+ shared_ptr_pointer (const shared_ptr_pointer &);
+ shared_ptr_pointer & operator=(const shared_ptr_pointer &);
+};
+
+template <class T>
+void
+shared_ptr_pointer<T>::on_zero_shared()
+{
+ delete data_;
+}
+
+template <class T>
+class shared_ptr_emplace
+ : public shared_count
+{
+ T data_;
+public:
+
+ shared_ptr_emplace()
+ : data_() {}
+
+ template <class A0>
+ shared_ptr_emplace(A0& a0)
+ : data_(a0) {}
+
+ template <class A0, class A1>
+ shared_ptr_emplace(A0& a0, A1& a1)
+ : data_(a0, a1) {}
+
+ template <class A0, class A1, class A2>
+ shared_ptr_emplace(A0& a0, A1& a1, A2& a2)
+ : data_(a0, a1, a2) {}
+
+ template <class A0, class A1, class A2, class A3>
+ shared_ptr_emplace(A0& a0, A1& a1, A2& a2, A3& a3)
+ : data_(a0, a1, a2, a3) {}
+
+ template <class A0, class A1, class A2, class A3, class A4>
+ shared_ptr_emplace(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4)
+ : data_(a0, a1, a2, a3, a4) {}
+
+private:
+ virtual void on_zero_shared();
+public:
+ T* get() {return &data_;}
+};
+
+template <class T>
+void
+shared_ptr_emplace<T>::on_zero_shared()
+{
+}
+
+} // namespace
+
+template<class T>
+class SharingPtr
+{
+public:
+ typedef T element_type;
+private:
+ element_type* ptr_;
+ imp::shared_count* cntrl_;
+
+ struct nat {int for_bool_;};
+public:
+ SharingPtr();
+ template<class Y> explicit SharingPtr(Y* p);
+ template<class Y> explicit SharingPtr(Y* p, imp::shared_count *ctrl_block);
+ template<class Y> SharingPtr(const SharingPtr<Y>& r, element_type *p);
+ SharingPtr(const SharingPtr& r);
+ template<class Y>
+ SharingPtr(const SharingPtr<Y>& r);
+
+ ~SharingPtr();
+
+ SharingPtr& operator=(const SharingPtr& r);
+ template<class Y> SharingPtr& operator=(const SharingPtr<Y>& r);
+
+ void swap(SharingPtr& r);
+ void reset();
+ template<class Y> void reset(Y* p);
+
+ element_type* get() const {return ptr_;}
+ element_type& operator*() const {return *ptr_;}
+ element_type* operator->() const {return ptr_;}
+ long use_count() const {return cntrl_ ? cntrl_->use_count() : 0;}
+ bool unique() const {return use_count() == 1;}
+ bool empty() const {return cntrl_ == 0;}
+ operator nat*() const {return (nat*)get();}
+
+ static SharingPtr<T> make_shared();
+
+ template<class A0>
+ static SharingPtr<T> make_shared(A0&);
+
+ template<class A0, class A1>
+ static SharingPtr<T> make_shared(A0&, A1&);
+
+ template<class A0, class A1, class A2>
+ static SharingPtr<T> make_shared(A0&, A1&, A2&);
+
+ template<class A0, class A1, class A2, class A3>
+ static SharingPtr<T> make_shared(A0&, A1&, A2&, A3&);
+
+ template<class A0, class A1, class A2, class A3, class A4>
+ static SharingPtr<T> make_shared(A0&, A1&, A2&, A3&, A4&);
+
+private:
+
+ template <class U> friend class SharingPtr;
+};
+
+template<class T>
+inline
+SharingPtr<T>::SharingPtr()
+ : ptr_(0),
+ cntrl_(0)
+{
+}
+
+template<class T>
+template<class Y>
+SharingPtr<T>::SharingPtr(Y* p)
+ : ptr_(p), cntrl_(0)
+{
+ std::unique_ptr<Y> hold(p);
+ typedef imp::shared_ptr_pointer<Y*> _CntrlBlk;
+ cntrl_ = new _CntrlBlk(p);
+ hold.release();
+}
+
+template<class T>
+template<class Y>
+SharingPtr<T>::SharingPtr(Y* p, imp::shared_count *cntrl_block)
+ : ptr_(p), cntrl_(cntrl_block)
+{
+}
+
+template<class T>
+template<class Y>
+inline
+SharingPtr<T>::SharingPtr(const SharingPtr<Y>& r, element_type *p)
+ : ptr_(p),
+ cntrl_(r.cntrl_)
+{
+ if (cntrl_)
+ cntrl_->add_shared();
+}
+
+template<class T>
+inline
+SharingPtr<T>::SharingPtr(const SharingPtr& r)
+ : ptr_(r.ptr_),
+ cntrl_(r.cntrl_)
+{
+ if (cntrl_)
+ cntrl_->add_shared();
+}
+
+template<class T>
+template<class Y>
+inline
+SharingPtr<T>::SharingPtr(const SharingPtr<Y>& r)
+ : ptr_(r.ptr_),
+ cntrl_(r.cntrl_)
+{
+ if (cntrl_)
+ cntrl_->add_shared();
+}
+
+template<class T>
+SharingPtr<T>::~SharingPtr()
+{
+ if (cntrl_)
+ cntrl_->release_shared();
+}
+
+template<class T>
+inline
+SharingPtr<T>&
+SharingPtr<T>::operator=(const SharingPtr& r)
+{
+ SharingPtr(r).swap(*this);
+ return *this;
+}
+
+template<class T>
+template<class Y>
+inline
+SharingPtr<T>&
+SharingPtr<T>::operator=(const SharingPtr<Y>& r)
+{
+ SharingPtr(r).swap(*this);
+ return *this;
+}
+
+template<class T>
+inline
+void
+SharingPtr<T>::swap(SharingPtr& r)
+{
+ std::swap(ptr_, r.ptr_);
+ std::swap(cntrl_, r.cntrl_);
+}
+
+template<class T>
+inline
+void
+SharingPtr<T>::reset()
+{
+ SharingPtr().swap(*this);
+}
+
+template<class T>
+template<class Y>
+inline
+void
+SharingPtr<T>::reset(Y* p)
+{
+ SharingPtr(p).swap(*this);
+}
+
+template<class T>
+SharingPtr<T>
+SharingPtr<T>::make_shared()
+{
+ typedef imp::shared_ptr_emplace<T> CntrlBlk;
+ SharingPtr<T> r;
+ r.cntrl_ = new CntrlBlk();
+ r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
+ return r;
+}
+
+template<class T>
+template<class A0>
+SharingPtr<T>
+SharingPtr<T>::make_shared(A0& a0)
+{
+ typedef imp::shared_ptr_emplace<T> CntrlBlk;
+ SharingPtr<T> r;
+ r.cntrl_ = new CntrlBlk(a0);
+ r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
+ return r;
+}
+
+template<class T>
+template<class A0, class A1>
+SharingPtr<T>
+SharingPtr<T>::make_shared(A0& a0, A1& a1)
+{
+ typedef imp::shared_ptr_emplace<T> CntrlBlk;
+ SharingPtr<T> r;
+ r.cntrl_ = new CntrlBlk(a0, a1);
+ r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
+ return r;
+}
+
+template<class T>
+template<class A0, class A1, class A2>
+SharingPtr<T>
+SharingPtr<T>::make_shared(A0& a0, A1& a1, A2& a2)
+{
+ typedef imp::shared_ptr_emplace<T> CntrlBlk;
+ SharingPtr<T> r;
+ r.cntrl_ = new CntrlBlk(a0, a1, a2);
+ r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
+ return r;
+}
+
+template<class T>
+template<class A0, class A1, class A2, class A3>
+SharingPtr<T>
+SharingPtr<T>::make_shared(A0& a0, A1& a1, A2& a2, A3& a3)
+{
+ typedef imp::shared_ptr_emplace<T> CntrlBlk;
+ SharingPtr<T> r;
+ r.cntrl_ = new CntrlBlk(a0, a1, a2, a3);
+ r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
+ return r;
+}
+
+template<class T>
+template<class A0, class A1, class A2, class A3, class A4>
+SharingPtr<T>
+SharingPtr<T>::make_shared(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4)
+{
+ typedef imp::shared_ptr_emplace<T> CntrlBlk;
+ SharingPtr<T> r;
+ r.cntrl_ = new CntrlBlk(a0, a1, a2, a3, a4);
+ r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
+ return r;
+}
+
+template<class T>
+inline
+SharingPtr<T>
+make_shared()
+{
+ return SharingPtr<T>::make_shared();
+}
+
+template<class T, class A0>
+inline
+SharingPtr<T>
+make_shared(A0& a0)
+{
+ return SharingPtr<T>::make_shared(a0);
+}
+
+template<class T, class A0, class A1>
+inline
+SharingPtr<T>
+make_shared(A0& a0, A1& a1)
+{
+ return SharingPtr<T>::make_shared(a0, a1);
+}
+
+template<class T, class A0, class A1, class A2>
+inline
+SharingPtr<T>
+make_shared(A0& a0, A1& a1, A2& a2)
+{
+ return SharingPtr<T>::make_shared(a0, a1, a2);
+}
+
+template<class T, class A0, class A1, class A2, class A3>
+inline
+SharingPtr<T>
+make_shared(A0& a0, A1& a1, A2& a2, A3& a3)
+{
+ return SharingPtr<T>::make_shared(a0, a1, a2, a3);
+}
+
+template<class T, class A0, class A1, class A2, class A3, class A4>
+inline
+SharingPtr<T>
+make_shared(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4)
+{
+ return SharingPtr<T>::make_shared(a0, a1, a2, a3, a4);
+}
+
+
+template<class T, class U>
+inline
+bool
+operator==(const SharingPtr<T>& __x, const SharingPtr<U>& __y)
+{
+ return __x.get() == __y.get();
+}
+
+template<class T, class U>
+inline
+bool
+operator!=(const SharingPtr<T>& __x, const SharingPtr<U>& __y)
+{
+ return !(__x == __y);
+}
+
+template<class T, class U>
+inline
+bool
+operator<(const SharingPtr<T>& __x, const SharingPtr<U>& __y)
+{
+ return __x.get() < __y.get();
+}
+
+template<class T>
+inline
+void
+swap(SharingPtr<T>& __x, SharingPtr<T>& __y)
+{
+ __x.swap(__y);
+}
+
+template<class T, class U>
+inline
+SharingPtr<T>
+static_pointer_cast(const SharingPtr<U>& r)
+{
+ return SharingPtr<T>(r, static_cast<T*>(r.get()));
+}
+
+template<class T, class U>
+SharingPtr<T>
+const_pointer_cast(const SharingPtr<U>& r)
+{
+ return SharingPtr<T>(r, const_cast<T*>(r.get()));
+}
+
+template <class T>
+class LoggingSharingPtr
+ : public SharingPtr<T>
+{
+ typedef SharingPtr<T> base;
+
+public:
+ typedef void (*Callback)(void*, const LoggingSharingPtr&, bool action);
+ // action: false means increment just happened
+ // true means decrement is about to happen
+
+private:
+ Callback cb_;
+ void* baton_;
+
+public:
+ LoggingSharingPtr() : cb_(0), baton_(0) {}
+ LoggingSharingPtr(Callback cb, void* baton)
+ : cb_(cb), baton_(baton)
+ {
+ if (cb_)
+ cb_(baton_, *this, false);
+ }
+
+ template <class Y>
+ LoggingSharingPtr(Y* p)
+ : base(p), cb_(0), baton_(0) {}
+
+ template <class Y>
+ LoggingSharingPtr(Y* p, Callback cb, void* baton)
+ : base(p), cb_(cb), baton_(baton)
+ {
+ if (cb_)
+ cb_(baton_, *this, false);
+ }
+
+ ~LoggingSharingPtr()
+ {
+ if (cb_)
+ cb_(baton_, *this, true);
+ }
+
+ LoggingSharingPtr(const LoggingSharingPtr& p)
+ : base(p), cb_(p.cb_), baton_(p.baton_)
+ {
+ if (cb_)
+ cb_(baton_, *this, false);
+ }
+
+ LoggingSharingPtr& operator=(const LoggingSharingPtr& p)
+ {
+ if (cb_)
+ cb_(baton_, *this, true);
+ base::operator=(p);
+ cb_ = p.cb_;
+ baton_ = p.baton_;
+ if (cb_)
+ cb_(baton_, *this, false);
+ return *this;
+ }
+
+ void reset()
+ {
+ if (cb_)
+ cb_(baton_, *this, true);
+ base::reset();
+ }
+
+ template <class Y>
+ void reset(Y* p)
+ {
+ if (cb_)
+ cb_(baton_, *this, true);
+ base::reset(p);
+ if (cb_)
+ cb_(baton_, *this, false);
+ }
+
+ void SetCallback(Callback cb, void* baton)
+ {
+ cb_ = cb;
+ baton_ = baton;
+ }
+
+ void ClearCallback()
+ {
+ cb_ = 0;
+ baton_ = 0;
+ }
+};
+
+
+template <class T>
+class IntrusiveSharingPtr;
+
+template <class T>
+class ReferenceCountedBase
+{
+public:
+ explicit ReferenceCountedBase()
+ : shared_owners_(-1)
+ {
+ }
+
+ void
+ add_shared();
+
+ void
+ release_shared();
+
+ long
+ use_count() const
+ {
+ return shared_owners_ + 1;
+ }
+
+protected:
+ long shared_owners_;
+
+ friend class IntrusiveSharingPtr<T>;
+
+private:
+ ReferenceCountedBase(const ReferenceCountedBase&);
+ ReferenceCountedBase& operator=(const ReferenceCountedBase&);
+};
+
+ template <class T>
+ void
+ lldb_private::ReferenceCountedBase<T>::add_shared()
+ {
+ imp::increment(shared_owners_);
+ }
+
+ template <class T>
+ void
+ lldb_private::ReferenceCountedBase<T>::release_shared()
+ {
+ if (imp::decrement(shared_owners_) == -1)
+ delete static_cast<T*>(this);
+ }
+
+
+template <class T>
+class ReferenceCountedBaseVirtual : public imp::shared_count
+{
+public:
+ explicit ReferenceCountedBaseVirtual () :
+ imp::shared_count(-1)
+ {
+ }
+
+ virtual
+ ~ReferenceCountedBaseVirtual ()
+ {
+ }
+
+ virtual void on_zero_shared ();
+
+};
+
+template <class T>
+void
+ReferenceCountedBaseVirtual<T>::on_zero_shared()
+{
+}
+
+template <typename T>
+class IntrusiveSharingPtr
+{
+public:
+ typedef T element_type;
+
+ explicit
+ IntrusiveSharingPtr () :
+ ptr_(0)
+ {
+ }
+
+ explicit
+ IntrusiveSharingPtr (T* ptr) :
+ ptr_(ptr)
+ {
+ add_shared();
+ }
+
+ IntrusiveSharingPtr (const IntrusiveSharingPtr& rhs) :
+ ptr_(rhs.ptr_)
+ {
+ add_shared();
+ }
+
+ template <class X>
+ IntrusiveSharingPtr (const IntrusiveSharingPtr<X>& rhs)
+ : ptr_(rhs.get())
+ {
+ add_shared();
+ }
+
+ IntrusiveSharingPtr&
+ operator= (const IntrusiveSharingPtr& rhs)
+ {
+ reset(rhs.get());
+ return *this;
+ }
+
+ template <class X> IntrusiveSharingPtr&
+ operator= (const IntrusiveSharingPtr<X>& rhs)
+ {
+ reset(rhs.get());
+ return *this;
+ }
+
+ IntrusiveSharingPtr&
+ operator= (T *ptr)
+ {
+ reset(ptr);
+ return *this;
+ }
+
+ ~IntrusiveSharingPtr()
+ {
+ release_shared();
+#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
+ // NULL out the pointer in objects which can help with leaks detection.
+ // We don't enable this for LLDB_CONFIGURATION_BUILD_AND_INTEGRATION or
+ // when none of the LLDB_CONFIGURATION_XXX macros are defined since
+ // those would be builds for release. But for debug and release builds
+ // that are for development, we NULL out the pointers to catch potential
+ // issues.
+ ptr_ = NULL;
+#endif // #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
+ }
+
+ T&
+ operator*() const
+ {
+ return *ptr_;
+ }
+
+ T*
+ operator->() const
+ {
+ return ptr_;
+ }
+
+ T*
+ get() const
+ {
+ return ptr_;
+ }
+
+ operator bool() const
+ {
+ return ptr_ != 0;
+ }
+
+ void
+ swap (IntrusiveSharingPtr& rhs)
+ {
+ std::swap(ptr_, rhs.ptr_);
+#if defined (ENABLE_SP_LOGGING)
+ track_sp (this, ptr_, use_count());
+ track_sp (&rhs, rhs.ptr_, rhs.use_count());
+#endif
+ }
+
+ void
+ reset(T* ptr = NULL)
+ {
+ IntrusiveSharingPtr(ptr).swap(*this);
+ }
+
+ long
+ use_count () const
+ {
+ if (ptr_)
+ return ptr_->use_count();
+ return 0;
+ }
+
+ bool
+ unique () const
+ {
+ return use_count () == 1;
+ }
+
+private:
+ element_type *ptr_;
+
+ void
+ add_shared()
+ {
+ if (ptr_)
+ {
+ ptr_->add_shared();
+#if defined (ENABLE_SP_LOGGING)
+ track_sp (this, ptr_, ptr_->use_count());
+#endif
+ }
+ }
+ void
+ release_shared()
+ {
+ if (ptr_)
+ {
+#if defined (ENABLE_SP_LOGGING)
+ track_sp (this, NULL, ptr_->use_count() - 1);
+#endif
+ ptr_->release_shared();
+ }
+ }
+};
+
+template<class T, class U>
+inline bool operator== (const IntrusiveSharingPtr<T>& lhs, const IntrusiveSharingPtr<U>& rhs)
+{
+ return lhs.get() == rhs.get();
+}
+
+template<class T, class U>
+inline bool operator!= (const IntrusiveSharingPtr<T>& lhs, const IntrusiveSharingPtr<U>& rhs)
+{
+ return lhs.get() != rhs.get();
+}
+
+template<class T, class U>
+inline bool operator== (const IntrusiveSharingPtr<T>& lhs, U* rhs)
+{
+ return lhs.get() == rhs;
+}
+
+template<class T, class U>
+inline bool operator!= (const IntrusiveSharingPtr<T>& lhs, U* rhs)
+{
+ return lhs.get() != rhs;
+}
+
+template<class T, class U>
+inline bool operator== (T* lhs, const IntrusiveSharingPtr<U>& rhs)
+{
+ return lhs == rhs.get();
+}
+
+template<class T, class U>
+inline bool operator!= (T* lhs, const IntrusiveSharingPtr<U>& rhs)
+{
+ return lhs != rhs.get();
+}
+
+} // namespace lldb_private
+
+#endif // utility_SharingPtr_h_
diff --git a/include/lldb/Utility/Utils.h b/include/lldb/Utility/Utils.h
new file mode 100644
index 000000000000..46bc1847c0b7
--- /dev/null
+++ b/include/lldb/Utility/Utils.h
@@ -0,0 +1,22 @@
+//===-- Utils.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_Utils_h_
+#define utility_Utils_h_
+
+// These utilities have llvm namespace.
+#include "llvm/ADT/STLExtras.h"
+
+namespace lldb_private {
+
+// Add lldb utilities here.
+
+} // namespace lldb_private
+
+#endif // utility_Utils
diff --git a/include/lldb/lldb-defines.h b/include/lldb/lldb-defines.h
new file mode 100644
index 000000000000..3318aa15f5ac
--- /dev/null
+++ b/include/lldb/lldb-defines.h
@@ -0,0 +1,125 @@
+//===-- lldb-defines.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_lldb_defines_h_
+#define LLDB_lldb_defines_h_
+
+#include "lldb/lldb-types.h"
+
+#if !defined(UINT32_MAX)
+ #define UINT32_MAX 4294967295U
+#endif
+
+#if !defined(UINT64_MAX)
+ #define UINT64_MAX 18446744073709551615ULL
+#endif
+
+//----------------------------------------------------------------------
+// LLDB version
+//
+// A build script phase can modify this version number if needed.
+//----------------------------------------------------------------------
+//#define LLDB_VERSION
+//#define LLDB_REVISION
+//#define LLDB_VERSION_STRING
+
+//----------------------------------------------------------------------
+// LLDB defines
+//----------------------------------------------------------------------
+#define LLDB_GENERIC_ERROR UINT32_MAX
+
+//----------------------------------------------------------------------
+// Breakpoints
+//----------------------------------------------------------------------
+#define LLDB_INVALID_BREAK_ID 0
+#define LLDB_DEFAULT_BREAK_SIZE 0
+#define LLDB_BREAK_ID_IS_VALID(bid) ((bid) != (LLDB_INVALID_BREAK_ID))
+#define LLDB_BREAK_ID_IS_INTERNAL(bid) ((bid) < 0)
+
+//----------------------------------------------------------------------
+// Watchpoints
+//----------------------------------------------------------------------
+#define LLDB_INVALID_WATCH_ID 0
+#define LLDB_WATCH_ID_IS_VALID(uid) ((uid) != (LLDB_INVALID_WATCH_ID))
+#define LLDB_WATCH_TYPE_READ (1u << 0)
+#define LLDB_WATCH_TYPE_WRITE (1u << 1)
+#define LLDB_WATCH_TYPE_IS_VALID(type) ((type | LLDB_WATCH_TYPE_READ) || (type | LLDB_WATCH_TYPE_WRITE))
+
+//----------------------------------------------------------------------
+// Generic Register Numbers
+//----------------------------------------------------------------------
+#define LLDB_REGNUM_GENERIC_PC 0 // Program Counter
+#define LLDB_REGNUM_GENERIC_SP 1 // Stack Pointer
+#define LLDB_REGNUM_GENERIC_FP 2 // Frame Pointer
+#define LLDB_REGNUM_GENERIC_RA 3 // Return Address
+#define LLDB_REGNUM_GENERIC_FLAGS 4 // Processor flags register
+#define LLDB_REGNUM_GENERIC_ARG1 5 // The register that would contain pointer size or less argument 1 (if any)
+#define LLDB_REGNUM_GENERIC_ARG2 6 // The register that would contain pointer size or less argument 2 (if any)
+#define LLDB_REGNUM_GENERIC_ARG3 7 // The register that would contain pointer size or less argument 3 (if any)
+#define LLDB_REGNUM_GENERIC_ARG4 8 // The register that would contain pointer size or less argument 4 (if any)
+#define LLDB_REGNUM_GENERIC_ARG5 9 // The register that would contain pointer size or less argument 5 (if any)
+#define LLDB_REGNUM_GENERIC_ARG6 10 // The register that would contain pointer size or less argument 6 (if any)
+#define LLDB_REGNUM_GENERIC_ARG7 11 // The register that would contain pointer size or less argument 7 (if any)
+#define LLDB_REGNUM_GENERIC_ARG8 12 // The register that would contain pointer size or less argument 8 (if any)
+//---------------------------------------------------------------------
+/// Invalid value definitions
+//----------------------------------------------------------------------
+#define LLDB_INVALID_ADDRESS UINT64_MAX
+#define LLDB_INVALID_INDEX32 UINT32_MAX
+#define LLDB_INVALID_IVAR_OFFSET UINT32_MAX
+#define LLDB_INVALID_IMAGE_TOKEN UINT32_MAX
+#define LLDB_INVALID_REGNUM UINT32_MAX
+#define LLDB_INVALID_UID UINT64_MAX
+#define LLDB_INVALID_PROCESS_ID 0
+#define LLDB_INVALID_THREAD_ID 0
+#define LLDB_INVALID_FRAME_ID UINT32_MAX
+#define LLDB_INVALID_SIGNAL_NUMBER INT32_MAX
+#define LLDB_INVALID_OFFSET UINT64_MAX // Must match max of lldb::offset_t
+
+//----------------------------------------------------------------------
+/// CPU Type defintions
+//----------------------------------------------------------------------
+#define LLDB_ARCH_DEFAULT "systemArch"
+#define LLDB_ARCH_DEFAULT_32BIT "systemArch32"
+#define LLDB_ARCH_DEFAULT_64BIT "systemArch64"
+#define LLDB_INVALID_CPUTYPE (0xFFFFFFFEu)
+
+//----------------------------------------------------------------------
+/// Option Set defintions
+//----------------------------------------------------------------------
+// FIXME: I'm sure there's some #define magic that can create all 32 sets on the
+// fly. That would have the added benefit of making this unreadable.
+#define LLDB_MAX_NUM_OPTION_SETS 32
+#define LLDB_OPT_SET_ALL 0xFFFFFFFFU
+#define LLDB_OPT_SET_1 (1U << 0)
+#define LLDB_OPT_SET_2 (1U << 1)
+#define LLDB_OPT_SET_3 (1U << 2)
+#define LLDB_OPT_SET_4 (1U << 3)
+#define LLDB_OPT_SET_5 (1U << 4)
+#define LLDB_OPT_SET_6 (1U << 5)
+#define LLDB_OPT_SET_7 (1U << 6)
+#define LLDB_OPT_SET_8 (1U << 7)
+#define LLDB_OPT_SET_9 (1U << 8)
+#define LLDB_OPT_SET_10 (1U << 9)
+#define LLDB_OPT_SET_FROM_TO(A, B) (((1U << (B)) - 1) ^ (((1U << (A))-1) >> 1))
+
+#if defined(__cplusplus)
+
+//----------------------------------------------------------------------
+/// @def DISALLOW_COPY_AND_ASSIGN(TypeName)
+/// Macro definition for easily disallowing copy constructor and
+/// assignment operators in C++ classes.
+//----------------------------------------------------------------------
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ const TypeName& operator=(const TypeName&)
+
+#endif // #if defined(__cplusplus)
+
+#endif // LLDB_lldb_defines_h_
diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h
new file mode 100644
index 000000000000..6ec5ed6a35e2
--- /dev/null
+++ b/include/lldb/lldb-enumerations.h
@@ -0,0 +1,685 @@
+//===-- lldb-enumerations.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_lldb_enumerations_h_
+#define LLDB_lldb_enumerations_h_
+
+namespace lldb {
+
+ //----------------------------------------------------------------------
+ // Process and Thread States
+ //----------------------------------------------------------------------
+ typedef enum StateType
+ {
+ eStateInvalid = 0,
+ eStateUnloaded, ///< Process is object is valid, but not currently loaded
+ eStateConnected, ///< Process is connected to remote debug services, but not launched or attached to anything yet
+ eStateAttaching, ///< Process is currently trying to attach
+ eStateLaunching, ///< Process is in the process of launching
+ eStateStopped, ///< Process or thread is stopped and can be examined.
+ eStateRunning, ///< Process or thread is running and can't be examined.
+ eStateStepping, ///< Process or thread is in the process of stepping and can not be examined.
+ eStateCrashed, ///< Process or thread has crashed and can be examined.
+ eStateDetached, ///< Process has been detached and can't be examined.
+ eStateExited, ///< Process has exited and can't be examined.
+ eStateSuspended ///< Process or thread is in a suspended state as far
+ ///< as the debugger is concerned while other processes
+ ///< or threads get the chance to run.
+ } StateType;
+
+ //----------------------------------------------------------------------
+ // Launch Flags
+ //----------------------------------------------------------------------
+ typedef enum LaunchFlags
+ {
+ eLaunchFlagNone = 0u,
+ eLaunchFlagExec = (1u << 0), ///< Exec when launching and turn the calling process into a new process
+ eLaunchFlagDebug = (1u << 1), ///< Stop as soon as the process launches to allow the process to be debugged
+ eLaunchFlagStopAtEntry = (1u << 2), ///< Stop at the program entry point instead of auto-continuing when launching or attaching at entry point
+ eLaunchFlagDisableASLR = (1u << 3), ///< Disable Address Space Layout Randomization
+ eLaunchFlagDisableSTDIO = (1u << 4), ///< Disable stdio for inferior process (e.g. for a GUI app)
+ eLaunchFlagLaunchInTTY = (1u << 5), ///< Launch the process in a new TTY if supported by the host
+ eLaunchFlagLaunchInShell= (1u << 6), ///< Launch the process inside a shell to get shell expansion
+ eLaunchFlagLaunchInSeparateProcessGroup = (1u << 7) ///< Launch the process in a separate process group
+ } LaunchFlags;
+
+ //----------------------------------------------------------------------
+ // Thread Run Modes
+ //----------------------------------------------------------------------
+ typedef enum RunMode {
+ eOnlyThisThread,
+ eAllThreads,
+ eOnlyDuringStepping
+ } RunMode;
+
+ //----------------------------------------------------------------------
+ // Byte ordering definitions
+ //----------------------------------------------------------------------
+ typedef enum ByteOrder
+ {
+ eByteOrderInvalid = 0,
+ eByteOrderBig = 1,
+ eByteOrderPDP = 2,
+ eByteOrderLittle = 4
+ } ByteOrder;
+
+ //----------------------------------------------------------------------
+ // Register encoding definitions
+ //----------------------------------------------------------------------
+ typedef enum Encoding
+ {
+ eEncodingInvalid = 0,
+ eEncodingUint, // unsigned integer
+ eEncodingSint, // signed integer
+ eEncodingIEEE754, // float
+ eEncodingVector // vector registers
+ } Encoding;
+
+ //----------------------------------------------------------------------
+ // Display format definitions
+ //----------------------------------------------------------------------
+ typedef enum Format
+ {
+ eFormatDefault = 0,
+ eFormatInvalid = 0,
+ eFormatBoolean,
+ eFormatBinary,
+ eFormatBytes,
+ eFormatBytesWithASCII,
+ eFormatChar,
+ eFormatCharPrintable, // Only printable characters, space if not printable
+ eFormatComplex, // Floating point complex type
+ eFormatComplexFloat = eFormatComplex,
+ eFormatCString, // NULL terminated C strings
+ eFormatDecimal,
+ eFormatEnum,
+ eFormatHex,
+ eFormatHexUppercase,
+ eFormatFloat,
+ eFormatOctal,
+ eFormatOSType, // OS character codes encoded into an integer 'PICT' 'text' etc...
+ eFormatUnicode16,
+ eFormatUnicode32,
+ eFormatUnsigned,
+ eFormatPointer,
+ eFormatVectorOfChar,
+ eFormatVectorOfSInt8,
+ eFormatVectorOfUInt8,
+ eFormatVectorOfSInt16,
+ eFormatVectorOfUInt16,
+ eFormatVectorOfSInt32,
+ eFormatVectorOfUInt32,
+ eFormatVectorOfSInt64,
+ eFormatVectorOfUInt64,
+ eFormatVectorOfFloat32,
+ eFormatVectorOfFloat64,
+ eFormatVectorOfUInt128,
+ eFormatComplexInteger, // Integer complex type
+ eFormatCharArray, // Print characters with no single quotes, used for character arrays that can contain non printable characters
+ eFormatAddressInfo, // Describe what an address points to (func + offset with file/line, symbol + offset, data, etc)
+ eFormatHexFloat, // ISO C99 hex float string
+ eFormatInstruction, // Disassemble an opcode
+ eFormatVoid, // Do not print this
+ kNumFormats
+ } Format;
+
+ //----------------------------------------------------------------------
+ // Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls
+ //----------------------------------------------------------------------
+ typedef enum DescriptionLevel
+ {
+ eDescriptionLevelBrief = 0,
+ eDescriptionLevelFull,
+ eDescriptionLevelVerbose,
+ eDescriptionLevelInitial,
+ kNumDescriptionLevels
+ } DescriptionLevel;
+
+ //----------------------------------------------------------------------
+ // Script interpreter types
+ //----------------------------------------------------------------------
+ typedef enum ScriptLanguage
+ {
+ eScriptLanguageNone,
+ eScriptLanguagePython,
+ eScriptLanguageDefault = eScriptLanguagePython
+ } ScriptLanguage;
+
+ //----------------------------------------------------------------------
+ // Register numbering types
+ //----------------------------------------------------------------------
+ typedef enum RegisterKind
+ {
+ eRegisterKindGCC = 0, // the register numbers seen in eh_frame
+ eRegisterKindDWARF, // the register numbers seen DWARF
+ eRegisterKindGeneric, // insn ptr reg, stack ptr reg, etc not specific to any particular target
+ eRegisterKindGDB, // the register numbers gdb uses (matches stabs numbers?)
+ eRegisterKindLLDB, // lldb's internal register numbers
+ kNumRegisterKinds
+ } RegisterKind;
+
+ //----------------------------------------------------------------------
+ // Thread stop reasons
+ //----------------------------------------------------------------------
+ typedef enum StopReason
+ {
+ eStopReasonInvalid = 0,
+ eStopReasonNone,
+ eStopReasonTrace,
+ eStopReasonBreakpoint,
+ eStopReasonWatchpoint,
+ eStopReasonSignal,
+ eStopReasonException,
+ eStopReasonExec, // Program was re-exec'ed
+ eStopReasonPlanComplete,
+ eStopReasonThreadExiting
+ } StopReason;
+
+ //----------------------------------------------------------------------
+ // Command Return Status Types
+ //----------------------------------------------------------------------
+ typedef enum ReturnStatus
+ {
+ eReturnStatusInvalid,
+ eReturnStatusSuccessFinishNoResult,
+ eReturnStatusSuccessFinishResult,
+ eReturnStatusSuccessContinuingNoResult,
+ eReturnStatusSuccessContinuingResult,
+ eReturnStatusStarted,
+ eReturnStatusFailed,
+ eReturnStatusQuit
+ } ReturnStatus;
+
+
+ //----------------------------------------------------------------------
+ // Connection Status Types
+ //----------------------------------------------------------------------
+ typedef enum ConnectionStatus
+ {
+ eConnectionStatusSuccess, // Success
+ eConnectionStatusEndOfFile, // End-of-file encountered
+ eConnectionStatusError, // Check GetError() for details
+ eConnectionStatusTimedOut, // Request timed out
+ eConnectionStatusNoConnection, // No connection
+ eConnectionStatusLostConnection // Lost connection while connected to a valid connection
+ } ConnectionStatus;
+
+ typedef enum ErrorType
+ {
+ eErrorTypeInvalid,
+ eErrorTypeGeneric, ///< Generic errors that can be any value.
+ eErrorTypeMachKernel, ///< Mach kernel error codes.
+ eErrorTypePOSIX ///< POSIX error codes.
+ } ErrorType;
+
+
+ typedef enum ValueType
+ {
+ eValueTypeInvalid = 0,
+ eValueTypeVariableGlobal = 1, // globals variable
+ eValueTypeVariableStatic = 2, // static variable
+ eValueTypeVariableArgument = 3, // function argument variables
+ eValueTypeVariableLocal = 4, // function local variables
+ eValueTypeRegister = 5, // stack frame register value
+ eValueTypeRegisterSet = 6, // A collection of stack frame register values
+ eValueTypeConstResult = 7 // constant result variables
+ } ValueType;
+
+ //----------------------------------------------------------------------
+ // Token size/granularities for Input Readers
+ //----------------------------------------------------------------------
+
+ typedef enum InputReaderGranularity
+ {
+ eInputReaderGranularityInvalid = 0,
+ eInputReaderGranularityByte,
+ eInputReaderGranularityWord,
+ eInputReaderGranularityLine,
+ eInputReaderGranularityAll
+ } InputReaderGranularity;
+
+ //------------------------------------------------------------------
+ /// These mask bits allow a common interface for queries that can
+ /// limit the amount of information that gets parsed to only the
+ /// information that is requested. These bits also can indicate what
+ /// actually did get resolved during query function calls.
+ ///
+ /// Each definition corresponds to a one of the member variables
+ /// in this class, and requests that that item be resolved, or
+ /// indicates that the member did get resolved.
+ //------------------------------------------------------------------
+ typedef enum SymbolContextItem
+ {
+ eSymbolContextTarget = (1u << 0), ///< Set when \a target is requested from a query, or was located in query results
+ eSymbolContextModule = (1u << 1), ///< Set when \a module is requested from a query, or was located in query results
+ eSymbolContextCompUnit = (1u << 2), ///< Set when \a comp_unit is requested from a query, or was located in query results
+ eSymbolContextFunction = (1u << 3), ///< Set when \a function is requested from a query, or was located in query results
+ eSymbolContextBlock = (1u << 4), ///< Set when the deepest \a block is requested from a query, or was located in query results
+ eSymbolContextLineEntry = (1u << 5), ///< Set when \a line_entry is requested from a query, or was located in query results
+ eSymbolContextSymbol = (1u << 6), ///< Set when \a symbol is requested from a query, or was located in query results
+ eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1u) ///< Indicates to try and lookup everything up during a query.
+ } SymbolContextItem;
+
+ typedef enum Permissions
+ {
+ ePermissionsWritable = (1u << 0),
+ ePermissionsReadable = (1u << 1),
+ ePermissionsExecutable = (1u << 2)
+ } Permissions;
+
+ typedef enum InputReaderAction
+ {
+ eInputReaderActivate, // reader is newly pushed onto the reader stack
+ eInputReaderAsynchronousOutputWritten, // an async output event occurred; the reader may want to do something
+ eInputReaderReactivate, // reader is on top of the stack again after another reader was popped off
+ eInputReaderDeactivate, // another reader was pushed on the stack
+ eInputReaderGotToken, // reader got one of its tokens (granularity)
+ eInputReaderInterrupt, // reader received an interrupt signal (probably from a control-c)
+ eInputReaderEndOfFile, // reader received an EOF char (probably from a control-d)
+ eInputReaderDone // reader was just popped off the stack and is done
+ } InputReaderAction;
+
+ typedef enum BreakpointEventType
+ {
+ eBreakpointEventTypeInvalidType = (1u << 0),
+ eBreakpointEventTypeAdded = (1u << 1),
+ eBreakpointEventTypeRemoved = (1u << 2),
+ eBreakpointEventTypeLocationsAdded = (1u << 3), // Locations added doesn't get sent when the breakpoint is created
+ eBreakpointEventTypeLocationsRemoved = (1u << 4),
+ eBreakpointEventTypeLocationsResolved = (1u << 5),
+ eBreakpointEventTypeEnabled = (1u << 6),
+ eBreakpointEventTypeDisabled = (1u << 7),
+ eBreakpointEventTypeCommandChanged = (1u << 8),
+ eBreakpointEventTypeConditionChanged = (1u << 9),
+ eBreakpointEventTypeIgnoreChanged = (1u << 10),
+ eBreakpointEventTypeThreadChanged = (1u << 11)
+ } BreakpointEventType;
+
+ typedef enum WatchpointEventType
+ {
+ eWatchpointEventTypeInvalidType = (1u << 0),
+ eWatchpointEventTypeAdded = (1u << 1),
+ eWatchpointEventTypeRemoved = (1u << 2),
+ eWatchpointEventTypeEnabled = (1u << 6),
+ eWatchpointEventTypeDisabled = (1u << 7),
+ eWatchpointEventTypeCommandChanged = (1u << 8),
+ eWatchpointEventTypeConditionChanged = (1u << 9),
+ eWatchpointEventTypeIgnoreChanged = (1u << 10),
+ eWatchpointEventTypeThreadChanged = (1u << 11),
+ eWatchpointEventTypeTypeChanged = (1u << 12)
+ } WatchpointEventType;
+
+
+ //----------------------------------------------------------------------
+ /// Programming language type.
+ ///
+ /// These enumerations use the same language enumerations as the DWARF
+ /// specification for ease of use and consistency.
+ /// The enum -> string code is in LanguageRuntime.cpp, don't change this
+ /// table without updating that code as well.
+ //----------------------------------------------------------------------
+ typedef enum LanguageType
+ {
+ eLanguageTypeUnknown = 0x0000, ///< Unknown or invalid language value.
+ eLanguageTypeC89 = 0x0001, ///< ISO C:1989.
+ eLanguageTypeC = 0x0002, ///< Non-standardized C, such as K&R.
+ eLanguageTypeAda83 = 0x0003, ///< ISO Ada:1983.
+ eLanguageTypeC_plus_plus = 0x0004, ///< ISO C++:1998.
+ eLanguageTypeCobol74 = 0x0005, ///< ISO Cobol:1974.
+ eLanguageTypeCobol85 = 0x0006, ///< ISO Cobol:1985.
+ eLanguageTypeFortran77 = 0x0007, ///< ISO Fortran 77.
+ eLanguageTypeFortran90 = 0x0008, ///< ISO Fortran 90.
+ eLanguageTypePascal83 = 0x0009, ///< ISO Pascal:1983.
+ eLanguageTypeModula2 = 0x000a, ///< ISO Modula-2:1996.
+ eLanguageTypeJava = 0x000b, ///< Java.
+ eLanguageTypeC99 = 0x000c, ///< ISO C:1999.
+ eLanguageTypeAda95 = 0x000d, ///< ISO Ada:1995.
+ eLanguageTypeFortran95 = 0x000e, ///< ISO Fortran 95.
+ eLanguageTypePLI = 0x000f, ///< ANSI PL/I:1976.
+ eLanguageTypeObjC = 0x0010, ///< Objective-C.
+ eLanguageTypeObjC_plus_plus = 0x0011, ///< Objective-C++.
+ eLanguageTypeUPC = 0x0012, ///< Unified Parallel C.
+ eLanguageTypeD = 0x0013, ///< D.
+ eLanguageTypePython = 0x0014, ///< Python.
+ eNumLanguageTypes
+ } LanguageType;
+
+ typedef enum DynamicValueType
+ {
+ eNoDynamicValues = 0,
+ eDynamicCanRunTarget = 1,
+ eDynamicDontRunTarget = 2
+ } DynamicValueType;
+
+ typedef enum AccessType
+ {
+ eAccessNone,
+ eAccessPublic,
+ eAccessPrivate,
+ eAccessProtected,
+ eAccessPackage
+ } AccessType;
+
+ typedef enum CommandArgumentType
+ {
+ eArgTypeAddress = 0,
+ eArgTypeAddressOrExpression,
+ eArgTypeAliasName,
+ eArgTypeAliasOptions,
+ eArgTypeArchitecture,
+ eArgTypeBoolean,
+ eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange,
+ eArgTypeByteSize,
+ eArgTypeClassName,
+ eArgTypeCommandName,
+ eArgTypeCount,
+ eArgTypeDirectoryName,
+ eArgTypeDisassemblyFlavor,
+ eArgTypeEndAddress,
+ eArgTypeExpression,
+ eArgTypeExpressionPath,
+ eArgTypeExprFormat,
+ eArgTypeFilename,
+ eArgTypeFormat,
+ eArgTypeFrameIndex,
+ eArgTypeFullName,
+ eArgTypeFunctionName,
+ eArgTypeFunctionOrSymbol,
+ eArgTypeGDBFormat,
+ eArgTypeIndex,
+ eArgTypeLanguage,
+ eArgTypeLineNum,
+ eArgTypeLogCategory,
+ eArgTypeLogChannel,
+ eArgTypeMethod,
+ eArgTypeName,
+ eArgTypeNewPathPrefix,
+ eArgTypeNumLines,
+ eArgTypeNumberPerLine,
+ eArgTypeOffset,
+ eArgTypeOldPathPrefix,
+ eArgTypeOneLiner,
+ eArgTypePid,
+ eArgTypePlugin,
+ eArgTypeProcessName,
+ eArgTypePythonClass,
+ eArgTypePythonFunction,
+ eArgTypePythonScript,
+ eArgTypeQueueName,
+ eArgTypeRegisterName,
+ eArgTypeRegularExpression,
+ eArgTypeRunArgs,
+ eArgTypeRunMode,
+ eArgTypeScriptedCommandSynchronicity,
+ eArgTypeScriptLang,
+ eArgTypeSearchWord,
+ eArgTypeSelector,
+ eArgTypeSettingIndex,
+ eArgTypeSettingKey,
+ eArgTypeSettingPrefix,
+ eArgTypeSettingVariableName,
+ eArgTypeShlibName,
+ eArgTypeSourceFile,
+ eArgTypeSortOrder,
+ eArgTypeStartAddress,
+ eArgTypeSummaryString,
+ eArgTypeSymbol,
+ eArgTypeThreadID,
+ eArgTypeThreadIndex,
+ eArgTypeThreadName,
+ eArgTypeUnsignedInteger,
+ eArgTypeUnixSignal,
+ eArgTypeVarName,
+ eArgTypeValue,
+ eArgTypeWidth,
+ eArgTypeNone,
+ eArgTypePlatform,
+ eArgTypeWatchpointID,
+ eArgTypeWatchpointIDRange,
+ eArgTypeWatchType,
+ eArgTypeLastArg // Always keep this entry as the last entry in this enumeration!!
+ } CommandArgumentType;
+
+ //----------------------------------------------------------------------
+ // Symbol types
+ //----------------------------------------------------------------------
+ typedef enum SymbolType
+ {
+ eSymbolTypeAny = 0,
+ eSymbolTypeInvalid = 0,
+ eSymbolTypeAbsolute,
+ eSymbolTypeCode,
+ eSymbolTypeResolver,
+ eSymbolTypeData,
+ eSymbolTypeTrampoline,
+ eSymbolTypeRuntime,
+ eSymbolTypeException,
+ eSymbolTypeSourceFile,
+ eSymbolTypeHeaderFile,
+ eSymbolTypeObjectFile,
+ eSymbolTypeCommonBlock,
+ eSymbolTypeBlock,
+ eSymbolTypeLocal,
+ eSymbolTypeParam,
+ eSymbolTypeVariable,
+ eSymbolTypeVariableType,
+ eSymbolTypeLineEntry,
+ eSymbolTypeLineHeader,
+ eSymbolTypeScopeBegin,
+ eSymbolTypeScopeEnd,
+ eSymbolTypeAdditional, // When symbols take more than one entry, the extra entries get this type
+ eSymbolTypeCompiler,
+ eSymbolTypeInstrumentation,
+ eSymbolTypeUndefined,
+ eSymbolTypeObjCClass,
+ eSymbolTypeObjCMetaClass,
+ eSymbolTypeObjCIVar
+ } SymbolType;
+
+ typedef enum SectionType
+ {
+ eSectionTypeInvalid,
+ eSectionTypeCode,
+ eSectionTypeContainer, // The section contains child sections
+ eSectionTypeData,
+ eSectionTypeDataCString, // Inlined C string data
+ eSectionTypeDataCStringPointers, // Pointers to C string data
+ eSectionTypeDataSymbolAddress, // Address of a symbol in the symbol table
+ eSectionTypeData4,
+ eSectionTypeData8,
+ eSectionTypeData16,
+ eSectionTypeDataPointers,
+ eSectionTypeDebug,
+ eSectionTypeZeroFill,
+ eSectionTypeDataObjCMessageRefs, // Pointer to function pointer + selector
+ eSectionTypeDataObjCCFStrings, // Objective C const CFString/NSString objects
+ eSectionTypeDWARFDebugAbbrev,
+ eSectionTypeDWARFDebugAranges,
+ eSectionTypeDWARFDebugFrame,
+ eSectionTypeDWARFDebugInfo,
+ eSectionTypeDWARFDebugLine,
+ eSectionTypeDWARFDebugLoc,
+ eSectionTypeDWARFDebugMacInfo,
+ eSectionTypeDWARFDebugPubNames,
+ eSectionTypeDWARFDebugPubTypes,
+ eSectionTypeDWARFDebugRanges,
+ eSectionTypeDWARFDebugStr,
+ eSectionTypeDWARFAppleNames,
+ eSectionTypeDWARFAppleTypes,
+ eSectionTypeDWARFAppleNamespaces,
+ eSectionTypeDWARFAppleObjC,
+ eSectionTypeELFSymbolTable, // Elf SHT_SYMTAB section
+ eSectionTypeELFDynamicSymbols, // Elf SHT_DYNSYM section
+ eSectionTypeELFRelocationEntries, // Elf SHT_REL or SHT_REL section
+ eSectionTypeELFDynamicLinkInfo, // Elf SHT_DYNAMIC section
+ eSectionTypeEHFrame,
+ eSectionTypeOther
+
+ } SectionType;
+
+ typedef enum EmulateInstructionOptions
+ {
+ eEmulateInstructionOptionNone = (0u),
+ eEmulateInstructionOptionAutoAdvancePC = (1u << 0),
+ eEmulateInstructionOptionIgnoreConditions = (1u << 1)
+ } EmulateInstructionOptions;
+
+ typedef enum FunctionNameType
+ {
+ eFunctionNameTypeNone = 0u,
+ eFunctionNameTypeAuto = (1u << 1), // Automatically figure out which FunctionNameType
+ // bits to set based on the function name.
+ eFunctionNameTypeFull = (1u << 2), // The function name.
+ // For C this is the same as just the name of the function
+ // For C++ this is the mangled or demangled version of the mangled name.
+ // For ObjC this is the full function signature with the + or
+ // - and the square brackets and the class and selector
+ eFunctionNameTypeBase = (1u << 3), // The function name only, no namespaces or arguments and no class
+ // methods or selectors will be searched.
+ eFunctionNameTypeMethod = (1u << 4), // Find function by method name (C++) with no namespace or arguments
+ eFunctionNameTypeSelector = (1u << 5), // Find function by selector name (ObjC) names
+ eFunctionNameTypeAny = eFunctionNameTypeAuto // DEPRECATED: use eFunctionNameTypeAuto
+ } FunctionNameType;
+
+
+ //----------------------------------------------------------------------
+ // Basic types enumeration for the public API SBType::GetBasicType()
+ //----------------------------------------------------------------------
+ typedef enum BasicType
+ {
+ eBasicTypeInvalid = 0,
+ eBasicTypeVoid = 1,
+ eBasicTypeChar,
+ eBasicTypeSignedChar,
+ eBasicTypeUnsignedChar,
+ eBasicTypeWChar,
+ eBasicTypeSignedWChar,
+ eBasicTypeUnsignedWChar,
+ eBasicTypeChar16,
+ eBasicTypeChar32,
+ eBasicTypeShort,
+ eBasicTypeUnsignedShort,
+ eBasicTypeInt,
+ eBasicTypeUnsignedInt,
+ eBasicTypeLong,
+ eBasicTypeUnsignedLong,
+ eBasicTypeLongLong,
+ eBasicTypeUnsignedLongLong,
+ eBasicTypeInt128,
+ eBasicTypeUnsignedInt128,
+ eBasicTypeBool,
+ eBasicTypeHalf,
+ eBasicTypeFloat,
+ eBasicTypeDouble,
+ eBasicTypeLongDouble,
+ eBasicTypeFloatComplex,
+ eBasicTypeDoubleComplex,
+ eBasicTypeLongDoubleComplex,
+ eBasicTypeObjCID,
+ eBasicTypeObjCClass,
+ eBasicTypeObjCSel,
+ eBasicTypeNullPtr,
+ eBasicTypeOther
+ } BasicType;
+
+ typedef enum TypeClass
+ {
+ eTypeClassInvalid = (0u),
+ eTypeClassArray = (1u << 0),
+ eTypeClassBlockPointer = (1u << 1),
+ eTypeClassBuiltin = (1u << 2),
+ eTypeClassClass = (1u << 3),
+ eTypeClassComplexFloat = (1u << 4),
+ eTypeClassComplexInteger = (1u << 5),
+ eTypeClassEnumeration = (1u << 6),
+ eTypeClassFunction = (1u << 7),
+ eTypeClassMemberPointer = (1u << 8),
+ eTypeClassObjCObject = (1u << 9),
+ eTypeClassObjCInterface = (1u << 10),
+ eTypeClassObjCObjectPointer = (1u << 11),
+ eTypeClassPointer = (1u << 12),
+ eTypeClassReference = (1u << 13),
+ eTypeClassStruct = (1u << 14),
+ eTypeClassTypedef = (1u << 15),
+ eTypeClassUnion = (1u << 16),
+ eTypeClassVector = (1u << 17),
+ // Define the last type class as the MSBit of a 32 bit value
+ eTypeClassOther = (1u << 31),
+ // Define a mask that can be used for any type when finding types
+ eTypeClassAny = (0xffffffffu)
+ } TypeClass;
+
+ typedef enum TemplateArgumentKind
+ {
+ eTemplateArgumentKindNull = 0,
+ eTemplateArgumentKindType,
+ eTemplateArgumentKindDeclaration,
+ eTemplateArgumentKindIntegral,
+ eTemplateArgumentKindTemplate,
+ eTemplateArgumentKindTemplateExpansion,
+ eTemplateArgumentKindExpression,
+ eTemplateArgumentKindPack
+
+ } TemplateArgumentKind;
+
+ //----------------------------------------------------------------------
+ // Options that can be set for a formatter to alter its behavior
+ // Not all of these are applicable to all formatter types
+ //----------------------------------------------------------------------
+ typedef enum TypeOptions
+ {
+ eTypeOptionNone = (0u),
+ eTypeOptionCascade = (1u << 0),
+ eTypeOptionSkipPointers = (1u << 1),
+ eTypeOptionSkipReferences = (1u << 2),
+ eTypeOptionHideChildren = (1u << 3),
+ eTypeOptionHideValue = (1u << 4),
+ eTypeOptionShowOneLiner = (1u << 5),
+ eTypeOptionHideNames = (1u << 6)
+ } TypeOptions;
+
+ //----------------------------------------------------------------------
+ // This is the return value for frame comparisons. When frame A pushes
+ // frame B onto the stack, frame A is OLDER than frame B.
+ //----------------------------------------------------------------------
+ typedef enum FrameComparison
+ {
+ eFrameCompareInvalid,
+ eFrameCompareUnknown,
+ eFrameCompareEqual,
+ eFrameCompareYounger,
+ eFrameCompareOlder
+ } FrameComparison;
+
+ //----------------------------------------------------------------------
+ // Address Class
+ //
+ // A way of classifying an address used for disassembling and setting
+ // breakpoints. Many object files can track exactly what parts of their
+ // object files are code, data and other information. This is of course
+ // above and beyond just looking at the section types. For example, code
+ // might contain PC relative data and the object file might be able to
+ // tell us that an address in code is data.
+ //----------------------------------------------------------------------
+ typedef enum AddressClass
+ {
+ eAddressClassInvalid,
+ eAddressClassUnknown,
+ eAddressClassCode,
+ eAddressClassCodeAlternateISA,
+ eAddressClassData,
+ eAddressClassDebug,
+ eAddressClassRuntime
+ } AddressClass;
+
+} // namespace lldb
+
+
+#endif // LLDB_lldb_enumerations_h_
diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h
new file mode 100644
index 000000000000..84af8b646901
--- /dev/null
+++ b/include/lldb/lldb-forward.h
@@ -0,0 +1,378 @@
+//===-- lldb-forward.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_lldb_forward_h_
+#define LLDB_lldb_forward_h_
+
+#if defined(__cplusplus)
+
+#include "lldb/Utility/SharingPtr.h"
+
+//----------------------------------------------------------------------
+// lldb forward declarations
+//----------------------------------------------------------------------
+namespace lldb_private {
+
+class ABI;
+class Address;
+class AddressImpl;
+class AddressRange;
+class AddressResolver;
+class ArchSpec;
+class Args;
+class ASTResultSynthesizer;
+class Baton;
+class Block;
+class Breakpoint;
+class BreakpointID;
+class BreakpointIDList;
+class BreakpointList;
+class BreakpointLocation;
+class BreakpointLocationCollection;
+class BreakpointLocationList;
+class BreakpointOptions;
+class BreakpointResolver;
+class BreakpointSite;
+class BreakpointSiteList;
+class BroadcastEventSpec;
+class Broadcaster;
+class BroadcasterManager;
+class CPPLanguageRuntime;
+class ClangASTContext;
+class ClangASTImporter;
+class ClangASTMetadata;
+class ClangASTSource;
+class ClangASTType;
+class ClangNamespaceDecl;
+class ClangExpression;
+class ClangExpressionDeclMap;
+class ClangExpressionParser;
+class ClangExpressionVariable;
+class ClangExpressionVariableList;
+class ClangExpressionVariableList;
+class ClangExpressionVariables;
+class ClangFunction;
+class ClangPersistentVariables;
+class ClangUserExpression;
+class ClangUtilityFunction;
+class CommandInterpreter;
+class CommandObject;
+class CommandReturnObject;
+class Communication;
+class CompileUnit;
+class Condition;
+class Connection;
+class ConnectionFileDescriptor;
+class ConstString;
+class CXXSyntheticChildren;
+class DWARFCallFrameInfo;
+class DWARFExpression;
+class DataBuffer;
+class DataEncoder;
+class DataExtractor;
+class Debugger;
+class Declaration;
+class Disassembler;
+class DynamicLibrary;
+class DynamicLoader;
+class EmulateInstruction;
+class Error;
+class EvaluateExpressionOptions;
+class Event;
+class EventData;
+class ExecutionContext;
+class ExecutionContextRef;
+class ExecutionContextRefLocker;
+class ExecutionContextScope;
+class FileSpec;
+class FileSpecList;
+class Flags;
+class TypeCategoryImpl;
+class FormatManager;
+class FuncUnwinders;
+class Function;
+class FunctionInfo;
+class InlineFunctionInfo;
+class InputReader;
+class Instruction;
+class InstructionList;
+class IRExecutionUnit;
+class LanguageRuntime;
+class LineTable;
+class Listener;
+class Log;
+class LogChannel;
+class Mangled;
+class Materializer;
+class Module;
+class ModuleList;
+class ModuleSpec;
+class ModuleSpecList;
+class Mutex;
+struct NameSearchContext;
+class ObjCLanguageRuntime;
+class ObjectContainer;
+class OptionGroup;
+class OptionGroupPlatform;
+class ObjectFile;
+class OperatingSystem;
+class Options;
+class OptionValue;
+class OptionValueArch;
+class OptionValueArgs;
+class OptionValueArray;
+class OptionValueBoolean;
+class OptionValueDictionary;
+class OptionValueEnumeration;
+class OptionValueFileSpec;
+class OptionValueFileSpecList;
+class OptionValueFormat;
+class OptionValuePathMappings;
+class OptionValueProperties;
+class OptionValueRegex;
+class OptionValueSInt64;
+class OptionValueString;
+class OptionValueUInt64;
+class OptionValueUUID;
+class NamedOption;
+class PathMappingList;
+class Platform;
+class Process;
+class ProcessAttachInfo;
+class ProcessModID;
+class ProcessInfo;
+class ProcessInstanceInfo;
+class ProcessInstanceInfoList;
+class ProcessInstanceInfoMatch;
+class ProcessLaunchInfo;
+class Property;
+struct PropertyDefinition;
+class PythonArray;
+class PythonDictionary;
+class PythonInteger;
+class PythonObject;
+class PythonString;
+class RegisterContext;
+class RegisterLocation;
+class RegisterLocationList;
+class RegisterValue;
+class RegularExpression;
+class Scalar;
+class ScriptInterpreter;
+class ScriptInterpreterLocker;
+class ScriptInterpreterObject;
+#ifndef LLDB_DISABLE_PYTHON
+class ScriptInterpreterPython;
+struct ScriptSummaryFormat;
+#endif
+class SearchFilter;
+class Section;
+class SectionImpl;
+class SectionList;
+class Settings;
+class SourceManager;
+class SourceManagerImpl;
+class StackFrame;
+class StackFrameImpl;
+class StackFrameList;
+class StackID;
+class StopInfo;
+class Stoppoint;
+class StoppointCallbackContext;
+class StoppointLocation;
+class Stream;
+template <unsigned N> class StreamBuffer;
+class StreamFile;
+class StreamString;
+class StringList;
+struct StringSummaryFormat;
+class TypeSummaryImpl;
+class Symbol;
+class SymbolContext;
+class SymbolContextList;
+class SymbolContextScope;
+class SymbolContextSpecifier;
+class SymbolFile;
+class SymbolFileType;
+class SymbolVendor;
+class Symtab;
+class SyntheticChildren;
+class SyntheticChildrenFrontEnd;
+class TypeFilterImpl;
+#ifndef LLDB_DISABLE_PYTHON
+class ScriptedSyntheticChildren;
+#endif
+class Target;
+class TargetList;
+class Thread;
+class ThreadList;
+class ThreadPlan;
+class ThreadPlanBase;
+class ThreadPlanRunToAddress;
+class ThreadPlanStepInstruction;
+class ThreadPlanStepOut;
+class ThreadPlanStepOverBreakpoint;
+class ThreadPlanStepRange;
+class ThreadPlanStepThrough;
+class ThreadPlanTracer;
+class ThreadSpec;
+class TimeValue;
+class Type;
+class TypeCategoryMap;
+class TypeImpl;
+class TypeAndOrName;
+class TypeList;
+class TypeListImpl;
+class TypeMemberImpl;
+class TypeNameSpecifierImpl;
+class UUID;
+class Unwind;
+class UnwindAssembly;
+class UnwindPlan;
+class UnwindTable;
+class VMRange;
+class Value;
+class TypeFormatImpl;
+class ValueList;
+class ValueObject;
+class ValueObjectChild;
+class ValueObjectConstResult;
+class ValueObjectConstResultChild;
+class ValueObjectConstResultImpl;
+class ValueObjectList;
+class Variable;
+class VariableList;
+class Watchpoint;
+class WatchpointList;
+class WatchpointOptions;
+struct LineEntry;
+
+} // namespace lldb_private
+
+//----------------------------------------------------------------------
+// lldb forward declarations
+//----------------------------------------------------------------------
+namespace lldb {
+
+ typedef std::shared_ptr<lldb_private::ABI> ABISP;
+ typedef std::shared_ptr<lldb_private::Baton> BatonSP;
+ typedef std::shared_ptr<lldb_private::Block> BlockSP;
+ typedef std::shared_ptr<lldb_private::Breakpoint> BreakpointSP;
+ typedef std::weak_ptr<lldb_private::Breakpoint> BreakpointWP;
+ typedef std::shared_ptr<lldb_private::BreakpointSite> BreakpointSiteSP;
+ typedef std::weak_ptr<lldb_private::BreakpointSite> BreakpointSiteWP;
+ typedef std::shared_ptr<lldb_private::BreakpointLocation> BreakpointLocationSP;
+ typedef std::weak_ptr<lldb_private::BreakpointLocation> BreakpointLocationWP;
+ typedef std::shared_ptr<lldb_private::BreakpointResolver> BreakpointResolverSP;
+ typedef std::shared_ptr<lldb_private::Broadcaster> BroadcasterSP;
+ typedef std::shared_ptr<lldb_private::ClangExpressionVariable> ClangExpressionVariableSP;
+ typedef std::shared_ptr<lldb_private::CommandObject> CommandObjectSP;
+ typedef std::shared_ptr<lldb_private::Communication> CommunicationSP;
+ typedef std::shared_ptr<lldb_private::Connection> ConnectionSP;
+ typedef std::shared_ptr<lldb_private::CompileUnit> CompUnitSP;
+ typedef std::shared_ptr<lldb_private::DataBuffer> DataBufferSP;
+ typedef std::shared_ptr<lldb_private::DataExtractor> DataExtractorSP;
+ typedef std::shared_ptr<lldb_private::Debugger> DebuggerSP;
+ typedef std::weak_ptr<lldb_private::Debugger> DebuggerWP;
+ typedef std::shared_ptr<lldb_private::Disassembler> DisassemblerSP;
+ typedef std::shared_ptr<lldb_private::DynamicLibrary> DynamicLibrarySP;
+ typedef std::shared_ptr<lldb_private::DynamicLoader> DynamicLoaderSP;
+ typedef std::shared_ptr<lldb_private::Event> EventSP;
+ typedef std::shared_ptr<lldb_private::ExecutionContextRef> ExecutionContextRefSP;
+ typedef std::shared_ptr<lldb_private::Function> FunctionSP;
+ typedef std::shared_ptr<lldb_private::FuncUnwinders> FuncUnwindersSP;
+ typedef std::shared_ptr<lldb_private::InlineFunctionInfo> InlineFunctionInfoSP;
+ typedef std::shared_ptr<lldb_private::InputReader> InputReaderSP;
+ typedef std::shared_ptr<lldb_private::Instruction> InstructionSP;
+ typedef std::shared_ptr<lldb_private::LanguageRuntime> LanguageRuntimeSP;
+ typedef std::shared_ptr<lldb_private::LineTable> LineTableSP;
+ typedef std::shared_ptr<lldb_private::Listener> ListenerSP;
+ typedef std::shared_ptr<lldb_private::LogChannel> LogChannelSP;
+ typedef std::shared_ptr<lldb_private::Module> ModuleSP;
+ typedef std::weak_ptr<lldb_private::Module> ModuleWP;
+ typedef std::shared_ptr<lldb_private::ObjectFile> ObjectFileSP;
+ typedef std::weak_ptr<lldb_private::ObjectFile> ObjectFileWP;
+ typedef std::shared_ptr<lldb_private::OptionValue> OptionValueSP;
+ typedef std::weak_ptr<lldb_private::OptionValue> OptionValueWP;
+ typedef std::shared_ptr<lldb_private::OptionValueArch> OptionValueArchSP;
+ typedef std::shared_ptr<lldb_private::OptionValueArgs> OptionValueArgsSP;
+ typedef std::shared_ptr<lldb_private::OptionValueArray> OptionValueArraySP;
+ typedef std::shared_ptr<lldb_private::OptionValueBoolean> OptionValueBooleanSP;
+ typedef std::shared_ptr<lldb_private::OptionValueDictionary> OptionValueDictionarySP;
+ typedef std::shared_ptr<lldb_private::OptionValueFileSpec> OptionValueFileSpecSP;
+ typedef std::shared_ptr<lldb_private::OptionValueFileSpecList> OptionValueFileSpecListSP;
+ typedef std::shared_ptr<lldb_private::OptionValueFormat> OptionValueFormatSP;
+ typedef std::shared_ptr<lldb_private::OptionValuePathMappings> OptionValuePathMappingsSP;
+ typedef std::shared_ptr<lldb_private::OptionValueProperties> OptionValuePropertiesSP;
+ typedef std::shared_ptr<lldb_private::OptionValueRegex> OptionValueRegexSP;
+ typedef std::shared_ptr<lldb_private::OptionValueSInt64> OptionValueSInt64SP;
+ typedef std::shared_ptr<lldb_private::OptionValueString> OptionValueStringSP;
+ typedef std::shared_ptr<lldb_private::OptionValueUInt64> OptionValueUInt64SP;
+ typedef std::shared_ptr<lldb_private::OptionValueUUID> OptionValueUUIDSP;
+ typedef std::shared_ptr<lldb_private::Platform> PlatformSP;
+ typedef std::shared_ptr<lldb_private::Process> ProcessSP;
+ typedef std::shared_ptr<lldb_private::ProcessAttachInfo> ProcessAttachInfoSP;
+ typedef std::shared_ptr<lldb_private::ProcessLaunchInfo> ProcessLaunchInfoSP;
+ typedef std::weak_ptr<lldb_private::Process> ProcessWP;
+ typedef std::shared_ptr<lldb_private::Property> PropertySP;
+ typedef std::shared_ptr<lldb_private::RegisterContext> RegisterContextSP;
+ typedef std::shared_ptr<lldb_private::RegularExpression> RegularExpressionSP;
+ typedef std::shared_ptr<lldb_private::ScriptInterpreterObject> ScriptInterpreterObjectSP;
+#ifndef LLDB_DISABLE_PYTHON
+ typedef std::shared_ptr<lldb_private::ScriptSummaryFormat> ScriptSummaryFormatSP;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+ typedef std::shared_ptr<lldb_private::Section> SectionSP;
+ typedef std::weak_ptr<lldb_private::Section> SectionWP;
+ typedef std::shared_ptr<lldb_private::SearchFilter> SearchFilterSP;
+ typedef std::shared_ptr<lldb_private::Settings> SettingsSP;
+ typedef std::shared_ptr<lldb_private::StackFrame> StackFrameSP;
+ typedef std::weak_ptr<lldb_private::StackFrame> StackFrameWP;
+ typedef std::shared_ptr<lldb_private::StackFrameList> StackFrameListSP;
+ typedef std::shared_ptr<lldb_private::StopInfo> StopInfoSP;
+ typedef std::shared_ptr<lldb_private::StoppointLocation> StoppointLocationSP;
+ typedef std::shared_ptr<lldb_private::Stream> StreamSP;
+ typedef std::weak_ptr<lldb_private::Stream> StreamWP;
+ typedef std::shared_ptr<lldb_private::StringSummaryFormat> StringTypeSummaryImplSP;
+ typedef std::shared_ptr<lldb_private::SymbolFile> SymbolFileSP;
+ typedef std::shared_ptr<lldb_private::SymbolFileType> SymbolFileTypeSP;
+ typedef std::weak_ptr<lldb_private::SymbolFileType> SymbolFileTypeWP;
+ typedef std::shared_ptr<lldb_private::SymbolContextSpecifier> SymbolContextSpecifierSP;
+ typedef std::shared_ptr<lldb_private::SyntheticChildren> SyntheticChildrenSP;
+ typedef std::shared_ptr<lldb_private::SyntheticChildrenFrontEnd> SyntheticChildrenFrontEndSP;
+ typedef std::shared_ptr<lldb_private::Target> TargetSP;
+ typedef std::weak_ptr<lldb_private::Target> TargetWP;
+ typedef std::shared_ptr<lldb_private::Thread> ThreadSP;
+ typedef std::weak_ptr<lldb_private::Thread> ThreadWP;
+ typedef std::shared_ptr<lldb_private::ThreadPlan> ThreadPlanSP;
+ typedef std::shared_ptr<lldb_private::ThreadPlanTracer> ThreadPlanTracerSP;
+ typedef std::shared_ptr<lldb_private::Type> TypeSP;
+ typedef std::weak_ptr<lldb_private::Type> TypeWP;
+ typedef std::shared_ptr<lldb_private::TypeCategoryImpl> TypeCategoryImplSP;
+ typedef std::shared_ptr<lldb_private::TypeImpl> TypeImplSP;
+ typedef std::shared_ptr<lldb_private::TypeFilterImpl> TypeFilterImplSP;
+ typedef std::shared_ptr<lldb_private::TypeFormatImpl> TypeFormatImplSP;
+ typedef std::shared_ptr<lldb_private::TypeNameSpecifierImpl> TypeNameSpecifierImplSP;
+ typedef std::shared_ptr<lldb_private::TypeSummaryImpl> TypeSummaryImplSP;
+#ifndef LLDB_DISABLE_PYTHON
+ typedef std::shared_ptr<lldb_private::ScriptedSyntheticChildren> ScriptedSyntheticChildrenSP;
+#endif
+ typedef std::shared_ptr<lldb_private::UnwindPlan> UnwindPlanSP;
+ typedef lldb_private::SharingPtr<lldb_private::ValueObject> ValueObjectSP;
+ typedef std::shared_ptr<lldb_private::Value> ValueSP;
+ typedef std::shared_ptr<lldb_private::ValueList> ValueListSP;
+ typedef std::shared_ptr<lldb_private::Variable> VariableSP;
+ typedef std::shared_ptr<lldb_private::VariableList> VariableListSP;
+ typedef std::shared_ptr<lldb_private::ValueObjectList> ValueObjectListSP;
+ typedef std::shared_ptr<lldb_private::Watchpoint> WatchpointSP;
+
+} // namespace lldb
+
+
+#endif // #if defined(__cplusplus)
+#endif // LLDB_lldb_forward_h_
diff --git a/include/lldb/lldb-private-enumerations.h b/include/lldb/lldb-private-enumerations.h
new file mode 100644
index 000000000000..60c90907145f
--- /dev/null
+++ b/include/lldb/lldb-private-enumerations.h
@@ -0,0 +1,245 @@
+//===-- lldb-private-enumerations.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_lldb_private_enumerations_h_
+#define LLDB_lldb_private_enumerations_h_
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// Thread Step Types
+//----------------------------------------------------------------------
+typedef enum StepType
+{
+ eStepTypeNone,
+ eStepTypeTrace, ///< Single step one instruction.
+ eStepTypeTraceOver, ///< Single step one instruction, stepping over.
+ eStepTypeInto, ///< Single step into a specified context.
+ eStepTypeOver, ///< Single step over a specified context.
+ eStepTypeOut ///< Single step out a specified context.
+} StepType;
+
+//----------------------------------------------------------------------
+// Address Types
+//----------------------------------------------------------------------
+typedef enum AddressType
+{
+ eAddressTypeInvalid = 0,
+ eAddressTypeFile, ///< Address is an address as found in an object or symbol file
+ eAddressTypeLoad, ///< Address is an address as in the current target inferior process
+ eAddressTypeHost ///< Address is an address in the process that is running this code
+} AddressType;
+
+//----------------------------------------------------------------------
+// Votes - Need a tri-state, yes, no, no opinion...
+//----------------------------------------------------------------------
+typedef enum Vote
+{
+ eVoteNo = -1,
+ eVoteNoOpinion = 0,
+ eVoteYes = 1
+} Vote;
+
+typedef enum ArchitectureType
+{
+ eArchTypeInvalid,
+ eArchTypeMachO,
+ eArchTypeELF,
+ kNumArchTypes
+} ArchitectureType;
+
+//----------------------------------------------------------------------
+/// Settable state variable types.
+///
+//----------------------------------------------------------------------
+
+//typedef enum SettableVariableType
+//{
+// eSetVarTypeInt,
+// eSetVarTypeBoolean,
+// eSetVarTypeString,
+// eSetVarTypeArray,
+// eSetVarTypeDictionary,
+// eSetVarTypeEnum,
+// eSetVarTypeNone
+//} SettableVariableType;
+
+typedef enum VarSetOperationType
+{
+ eVarSetOperationReplace,
+ eVarSetOperationInsertBefore,
+ eVarSetOperationInsertAfter,
+ eVarSetOperationRemove,
+ eVarSetOperationAppend,
+ eVarSetOperationClear,
+ eVarSetOperationAssign,
+ eVarSetOperationInvalid
+} VarSetOperationType;
+
+typedef enum ArgumentRepetitionType
+{
+ eArgRepeatPlain, // Exactly one occurrence
+ eArgRepeatOptional, // At most one occurrence, but it's optional
+ eArgRepeatPlus, // One or more occurrences
+ eArgRepeatStar, // Zero or more occurrences
+ eArgRepeatRange, // Repetition of same argument, from 1 to n
+ eArgRepeatPairPlain, // A pair of arguments that must always go together ([arg-type arg-value]), occurs exactly once
+ eArgRepeatPairOptional, // A pair that occurs at most once (optional)
+ eArgRepeatPairPlus, // One or more occurrences of a pair
+ eArgRepeatPairStar, // Zero or more occurrences of a pair
+ eArgRepeatPairRange, // A pair that repeats from 1 to n
+ eArgRepeatPairRangeOptional // A pair that repeats from 1 to n, but is optional
+} ArgumentRepetitionType;
+
+typedef enum SortOrder
+{
+ eSortOrderNone,
+ eSortOrderByAddress,
+ eSortOrderByName
+} SortOrder;
+
+
+//----------------------------------------------------------------------
+// Used in conjunction with Host::GetLLDBPath () to find files that
+// are related to
+//----------------------------------------------------------------------
+typedef enum PathType
+{
+ ePathTypeLLDBShlibDir, // The directory where the lldb.so (unix) or LLDB mach-o file in LLDB.framework (MacOSX) exists
+ ePathTypeSupportExecutableDir, // Find LLDB support executable directory (debugserver, etc)
+ ePathTypeHeaderDir, // Find LLDB header file directory
+ ePathTypePythonDir, // Find Python modules (PYTHONPATH) directory
+ ePathTypeLLDBSystemPlugins, // System plug-ins directory
+ ePathTypeLLDBUserPlugins // User plug-ins directory
+} PathType;
+
+
+//----------------------------------------------------------------------
+// We can execute ThreadPlans on one thread with various fall-back modes
+// (try other threads after timeout, etc.) This enum gives the result of
+// thread plan executions.
+//----------------------------------------------------------------------
+typedef enum ExecutionResults
+{
+ eExecutionSetupError,
+ eExecutionCompleted,
+ eExecutionDiscarded,
+ eExecutionInterrupted,
+ eExecutionHitBreakpoint,
+ eExecutionTimedOut
+} ExecutionResults;
+
+typedef enum ObjCRuntimeVersions {
+ eObjC_VersionUnknown = 0,
+ eAppleObjC_V1 = 1,
+ eAppleObjC_V2 = 2
+} ObjCRuntimeVersions;
+
+
+//----------------------------------------------------------------------
+// LazyBool is for boolean values that need to be calculated lazily.
+// Values start off set to eLazyBoolCalculate, and then they can be
+// calculated once and set to eLazyBoolNo or eLazyBoolYes.
+//----------------------------------------------------------------------
+typedef enum LazyBool {
+ eLazyBoolCalculate = -1,
+ eLazyBoolNo = 0,
+ eLazyBoolYes = 1
+} LazyBool;
+
+//------------------------------------------------------------------
+/// Name matching
+//------------------------------------------------------------------
+typedef enum NameMatchType
+{
+ eNameMatchIgnore,
+ eNameMatchEquals,
+ eNameMatchContains,
+ eNameMatchStartsWith,
+ eNameMatchEndsWith,
+ eNameMatchRegularExpression
+
+} NameMatchType;
+
+
+//------------------------------------------------------------------
+/// Instruction types
+//------------------------------------------------------------------
+typedef enum InstructionType
+{
+ eInstructionTypeAny, // Support for any instructions at all (at least one)
+ eInstructionTypePrologueEpilogue, // All prologue and epilogue instructons that push and pop register values and modify sp/fp
+ eInstructionTypePCModifying, // Any instruction that modifies the program counter/instruction pointer
+ eInstructionTypeAll // All instructions of any kind
+
+} InstructionType;
+
+
+//------------------------------------------------------------------
+/// Format category entry types
+//------------------------------------------------------------------
+typedef enum FormatCategoryItem
+{
+ eFormatCategoryItemSummary = 0x0001,
+ eFormatCategoryItemRegexSummary = 0x0002,
+ eFormatCategoryItemFilter = 0x0004,
+ eFormatCategoryItemRegexFilter = 0x0008,
+ eFormatCategoryItemSynth = 0x0010,
+ eFormatCategoryItemRegexSynth = 0x0020
+} FormatCategoryItem;
+
+//------------------------------------------------------------------
+/// Expression execution policies
+//------------------------------------------------------------------
+typedef enum {
+ eExecutionPolicyOnlyWhenNeeded,
+ eExecutionPolicyNever,
+ eExecutionPolicyAlways
+} ExecutionPolicy;
+
+//----------------------------------------------------------------------
+// Ways that the FormatManager picks a particular format for a type
+//----------------------------------------------------------------------
+typedef enum FormatterChoiceCriterion
+{
+ eFormatterChoiceCriterionDirectChoice = 0x00000000,
+ eFormatterChoiceCriterionStrippedPointerReference = 0x00000001,
+ eFormatterChoiceCriterionNavigatedTypedefs = 0x00000002,
+ eFormatterChoiceCriterionRegularExpressionSummary = 0x00000004,
+ eFormatterChoiceCriterionRegularExpressionFilter = 0x00000004,
+ eFormatterChoiceCriterionDynamicObjCDiscovery = 0x00000008,
+ eFormatterChoiceCriterionStrippedBitField = 0x00000010,
+ eFormatterChoiceCriterionWentToStaticValue = 0x00000020
+} FormatterChoiceCriterion;
+
+//----------------------------------------------------------------------
+// Synchronicity behavior of scripted commands
+//----------------------------------------------------------------------
+typedef enum ScriptedCommandSynchronicity
+{
+ eScriptedCommandSynchronicitySynchronous,
+ eScriptedCommandSynchronicityAsynchronous,
+ eScriptedCommandSynchronicityCurrentValue // use whatever the current synchronicity is
+} ScriptedCommandSynchronicity;
+
+
+//----------------------------------------------------------------------
+// Loading modules from memory
+//----------------------------------------------------------------------
+typedef enum MemoryModuleLoadLevel {
+ eMemoryModuleLoadLevelMinimal, // Load sections only
+ eMemoryModuleLoadLevelPartial, // Load function bounds but no symbols
+ eMemoryModuleLoadLevelComplete, // Load sections and all symbols
+} MemoryModuleLoadLevel;
+
+
+} // namespace lldb_private
+
+
+#endif // LLDB_lldb_private_enumerations_h_
diff --git a/include/lldb/lldb-private-interfaces.h b/include/lldb/lldb-private-interfaces.h
new file mode 100644
index 000000000000..949cafed98b3
--- /dev/null
+++ b/include/lldb/lldb-private-interfaces.h
@@ -0,0 +1,46 @@
+//===-- lldb-private-interfaces.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_lldb_private_interfaces_h_
+#define liblldb_lldb_private_interfaces_h_
+
+#if defined(__cplusplus)
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private
+{
+ typedef lldb::ABISP (*ABICreateInstance) (const ArchSpec &arch);
+ typedef Disassembler* (*DisassemblerCreateInstance) (const ArchSpec &arch, const char *flavor);
+ typedef DynamicLoader* (*DynamicLoaderCreateInstance) (Process* process, bool force);
+ typedef ObjectContainer* (*ObjectContainerCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t offset, lldb::offset_t length);
+ typedef size_t (*ObjectFileGetModuleSpecifications) (const FileSpec &file, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, ModuleSpecList &module_specs);
+ typedef ObjectFile* (*ObjectFileCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, const FileSpec* file, lldb::offset_t file_offset, lldb::offset_t length);
+ typedef ObjectFile* (*ObjectFileCreateMemoryInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t offset);
+ typedef LogChannel* (*LogChannelCreateInstance) ();
+ typedef EmulateInstruction * (*EmulateInstructionCreateInstance) (const ArchSpec &arch, InstructionType inst_type);
+ typedef OperatingSystem* (*OperatingSystemCreateInstance) (Process *process, bool force);
+ typedef LanguageRuntime *(*LanguageRuntimeCreateInstance) (Process *process, lldb::LanguageType language);
+ typedef Platform* (*PlatformCreateInstance) (bool force, const ArchSpec *arch);
+ typedef lldb::ProcessSP (*ProcessCreateInstance) (Target &target, Listener &listener, const FileSpec *crash_file_path);
+ typedef SymbolFile* (*SymbolFileCreateInstance) (ObjectFile* obj_file);
+ typedef SymbolVendor* (*SymbolVendorCreateInstance) (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm); // Module can be NULL for default system symbol vendor
+ typedef bool (*BreakpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+ typedef bool (*WatchpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id);
+ typedef lldb::ThreadPlanSP (*ThreadPlanShouldStopHereCallback) (ThreadPlan *current_plan, Flags &flags, void *baton);
+ typedef UnwindAssembly* (*UnwindAssemblyCreateInstance) (const ArchSpec &arch);
+ typedef int (*ComparisonFunction)(const void *, const void *);
+ typedef bool (*CommandOverrideCallback)(void *baton, const char **argv);
+ typedef void (*DebuggerInitializeCallback)(Debugger &debugger);
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+
+#endif // liblldb_lldb_private_interfaces_h_
diff --git a/include/lldb/lldb-private-log.h b/include/lldb/lldb-private-log.h
new file mode 100644
index 000000000000..31a1c23c5e67
--- /dev/null
+++ b/include/lldb/lldb-private-log.h
@@ -0,0 +1,90 @@
+//===-- lldb-private-log.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_lldb_private_log_h_
+#define liblldb_lldb_private_log_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+
+//----------------------------------------------------------------------
+// Log Bits specific to logging in lldb
+//----------------------------------------------------------------------
+#define LIBLLDB_LOG_VERBOSE (1u << 0)
+#define LIBLLDB_LOG_PROCESS (1u << 1)
+#define LIBLLDB_LOG_THREAD (1u << 2)
+#define LIBLLDB_LOG_DYNAMIC_LOADER (1u << 3)
+#define LIBLLDB_LOG_EVENTS (1u << 4)
+#define LIBLLDB_LOG_BREAKPOINTS (1u << 5)
+#define LIBLLDB_LOG_WATCHPOINTS (1u << 6)
+#define LIBLLDB_LOG_STEP (1u << 7)
+#define LIBLLDB_LOG_EXPRESSIONS (1u << 8)
+#define LIBLLDB_LOG_TEMPORARY (1u << 9)
+#define LIBLLDB_LOG_STATE (1u << 10)
+#define LIBLLDB_LOG_OBJECT (1u << 11)
+#define LIBLLDB_LOG_COMMUNICATION (1u << 12)
+#define LIBLLDB_LOG_CONNECTION (1u << 13)
+#define LIBLLDB_LOG_HOST (1u << 14)
+#define LIBLLDB_LOG_UNWIND (1u << 15)
+#define LIBLLDB_LOG_API (1u << 16)
+#define LIBLLDB_LOG_SCRIPT (1u << 17)
+#define LIBLLDB_LOG_COMMANDS (1U << 18)
+#define LIBLLDB_LOG_TYPES (1u << 19)
+#define LIBLLDB_LOG_SYMBOLS (1u << 20)
+#define LIBLLDB_LOG_MODULES (1u << 21)
+#define LIBLLDB_LOG_TARGET (1u << 22)
+#define LIBLLDB_LOG_MMAP (1u << 23)
+#define LIBLLDB_LOG_OS (1u << 24)
+#define LIBLLDB_LOG_ALL (UINT32_MAX)
+#define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\
+ LIBLLDB_LOG_THREAD |\
+ LIBLLDB_LOG_DYNAMIC_LOADER |\
+ LIBLLDB_LOG_BREAKPOINTS |\
+ LIBLLDB_LOG_WATCHPOINTS |\
+ LIBLLDB_LOG_STEP |\
+ LIBLLDB_LOG_STATE |\
+ LIBLLDB_LOG_SYMBOLS |\
+ LIBLLDB_LOG_TARGET |\
+ LIBLLDB_LOG_COMMANDS)
+
+namespace lldb_private {
+
+void
+LogIfAllCategoriesSet (uint32_t mask, const char *format, ...);
+
+void
+LogIfAnyCategoriesSet (uint32_t mask, const char *format, ...);
+
+Log *
+GetLogIfAllCategoriesSet (uint32_t mask);
+
+Log *
+GetLogIfAnyCategoriesSet (uint32_t mask);
+
+uint32_t
+GetLogMask ();
+
+bool
+IsLogVerbose ();
+
+void
+DisableLog (const char **categories, Stream *feedback_strm);
+
+Log *
+EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm);
+
+void
+ListLogCategories (Stream *strm);
+
+} // namespace lldb_private
+
+#endif // liblldb_lldb_private_log_h_
diff --git a/include/lldb/lldb-private-types.h b/include/lldb/lldb-private-types.h
new file mode 100644
index 000000000000..4340af114be3
--- /dev/null
+++ b/include/lldb/lldb-private-types.h
@@ -0,0 +1,74 @@
+//===-- lldb-private-types.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_lldb_private_types_h_
+#define liblldb_lldb_private_types_h_
+
+#if defined(__cplusplus)
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private
+{
+ //----------------------------------------------------------------------
+ // Every register is described in detail including its name, alternate
+ // name (optional), encoding, size in bytes and the default display
+ // format.
+ //----------------------------------------------------------------------
+ typedef struct
+ {
+ const char *name; // Name of this register, can't be NULL
+ const char *alt_name; // Alternate name of this register, can be NULL
+ uint32_t byte_size; // Size in bytes of the register
+ uint32_t byte_offset; // The byte offset in the register context data where this register's value is found
+ lldb::Encoding encoding; // Encoding of the register bits
+ lldb::Format format; // Default display format
+ uint32_t kinds[lldb::kNumRegisterKinds]; // Holds all of the various register numbers for all register kinds
+ uint32_t *value_regs; // List of registers that must be terminated with LLDB_INVALID_REGNUM
+ uint32_t *invalidate_regs; // List of registers that must be invalidated when this register is modified, list must be terminated with LLDB_INVALID_REGNUM
+ } RegisterInfo;
+
+ //----------------------------------------------------------------------
+ // Registers are grouped into register sets
+ //----------------------------------------------------------------------
+ typedef struct
+ {
+ const char *name; // Name of this register set
+ const char *short_name; // A short name for this register set
+ size_t num_registers; // The number of registers in REGISTERS array below
+ const uint32_t *registers; // An array of register numbers in this set
+ } RegisterSet;
+
+ typedef struct
+ {
+ int64_t value;
+ const char *string_value;
+ const char *usage;
+ } OptionEnumValueElement;
+
+ typedef struct
+ {
+ uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
+ // then this option belongs to option set n.
+ bool required; // This option is required (in the current usage level)
+ const char *long_option; // Full name for this option.
+ int short_option; // Single character for this option.
+ int option_has_arg; // no_argument, required_argument or optional_argument
+ OptionEnumValueElement *enum_values; // If non-NULL an array of enum values.
+ uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
+ lldb::CommandArgumentType argument_type; // Type of argument this option takes
+ const char *usage_text; // Full text explaining what this options does and what (if any) argument to
+ // pass it.
+ } OptionDefinition;
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+
+#endif // liblldb_lldb_private_types_h_
diff --git a/include/lldb/lldb-private.h b/include/lldb/lldb-private.h
new file mode 100644
index 000000000000..90590601d945
--- /dev/null
+++ b/include/lldb/lldb-private.h
@@ -0,0 +1,84 @@
+//===-- lldb-private.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_lldb_private_h_
+#define lldb_lldb_private_h_
+
+#if defined(__cplusplus)
+
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-private-interfaces.h"
+#include "lldb/lldb-private-log.h"
+#include "lldb/lldb-private-types.h"
+
+namespace lldb_private {
+
+//------------------------------------------------------------------
+/// Initializes lldb.
+///
+/// This function should be called prior to using any lldb
+/// classes to ensure they have a chance to do any static
+/// initialization that they need to do.
+//------------------------------------------------------------------
+void
+Initialize();
+
+
+//------------------------------------------------------------------
+/// Notifies any classes that lldb will be terminating soon.
+///
+/// This function will be called when the Debugger shared instance
+/// is being destructed and will give classes the ability to clean
+/// up any threads or other resources they have that they might not
+/// be able to clean up in their own destructors.
+///
+/// Internal classes that need this ability will need to add their
+/// void T::WillTerminate() method in the body of this function in
+/// lldb.cpp to ensure it will get called.
+///
+/// TODO: when we start having external plug-ins, we will need a way
+/// for plug-ins to register a WillTerminate callback.
+//------------------------------------------------------------------
+void
+WillTerminate();
+
+//------------------------------------------------------------------
+/// Terminates lldb
+///
+/// This function optionally can be called when clients are done
+/// using lldb functionality to free up any static resources
+/// that have been allocated during initialization or during
+/// function calls. No lldb functions should be called after
+/// calling this function without again calling DCInitialize()
+/// again.
+//------------------------------------------------------------------
+void
+Terminate();
+
+
+const char *
+GetVersion ();
+
+const char *
+GetVoteAsCString (Vote vote);
+
+const char *
+GetSectionTypeAsCString (lldb::SectionType sect_type);
+
+bool
+NameMatches (const char *name, NameMatchType match_type, const char *match);
+
+} // namespace lldb_private
+
+
+#endif // defined(__cplusplus)
+
+
+#endif // lldb_lldb_private_h_
diff --git a/include/lldb/lldb-public.h b/include/lldb/lldb-public.h
new file mode 100644
index 000000000000..b010edf5859a
--- /dev/null
+++ b/include/lldb/lldb-public.h
@@ -0,0 +1,18 @@
+//===-- lldb-include.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_lldb_h_
+#define LLDB_lldb_h_
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#endif // LLDB_lldb_h_
diff --git a/include/lldb/lldb-python.h b/include/lldb/lldb-python.h
new file mode 100644
index 000000000000..229e3967e4a5
--- /dev/null
+++ b/include/lldb/lldb-python.h
@@ -0,0 +1,29 @@
+//===-- lldb-python.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_lldb_python_h_
+#define LLDB_lldb_python_h_
+
+// Python.h needs to be included before any system headers in order to avoid redefinition of macros
+
+#ifdef LLDB_DISABLE_PYTHON
+
+// Python is disabled in this build
+
+#else
+
+#if defined (__APPLE__)
+#include <Python/Python.h>
+#else
+#include <Python.h>
+#endif
+
+#endif // LLDB_DISABLE_PYTHON
+
+#endif // LLDB_lldb_python_h_
diff --git a/include/lldb/lldb-types.h b/include/lldb/lldb-types.h
new file mode 100644
index 000000000000..2693c0c822bb
--- /dev/null
+++ b/include/lldb/lldb-types.h
@@ -0,0 +1,83 @@
+//===-- lldb-types.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_lldb_types_h_
+#define LLDB_lldb_types_h_
+
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+
+#include <assert.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+//----------------------------------------------------------------------
+// All host systems must define:
+// lldb::condition_t The native condition type (or a substitute class) for conditions on the host system.
+// lldb::mutex_t The native mutex type for mutex objects on the host system.
+// lldb::thread_t The native thread type for spawned threads on the system
+// lldb::thread_arg_t The type of the one any only thread creation argument for the host system
+// lldb::thread_result_t The return type that gets returned when a thread finishes.
+// lldb::thread_func_t The function prototype used to spawn a thread on the host system.
+// #define LLDB_INVALID_PROCESS_ID ...
+// #define LLDB_INVALID_THREAD_ID ...
+// #define LLDB_INVALID_HOST_THREAD ...
+// #define IS_VALID_LLDB_HOST_THREAD ...
+//----------------------------------------------------------------------
+
+// TODO: Add a bunch of ifdefs to determine the host system and what
+// things should be defined. Currently MacOSX is being assumed by default
+// since that is what lldb was first developed for.
+
+namespace lldb {
+ //----------------------------------------------------------------------
+ // MacOSX Types
+ //----------------------------------------------------------------------
+ typedef ::pthread_mutex_t mutex_t;
+ typedef pthread_cond_t condition_t;
+ typedef pthread_t thread_t; // Host thread type
+ typedef void * thread_arg_t; // Host thread argument type
+ typedef void * thread_result_t; // Host thread result type
+ typedef void * (*thread_func_t)(void *); // Host thread function type
+ typedef void (*LogOutputCallback) (const char *, void *baton);
+ typedef bool (*CommandOverrideCallback)(void *baton, const char **argv);
+} // namespace lldb
+
+#if defined(__MINGW32__)
+
+const lldb::thread_t lldb_invalid_host_thread_const = { NULL, 0 } ;
+#define LLDB_INVALID_HOST_THREAD (lldb_invalid_host_thread_const)
+#define IS_VALID_LLDB_HOST_THREAD(t) (!(NULL == (t).p && 0 == (t).x))
+
+#else
+
+#define LLDB_INVALID_HOST_THREAD ((lldb::thread_t)NULL)
+#define IS_VALID_LLDB_HOST_THREAD(t) ((t) != LLDB_INVALID_HOST_THREAD)
+
+#endif
+
+#define LLDB_INVALID_HOST_TIME { 0, 0 }
+
+namespace lldb
+{
+ typedef uint64_t addr_t;
+ typedef uint64_t user_id_t;
+ typedef uint64_t pid_t;
+ typedef uint64_t tid_t;
+ typedef uint64_t offset_t;
+ typedef int32_t break_id_t;
+ typedef int32_t watch_id_t;
+ typedef void * clang_type_t;
+}
+
+
+#endif // LLDB_lldb_types_h_
diff --git a/include/lldb/lldb-versioning.h b/include/lldb/lldb-versioning.h
new file mode 100644
index 000000000000..8ccc67d8e9c0
--- /dev/null
+++ b/include/lldb/lldb-versioning.h
@@ -0,0 +1,1607 @@
+//===-- lldb-versioning.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_lldb_versioning_h_
+#define LLDB_lldb_versioning_h_
+
+//----------------------------------------------------------------------
+// LLDB API version
+//----------------------------------------------------------------------
+#define LLDB_API_MAJOR_VERSION 1
+#define LLDB_API_MINOR_VERSION 0
+
+/*
+ API versioning
+ ---------------------------------
+
+ The LLDB API is versioned independently of the LLDB source base
+ Our API version numbers are composed of a major and a minor number
+
+ The major number means a complete and stable revision of the API. Major numbers are compatibility breakers
+ (i.e. when we change the API major number, there is no promise of compatibility with the previous major version
+ and we are free to remove and/or change any APIs)
+ Minor numbers are a work-in-progress evolution of the API. APIs will not be removed or changed across minor versions
+ (minors do not break compatibility). However, we can deprecate APIs in minor versions or add new APIs in minor versions
+ A deprecated API is supposedly going to be removed in the next major version and will generate a warning if used
+ APIs we add in minor versions will not be removed (at least until the following major) but they might theoretically be deprecated
+ in a following minor version
+ Users are discouraged from using the LLDB version number to test for API features and should instead use the API version checking
+ as discussed below
+
+ API version checking
+ ---------------------------------
+
+ You can (optionally) sign into an API version checking feature
+ To do so you need to define three macros:
+ LLDB_API_CHECK_VERSIONING - define to any value (or no value)
+ LLDB_API_MAJOR_VERSION_WANTED - which major version of the LLDB API you are targeting
+ LLDB_API_MINOR_VERSION_WANTED - which minor version of the LLDB API you are targeting
+
+ If these macros exist - LLDB will enable version checking of the public API
+
+ If LLDB_API_MAJOR_VERSION is not equal to LLDB_API_MAJOR_VERSION_WANTED we will immediately halt your compilation with an error
+ This is by design, since we do not make any promise of compatibility across major versions - if you really want to test your luck, disable the versioning altogether
+
+ If the major version test passes, you have signed up for a specific minor version of the API
+ Whenever we add or deprecate an API in a minor version, we will mark it with either
+ LLDB_API_NEW_IN_DOT_x - this API is new in LLDB .x
+ LLDB_API_DEPRECATED_IN_DOT_x - this API is deprecated as of .x
+
+ If you are using an API new in DOT_x
+ if LLDB_API_MINOR_VERSION_WANTED >= x then all is well, else you will get a compilation error
+ This is meant to prevent you from using APIs that are newer than whatever LLDB you want to target
+
+ If you are using an API deprecated in DOT_x
+ if LLDB_API_MINOR_VERSION_WANTED >= x then you will get a compilation warning, else all is well
+ This is meant to let you know that you are using an API that is deprecated and might go away
+
+ Caveats
+ ---------------------------------
+
+ Version checking only works on clang on OSX - you will get an error if you try to enable it on any other OS/compiler
+ If you want to enable version checking on other platforms, you will need to define appropriate implementations for
+ LLDB_API_IMPL_DEPRECATED and LLDB_API_IMPL_TOONEW and any other infrastructure your compiler needs for this purpose
+
+ We have no deprecation-as-error mode
+
+ There is no support for API versioning in Python
+
+ We reserve to use macros whose names begin with LLDB_API_ and you should not use them in your source code as they might conflict
+ with present or future macro names we are using to implement versioning
+*/
+
+// if you want the version checking to work on other OS/compiler, define appropriate IMPL_DEPRECATED/IMPL_TOONEW
+// and define LLDB_API_CHECK_VERSIONING_WORKS when you are ready to go live
+#if defined(__APPLE__) && defined(__clang__)
+#define LLDB_API_IMPL_DEPRECATED __attribute__((deprecated))
+#define LLDB_API_IMPL_TOONEW __attribute__((unavailable))
+#define LLDB_API_CHECK_VERSIONING_WORKS
+#endif
+
+#if defined(LLDB_API_CHECK_VERSIONING) && !defined(LLDB_API_CHECK_VERSIONING_WORKS)
+#error "API version checking will not work here - please disable or create and submit patches to lldb-versioning.h"
+#endif
+
+#if defined(LLDB_API_CHECK_VERSIONING_WORKS) && (!defined(LLDB_API_IMPL_DEPRECATED) || !defined(LLDB_API_IMPL_TOONEW))
+#error "LLDB_API_CHECK_VERSIONING_WORKS needs LLDB_API_IMPL_DEPRECATED and LLDB_API_IMPL_TOONEW to be defined"
+#endif
+
+#if defined(LLDB_API_CHECK_VERSIONING) && defined(LLDB_API_MAJOR_VERSION_WANTED) && defined(LLDB_API_MINOR_VERSION_WANTED)
+
+#if defined (LLDB_API_MAJOR_VERSION) && (LLDB_API_MAJOR_VERSION != LLDB_API_MAJOR_VERSION_WANTED)
+#error "Cannot link using this LLDB version - public API versions are incompatible"
+#endif
+
+#define LLDB_API_MINOR_VERSION_DOT_0 0
+#define LLDB_API_MINOR_VERSION_DOT_1 1
+#define LLDB_API_MINOR_VERSION_DOT_2 2
+#define LLDB_API_MINOR_VERSION_DOT_3 3
+#define LLDB_API_MINOR_VERSION_DOT_4 4
+#define LLDB_API_MINOR_VERSION_DOT_5 5
+#define LLDB_API_MINOR_VERSION_DOT_6 6
+#define LLDB_API_MINOR_VERSION_DOT_7 7
+#define LLDB_API_MINOR_VERSION_DOT_8 8
+#define LLDB_API_MINOR_VERSION_DOT_9 9
+#define LLDB_API_MINOR_VERSION_DOT_10 10
+#define LLDB_API_MINOR_VERSION_DOT_11 11
+#define LLDB_API_MINOR_VERSION_DOT_12 12
+#define LLDB_API_MINOR_VERSION_DOT_13 13
+#define LLDB_API_MINOR_VERSION_DOT_14 14
+#define LLDB_API_MINOR_VERSION_DOT_15 15
+#define LLDB_API_MINOR_VERSION_DOT_16 16
+#define LLDB_API_MINOR_VERSION_DOT_17 17
+#define LLDB_API_MINOR_VERSION_DOT_18 18
+#define LLDB_API_MINOR_VERSION_DOT_19 19
+#define LLDB_API_MINOR_VERSION_DOT_20 20
+#define LLDB_API_MINOR_VERSION_DOT_21 21
+#define LLDB_API_MINOR_VERSION_DOT_22 22
+#define LLDB_API_MINOR_VERSION_DOT_23 23
+#define LLDB_API_MINOR_VERSION_DOT_24 24
+#define LLDB_API_MINOR_VERSION_DOT_25 25
+#define LLDB_API_MINOR_VERSION_DOT_26 26
+#define LLDB_API_MINOR_VERSION_DOT_27 27
+#define LLDB_API_MINOR_VERSION_DOT_28 28
+#define LLDB_API_MINOR_VERSION_DOT_29 29
+#define LLDB_API_MINOR_VERSION_DOT_30 30
+#define LLDB_API_MINOR_VERSION_DOT_31 31
+#define LLDB_API_MINOR_VERSION_DOT_32 32
+#define LLDB_API_MINOR_VERSION_DOT_33 33
+#define LLDB_API_MINOR_VERSION_DOT_34 34
+#define LLDB_API_MINOR_VERSION_DOT_35 35
+#define LLDB_API_MINOR_VERSION_DOT_36 36
+#define LLDB_API_MINOR_VERSION_DOT_37 37
+#define LLDB_API_MINOR_VERSION_DOT_38 38
+#define LLDB_API_MINOR_VERSION_DOT_39 39
+#define LLDB_API_MINOR_VERSION_DOT_40 40
+#define LLDB_API_MINOR_VERSION_DOT_41 41
+#define LLDB_API_MINOR_VERSION_DOT_42 42
+#define LLDB_API_MINOR_VERSION_DOT_43 43
+#define LLDB_API_MINOR_VERSION_DOT_44 44
+#define LLDB_API_MINOR_VERSION_DOT_45 45
+#define LLDB_API_MINOR_VERSION_DOT_46 46
+#define LLDB_API_MINOR_VERSION_DOT_47 47
+#define LLDB_API_MINOR_VERSION_DOT_48 48
+#define LLDB_API_MINOR_VERSION_DOT_49 49
+#define LLDB_API_MINOR_VERSION_DOT_50 50
+#define LLDB_API_MINOR_VERSION_DOT_51 51
+#define LLDB_API_MINOR_VERSION_DOT_52 52
+#define LLDB_API_MINOR_VERSION_DOT_53 53
+#define LLDB_API_MINOR_VERSION_DOT_54 54
+#define LLDB_API_MINOR_VERSION_DOT_55 55
+#define LLDB_API_MINOR_VERSION_DOT_56 56
+#define LLDB_API_MINOR_VERSION_DOT_57 57
+#define LLDB_API_MINOR_VERSION_DOT_58 58
+#define LLDB_API_MINOR_VERSION_DOT_59 59
+#define LLDB_API_MINOR_VERSION_DOT_60 60
+#define LLDB_API_MINOR_VERSION_DOT_61 61
+#define LLDB_API_MINOR_VERSION_DOT_62 62
+#define LLDB_API_MINOR_VERSION_DOT_63 63
+#define LLDB_API_MINOR_VERSION_DOT_64 64
+#define LLDB_API_MINOR_VERSION_DOT_65 65
+#define LLDB_API_MINOR_VERSION_DOT_66 66
+#define LLDB_API_MINOR_VERSION_DOT_67 67
+#define LLDB_API_MINOR_VERSION_DOT_68 68
+#define LLDB_API_MINOR_VERSION_DOT_69 69
+#define LLDB_API_MINOR_VERSION_DOT_70 70
+#define LLDB_API_MINOR_VERSION_DOT_71 71
+#define LLDB_API_MINOR_VERSION_DOT_72 72
+#define LLDB_API_MINOR_VERSION_DOT_73 73
+#define LLDB_API_MINOR_VERSION_DOT_74 74
+#define LLDB_API_MINOR_VERSION_DOT_75 75
+#define LLDB_API_MINOR_VERSION_DOT_76 76
+#define LLDB_API_MINOR_VERSION_DOT_77 77
+#define LLDB_API_MINOR_VERSION_DOT_78 78
+#define LLDB_API_MINOR_VERSION_DOT_79 79
+#define LLDB_API_MINOR_VERSION_DOT_80 80
+#define LLDB_API_MINOR_VERSION_DOT_81 81
+#define LLDB_API_MINOR_VERSION_DOT_82 82
+#define LLDB_API_MINOR_VERSION_DOT_83 83
+#define LLDB_API_MINOR_VERSION_DOT_84 84
+#define LLDB_API_MINOR_VERSION_DOT_85 85
+#define LLDB_API_MINOR_VERSION_DOT_86 86
+#define LLDB_API_MINOR_VERSION_DOT_87 87
+#define LLDB_API_MINOR_VERSION_DOT_88 88
+#define LLDB_API_MINOR_VERSION_DOT_89 89
+#define LLDB_API_MINOR_VERSION_DOT_90 90
+#define LLDB_API_MINOR_VERSION_DOT_91 91
+#define LLDB_API_MINOR_VERSION_DOT_92 92
+#define LLDB_API_MINOR_VERSION_DOT_93 93
+#define LLDB_API_MINOR_VERSION_DOT_94 94
+#define LLDB_API_MINOR_VERSION_DOT_95 95
+#define LLDB_API_MINOR_VERSION_DOT_96 96
+#define LLDB_API_MINOR_VERSION_DOT_97 97
+#define LLDB_API_MINOR_VERSION_DOT_98 98
+#define LLDB_API_MINOR_VERSION_DOT_99 99
+
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_0
+#define LLDB_API_NEW_IN_DOT_0 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_0
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_0
+#define LLDB_API_DEPRECATED_IN_DOT_0 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_0
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_1
+#define LLDB_API_NEW_IN_DOT_1 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_1
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_1
+#define LLDB_API_DEPRECATED_IN_DOT_1 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_1
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_2
+#define LLDB_API_NEW_IN_DOT_2 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_2
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_2
+#define LLDB_API_DEPRECATED_IN_DOT_2 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_2
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_3
+#define LLDB_API_NEW_IN_DOT_3 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_3
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_3
+#define LLDB_API_DEPRECATED_IN_DOT_3 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_3
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_4
+#define LLDB_API_NEW_IN_DOT_4 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_4
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_4
+#define LLDB_API_DEPRECATED_IN_DOT_4 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_4
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_5
+#define LLDB_API_NEW_IN_DOT_5 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_5
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_5
+#define LLDB_API_DEPRECATED_IN_DOT_5 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_5
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_6
+#define LLDB_API_NEW_IN_DOT_6 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_6
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_6
+#define LLDB_API_DEPRECATED_IN_DOT_6 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_6
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_7
+#define LLDB_API_NEW_IN_DOT_7 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_7
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_7
+#define LLDB_API_DEPRECATED_IN_DOT_7 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_7
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_8
+#define LLDB_API_NEW_IN_DOT_8 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_8
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_8
+#define LLDB_API_DEPRECATED_IN_DOT_8 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_8
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_9
+#define LLDB_API_NEW_IN_DOT_9 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_9
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_9
+#define LLDB_API_DEPRECATED_IN_DOT_9 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_9
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_10
+#define LLDB_API_NEW_IN_DOT_10 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_10
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_10
+#define LLDB_API_DEPRECATED_IN_DOT_10 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_10
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_11
+#define LLDB_API_NEW_IN_DOT_11 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_11
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_11
+#define LLDB_API_DEPRECATED_IN_DOT_11 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_11
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_12
+#define LLDB_API_NEW_IN_DOT_12 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_12
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_12
+#define LLDB_API_DEPRECATED_IN_DOT_12 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_12
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_13
+#define LLDB_API_NEW_IN_DOT_13 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_13
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_13
+#define LLDB_API_DEPRECATED_IN_DOT_13 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_13
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_14
+#define LLDB_API_NEW_IN_DOT_14 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_14
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_14
+#define LLDB_API_DEPRECATED_IN_DOT_14 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_14
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_15
+#define LLDB_API_NEW_IN_DOT_15 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_15
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_15
+#define LLDB_API_DEPRECATED_IN_DOT_15 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_15
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_16
+#define LLDB_API_NEW_IN_DOT_16 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_16
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_16
+#define LLDB_API_DEPRECATED_IN_DOT_16 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_16
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_17
+#define LLDB_API_NEW_IN_DOT_17 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_17
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_17
+#define LLDB_API_DEPRECATED_IN_DOT_17 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_17
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_18
+#define LLDB_API_NEW_IN_DOT_18 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_18
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_18
+#define LLDB_API_DEPRECATED_IN_DOT_18 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_18
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_19
+#define LLDB_API_NEW_IN_DOT_19 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_19
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_19
+#define LLDB_API_DEPRECATED_IN_DOT_19 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_19
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_20
+#define LLDB_API_NEW_IN_DOT_20 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_20
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_20
+#define LLDB_API_DEPRECATED_IN_DOT_20 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_20
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_21
+#define LLDB_API_NEW_IN_DOT_21 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_21
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_21
+#define LLDB_API_DEPRECATED_IN_DOT_21 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_21
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_22
+#define LLDB_API_NEW_IN_DOT_22 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_22
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_22
+#define LLDB_API_DEPRECATED_IN_DOT_22 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_22
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_23
+#define LLDB_API_NEW_IN_DOT_23 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_23
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_23
+#define LLDB_API_DEPRECATED_IN_DOT_23 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_23
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_24
+#define LLDB_API_NEW_IN_DOT_24 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_24
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_24
+#define LLDB_API_DEPRECATED_IN_DOT_24 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_24
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_25
+#define LLDB_API_NEW_IN_DOT_25 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_25
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_25
+#define LLDB_API_DEPRECATED_IN_DOT_25 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_25
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_26
+#define LLDB_API_NEW_IN_DOT_26 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_26
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_26
+#define LLDB_API_DEPRECATED_IN_DOT_26 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_26
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_27
+#define LLDB_API_NEW_IN_DOT_27 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_27
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_27
+#define LLDB_API_DEPRECATED_IN_DOT_27 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_27
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_28
+#define LLDB_API_NEW_IN_DOT_28 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_28
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_28
+#define LLDB_API_DEPRECATED_IN_DOT_28 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_28
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_29
+#define LLDB_API_NEW_IN_DOT_29 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_29
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_29
+#define LLDB_API_DEPRECATED_IN_DOT_29 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_29
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_30
+#define LLDB_API_NEW_IN_DOT_30 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_30
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_30
+#define LLDB_API_DEPRECATED_IN_DOT_30 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_30
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_31
+#define LLDB_API_NEW_IN_DOT_31 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_31
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_31
+#define LLDB_API_DEPRECATED_IN_DOT_31 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_31
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_32
+#define LLDB_API_NEW_IN_DOT_32 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_32
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_32
+#define LLDB_API_DEPRECATED_IN_DOT_32 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_32
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_33
+#define LLDB_API_NEW_IN_DOT_33 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_33
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_33
+#define LLDB_API_DEPRECATED_IN_DOT_33 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_33
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_34
+#define LLDB_API_NEW_IN_DOT_34 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_34
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_34
+#define LLDB_API_DEPRECATED_IN_DOT_34 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_34
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_35
+#define LLDB_API_NEW_IN_DOT_35 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_35
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_35
+#define LLDB_API_DEPRECATED_IN_DOT_35 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_35
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_36
+#define LLDB_API_NEW_IN_DOT_36 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_36
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_36
+#define LLDB_API_DEPRECATED_IN_DOT_36 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_36
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_37
+#define LLDB_API_NEW_IN_DOT_37 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_37
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_37
+#define LLDB_API_DEPRECATED_IN_DOT_37 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_37
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_38
+#define LLDB_API_NEW_IN_DOT_38 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_38
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_38
+#define LLDB_API_DEPRECATED_IN_DOT_38 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_38
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_39
+#define LLDB_API_NEW_IN_DOT_39 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_39
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_39
+#define LLDB_API_DEPRECATED_IN_DOT_39 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_39
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_40
+#define LLDB_API_NEW_IN_DOT_40 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_40
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_40
+#define LLDB_API_DEPRECATED_IN_DOT_40 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_40
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_41
+#define LLDB_API_NEW_IN_DOT_41 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_41
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_41
+#define LLDB_API_DEPRECATED_IN_DOT_41 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_41
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_42
+#define LLDB_API_NEW_IN_DOT_42 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_42
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_42
+#define LLDB_API_DEPRECATED_IN_DOT_42 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_42
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_43
+#define LLDB_API_NEW_IN_DOT_43 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_43
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_43
+#define LLDB_API_DEPRECATED_IN_DOT_43 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_43
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_44
+#define LLDB_API_NEW_IN_DOT_44 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_44
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_44
+#define LLDB_API_DEPRECATED_IN_DOT_44 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_44
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_45
+#define LLDB_API_NEW_IN_DOT_45 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_45
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_45
+#define LLDB_API_DEPRECATED_IN_DOT_45 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_45
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_46
+#define LLDB_API_NEW_IN_DOT_46 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_46
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_46
+#define LLDB_API_DEPRECATED_IN_DOT_46 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_46
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_47
+#define LLDB_API_NEW_IN_DOT_47 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_47
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_47
+#define LLDB_API_DEPRECATED_IN_DOT_47 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_47
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_48
+#define LLDB_API_NEW_IN_DOT_48 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_48
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_48
+#define LLDB_API_DEPRECATED_IN_DOT_48 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_48
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_49
+#define LLDB_API_NEW_IN_DOT_49 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_49
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_49
+#define LLDB_API_DEPRECATED_IN_DOT_49 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_49
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_50
+#define LLDB_API_NEW_IN_DOT_50 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_50
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_50
+#define LLDB_API_DEPRECATED_IN_DOT_50 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_50
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_51
+#define LLDB_API_NEW_IN_DOT_51 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_51
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_51
+#define LLDB_API_DEPRECATED_IN_DOT_51 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_51
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_52
+#define LLDB_API_NEW_IN_DOT_52 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_52
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_52
+#define LLDB_API_DEPRECATED_IN_DOT_52 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_52
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_53
+#define LLDB_API_NEW_IN_DOT_53 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_53
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_53
+#define LLDB_API_DEPRECATED_IN_DOT_53 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_53
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_54
+#define LLDB_API_NEW_IN_DOT_54 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_54
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_54
+#define LLDB_API_DEPRECATED_IN_DOT_54 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_54
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_55
+#define LLDB_API_NEW_IN_DOT_55 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_55
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_55
+#define LLDB_API_DEPRECATED_IN_DOT_55 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_55
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_56
+#define LLDB_API_NEW_IN_DOT_56 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_56
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_56
+#define LLDB_API_DEPRECATED_IN_DOT_56 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_56
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_57
+#define LLDB_API_NEW_IN_DOT_57 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_57
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_57
+#define LLDB_API_DEPRECATED_IN_DOT_57 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_57
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_58
+#define LLDB_API_NEW_IN_DOT_58 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_58
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_58
+#define LLDB_API_DEPRECATED_IN_DOT_58 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_58
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_59
+#define LLDB_API_NEW_IN_DOT_59 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_59
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_59
+#define LLDB_API_DEPRECATED_IN_DOT_59 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_59
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_60
+#define LLDB_API_NEW_IN_DOT_60 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_60
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_60
+#define LLDB_API_DEPRECATED_IN_DOT_60 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_60
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_61
+#define LLDB_API_NEW_IN_DOT_61 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_61
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_61
+#define LLDB_API_DEPRECATED_IN_DOT_61 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_61
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_62
+#define LLDB_API_NEW_IN_DOT_62 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_62
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_62
+#define LLDB_API_DEPRECATED_IN_DOT_62 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_62
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_63
+#define LLDB_API_NEW_IN_DOT_63 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_63
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_63
+#define LLDB_API_DEPRECATED_IN_DOT_63 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_63
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_64
+#define LLDB_API_NEW_IN_DOT_64 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_64
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_64
+#define LLDB_API_DEPRECATED_IN_DOT_64 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_64
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_65
+#define LLDB_API_NEW_IN_DOT_65 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_65
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_65
+#define LLDB_API_DEPRECATED_IN_DOT_65 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_65
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_66
+#define LLDB_API_NEW_IN_DOT_66 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_66
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_66
+#define LLDB_API_DEPRECATED_IN_DOT_66 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_66
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_67
+#define LLDB_API_NEW_IN_DOT_67 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_67
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_67
+#define LLDB_API_DEPRECATED_IN_DOT_67 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_67
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_68
+#define LLDB_API_NEW_IN_DOT_68 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_68
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_68
+#define LLDB_API_DEPRECATED_IN_DOT_68 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_68
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_69
+#define LLDB_API_NEW_IN_DOT_69 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_69
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_69
+#define LLDB_API_DEPRECATED_IN_DOT_69 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_69
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_70
+#define LLDB_API_NEW_IN_DOT_70 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_70
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_70
+#define LLDB_API_DEPRECATED_IN_DOT_70 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_70
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_71
+#define LLDB_API_NEW_IN_DOT_71 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_71
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_71
+#define LLDB_API_DEPRECATED_IN_DOT_71 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_71
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_72
+#define LLDB_API_NEW_IN_DOT_72 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_72
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_72
+#define LLDB_API_DEPRECATED_IN_DOT_72 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_72
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_73
+#define LLDB_API_NEW_IN_DOT_73 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_73
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_73
+#define LLDB_API_DEPRECATED_IN_DOT_73 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_73
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_74
+#define LLDB_API_NEW_IN_DOT_74 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_74
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_74
+#define LLDB_API_DEPRECATED_IN_DOT_74 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_74
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_75
+#define LLDB_API_NEW_IN_DOT_75 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_75
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_75
+#define LLDB_API_DEPRECATED_IN_DOT_75 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_75
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_76
+#define LLDB_API_NEW_IN_DOT_76 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_76
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_76
+#define LLDB_API_DEPRECATED_IN_DOT_76 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_76
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_77
+#define LLDB_API_NEW_IN_DOT_77 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_77
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_77
+#define LLDB_API_DEPRECATED_IN_DOT_77 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_77
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_78
+#define LLDB_API_NEW_IN_DOT_78 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_78
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_78
+#define LLDB_API_DEPRECATED_IN_DOT_78 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_78
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_79
+#define LLDB_API_NEW_IN_DOT_79 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_79
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_79
+#define LLDB_API_DEPRECATED_IN_DOT_79 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_79
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_80
+#define LLDB_API_NEW_IN_DOT_80 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_80
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_80
+#define LLDB_API_DEPRECATED_IN_DOT_80 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_80
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_81
+#define LLDB_API_NEW_IN_DOT_81 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_81
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_81
+#define LLDB_API_DEPRECATED_IN_DOT_81 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_81
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_82
+#define LLDB_API_NEW_IN_DOT_82 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_82
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_82
+#define LLDB_API_DEPRECATED_IN_DOT_82 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_82
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_83
+#define LLDB_API_NEW_IN_DOT_83 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_83
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_83
+#define LLDB_API_DEPRECATED_IN_DOT_83 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_83
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_84
+#define LLDB_API_NEW_IN_DOT_84 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_84
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_84
+#define LLDB_API_DEPRECATED_IN_DOT_84 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_84
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_85
+#define LLDB_API_NEW_IN_DOT_85 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_85
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_85
+#define LLDB_API_DEPRECATED_IN_DOT_85 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_85
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_86
+#define LLDB_API_NEW_IN_DOT_86 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_86
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_86
+#define LLDB_API_DEPRECATED_IN_DOT_86 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_86
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_87
+#define LLDB_API_NEW_IN_DOT_87 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_87
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_87
+#define LLDB_API_DEPRECATED_IN_DOT_87 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_87
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_88
+#define LLDB_API_NEW_IN_DOT_88 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_88
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_88
+#define LLDB_API_DEPRECATED_IN_DOT_88 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_88
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_89
+#define LLDB_API_NEW_IN_DOT_89 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_89
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_89
+#define LLDB_API_DEPRECATED_IN_DOT_89 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_89
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_90
+#define LLDB_API_NEW_IN_DOT_90 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_90
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_90
+#define LLDB_API_DEPRECATED_IN_DOT_90 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_90
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_91
+#define LLDB_API_NEW_IN_DOT_91 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_91
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_91
+#define LLDB_API_DEPRECATED_IN_DOT_91 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_91
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_92
+#define LLDB_API_NEW_IN_DOT_92 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_92
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_92
+#define LLDB_API_DEPRECATED_IN_DOT_92 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_92
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_93
+#define LLDB_API_NEW_IN_DOT_93 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_93
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_93
+#define LLDB_API_DEPRECATED_IN_DOT_93 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_93
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_94
+#define LLDB_API_NEW_IN_DOT_94 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_94
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_94
+#define LLDB_API_DEPRECATED_IN_DOT_94 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_94
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_95
+#define LLDB_API_NEW_IN_DOT_95 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_95
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_95
+#define LLDB_API_DEPRECATED_IN_DOT_95 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_95
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_96
+#define LLDB_API_NEW_IN_DOT_96 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_96
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_96
+#define LLDB_API_DEPRECATED_IN_DOT_96 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_96
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_97
+#define LLDB_API_NEW_IN_DOT_97 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_97
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_97
+#define LLDB_API_DEPRECATED_IN_DOT_97 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_97
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_98
+#define LLDB_API_NEW_IN_DOT_98 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_98
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_98
+#define LLDB_API_DEPRECATED_IN_DOT_98 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_98
+#endif
+#if LLDB_API_MINOR_VERSION_WANTED < LLDB_API_MINOR_VERSION_DOT_99
+#define LLDB_API_NEW_IN_DOT_99 LLDB_API_IMPL_TOONEW
+#else
+#define LLDB_API_NEW_IN_DOT_99
+#endif
+
+
+#if LLDB_API_MINOR_VERSION_WANTED >= LLDB_API_MINOR_VERSION_DOT_99
+#define LLDB_API_DEPRECATED_IN_DOT_99 LLDB_API_IMPL_DEPRECATED
+#else
+#define LLDB_API_DEPRECATED_IN_DOT_99
+#endif
+
+#else // defined(LLDB_CHECK_API_VERSIONING) && defined(LLDB_API_MAJOR_VERSION_WANTED) && defined(LLDB_API_MINOR_VERSION_WANTED) && defined (LLDB_API_MAJOR_VERSION)
+
+#define LLDB_API_NEW_IN_DOT_0
+#define LLDB_API_DEPRECATED_IN_DOT_0
+#define LLDB_API_NEW_IN_DOT_1
+#define LLDB_API_DEPRECATED_IN_DOT_1
+#define LLDB_API_NEW_IN_DOT_2
+#define LLDB_API_DEPRECATED_IN_DOT_2
+#define LLDB_API_NEW_IN_DOT_3
+#define LLDB_API_DEPRECATED_IN_DOT_3
+#define LLDB_API_NEW_IN_DOT_4
+#define LLDB_API_DEPRECATED_IN_DOT_4
+#define LLDB_API_NEW_IN_DOT_5
+#define LLDB_API_DEPRECATED_IN_DOT_5
+#define LLDB_API_NEW_IN_DOT_6
+#define LLDB_API_DEPRECATED_IN_DOT_6
+#define LLDB_API_NEW_IN_DOT_7
+#define LLDB_API_DEPRECATED_IN_DOT_7
+#define LLDB_API_NEW_IN_DOT_8
+#define LLDB_API_DEPRECATED_IN_DOT_8
+#define LLDB_API_NEW_IN_DOT_9
+#define LLDB_API_DEPRECATED_IN_DOT_9
+#define LLDB_API_NEW_IN_DOT_10
+#define LLDB_API_DEPRECATED_IN_DOT_10
+#define LLDB_API_NEW_IN_DOT_11
+#define LLDB_API_DEPRECATED_IN_DOT_11
+#define LLDB_API_NEW_IN_DOT_12
+#define LLDB_API_DEPRECATED_IN_DOT_12
+#define LLDB_API_NEW_IN_DOT_13
+#define LLDB_API_DEPRECATED_IN_DOT_13
+#define LLDB_API_NEW_IN_DOT_14
+#define LLDB_API_DEPRECATED_IN_DOT_14
+#define LLDB_API_NEW_IN_DOT_15
+#define LLDB_API_DEPRECATED_IN_DOT_15
+#define LLDB_API_NEW_IN_DOT_16
+#define LLDB_API_DEPRECATED_IN_DOT_16
+#define LLDB_API_NEW_IN_DOT_17
+#define LLDB_API_DEPRECATED_IN_DOT_17
+#define LLDB_API_NEW_IN_DOT_18
+#define LLDB_API_DEPRECATED_IN_DOT_18
+#define LLDB_API_NEW_IN_DOT_19
+#define LLDB_API_DEPRECATED_IN_DOT_19
+#define LLDB_API_NEW_IN_DOT_20
+#define LLDB_API_DEPRECATED_IN_DOT_20
+#define LLDB_API_NEW_IN_DOT_21
+#define LLDB_API_DEPRECATED_IN_DOT_21
+#define LLDB_API_NEW_IN_DOT_22
+#define LLDB_API_DEPRECATED_IN_DOT_22
+#define LLDB_API_NEW_IN_DOT_23
+#define LLDB_API_DEPRECATED_IN_DOT_23
+#define LLDB_API_NEW_IN_DOT_24
+#define LLDB_API_DEPRECATED_IN_DOT_24
+#define LLDB_API_NEW_IN_DOT_25
+#define LLDB_API_DEPRECATED_IN_DOT_25
+#define LLDB_API_NEW_IN_DOT_26
+#define LLDB_API_DEPRECATED_IN_DOT_26
+#define LLDB_API_NEW_IN_DOT_27
+#define LLDB_API_DEPRECATED_IN_DOT_27
+#define LLDB_API_NEW_IN_DOT_28
+#define LLDB_API_DEPRECATED_IN_DOT_28
+#define LLDB_API_NEW_IN_DOT_29
+#define LLDB_API_DEPRECATED_IN_DOT_29
+#define LLDB_API_NEW_IN_DOT_30
+#define LLDB_API_DEPRECATED_IN_DOT_30
+#define LLDB_API_NEW_IN_DOT_31
+#define LLDB_API_DEPRECATED_IN_DOT_31
+#define LLDB_API_NEW_IN_DOT_32
+#define LLDB_API_DEPRECATED_IN_DOT_32
+#define LLDB_API_NEW_IN_DOT_33
+#define LLDB_API_DEPRECATED_IN_DOT_33
+#define LLDB_API_NEW_IN_DOT_34
+#define LLDB_API_DEPRECATED_IN_DOT_34
+#define LLDB_API_NEW_IN_DOT_35
+#define LLDB_API_DEPRECATED_IN_DOT_35
+#define LLDB_API_NEW_IN_DOT_36
+#define LLDB_API_DEPRECATED_IN_DOT_36
+#define LLDB_API_NEW_IN_DOT_37
+#define LLDB_API_DEPRECATED_IN_DOT_37
+#define LLDB_API_NEW_IN_DOT_38
+#define LLDB_API_DEPRECATED_IN_DOT_38
+#define LLDB_API_NEW_IN_DOT_39
+#define LLDB_API_DEPRECATED_IN_DOT_39
+#define LLDB_API_NEW_IN_DOT_40
+#define LLDB_API_DEPRECATED_IN_DOT_40
+#define LLDB_API_NEW_IN_DOT_41
+#define LLDB_API_DEPRECATED_IN_DOT_41
+#define LLDB_API_NEW_IN_DOT_42
+#define LLDB_API_DEPRECATED_IN_DOT_42
+#define LLDB_API_NEW_IN_DOT_43
+#define LLDB_API_DEPRECATED_IN_DOT_43
+#define LLDB_API_NEW_IN_DOT_44
+#define LLDB_API_DEPRECATED_IN_DOT_44
+#define LLDB_API_NEW_IN_DOT_45
+#define LLDB_API_DEPRECATED_IN_DOT_45
+#define LLDB_API_NEW_IN_DOT_46
+#define LLDB_API_DEPRECATED_IN_DOT_46
+#define LLDB_API_NEW_IN_DOT_47
+#define LLDB_API_DEPRECATED_IN_DOT_47
+#define LLDB_API_NEW_IN_DOT_48
+#define LLDB_API_DEPRECATED_IN_DOT_48
+#define LLDB_API_NEW_IN_DOT_49
+#define LLDB_API_DEPRECATED_IN_DOT_49
+#define LLDB_API_NEW_IN_DOT_50
+#define LLDB_API_DEPRECATED_IN_DOT_50
+#define LLDB_API_NEW_IN_DOT_51
+#define LLDB_API_DEPRECATED_IN_DOT_51
+#define LLDB_API_NEW_IN_DOT_52
+#define LLDB_API_DEPRECATED_IN_DOT_52
+#define LLDB_API_NEW_IN_DOT_53
+#define LLDB_API_DEPRECATED_IN_DOT_53
+#define LLDB_API_NEW_IN_DOT_54
+#define LLDB_API_DEPRECATED_IN_DOT_54
+#define LLDB_API_NEW_IN_DOT_55
+#define LLDB_API_DEPRECATED_IN_DOT_55
+#define LLDB_API_NEW_IN_DOT_56
+#define LLDB_API_DEPRECATED_IN_DOT_56
+#define LLDB_API_NEW_IN_DOT_57
+#define LLDB_API_DEPRECATED_IN_DOT_57
+#define LLDB_API_NEW_IN_DOT_58
+#define LLDB_API_DEPRECATED_IN_DOT_58
+#define LLDB_API_NEW_IN_DOT_59
+#define LLDB_API_DEPRECATED_IN_DOT_59
+#define LLDB_API_NEW_IN_DOT_60
+#define LLDB_API_DEPRECATED_IN_DOT_60
+#define LLDB_API_NEW_IN_DOT_61
+#define LLDB_API_DEPRECATED_IN_DOT_61
+#define LLDB_API_NEW_IN_DOT_62
+#define LLDB_API_DEPRECATED_IN_DOT_62
+#define LLDB_API_NEW_IN_DOT_63
+#define LLDB_API_DEPRECATED_IN_DOT_63
+#define LLDB_API_NEW_IN_DOT_64
+#define LLDB_API_DEPRECATED_IN_DOT_64
+#define LLDB_API_NEW_IN_DOT_65
+#define LLDB_API_DEPRECATED_IN_DOT_65
+#define LLDB_API_NEW_IN_DOT_66
+#define LLDB_API_DEPRECATED_IN_DOT_66
+#define LLDB_API_NEW_IN_DOT_67
+#define LLDB_API_DEPRECATED_IN_DOT_67
+#define LLDB_API_NEW_IN_DOT_68
+#define LLDB_API_DEPRECATED_IN_DOT_68
+#define LLDB_API_NEW_IN_DOT_69
+#define LLDB_API_DEPRECATED_IN_DOT_69
+#define LLDB_API_NEW_IN_DOT_70
+#define LLDB_API_DEPRECATED_IN_DOT_70
+#define LLDB_API_NEW_IN_DOT_71
+#define LLDB_API_DEPRECATED_IN_DOT_71
+#define LLDB_API_NEW_IN_DOT_72
+#define LLDB_API_DEPRECATED_IN_DOT_72
+#define LLDB_API_NEW_IN_DOT_73
+#define LLDB_API_DEPRECATED_IN_DOT_73
+#define LLDB_API_NEW_IN_DOT_74
+#define LLDB_API_DEPRECATED_IN_DOT_74
+#define LLDB_API_NEW_IN_DOT_75
+#define LLDB_API_DEPRECATED_IN_DOT_75
+#define LLDB_API_NEW_IN_DOT_76
+#define LLDB_API_DEPRECATED_IN_DOT_76
+#define LLDB_API_NEW_IN_DOT_77
+#define LLDB_API_DEPRECATED_IN_DOT_77
+#define LLDB_API_NEW_IN_DOT_78
+#define LLDB_API_DEPRECATED_IN_DOT_78
+#define LLDB_API_NEW_IN_DOT_79
+#define LLDB_API_DEPRECATED_IN_DOT_79
+#define LLDB_API_NEW_IN_DOT_80
+#define LLDB_API_DEPRECATED_IN_DOT_80
+#define LLDB_API_NEW_IN_DOT_81
+#define LLDB_API_DEPRECATED_IN_DOT_81
+#define LLDB_API_NEW_IN_DOT_82
+#define LLDB_API_DEPRECATED_IN_DOT_82
+#define LLDB_API_NEW_IN_DOT_83
+#define LLDB_API_DEPRECATED_IN_DOT_83
+#define LLDB_API_NEW_IN_DOT_84
+#define LLDB_API_DEPRECATED_IN_DOT_84
+#define LLDB_API_NEW_IN_DOT_85
+#define LLDB_API_DEPRECATED_IN_DOT_85
+#define LLDB_API_NEW_IN_DOT_86
+#define LLDB_API_DEPRECATED_IN_DOT_86
+#define LLDB_API_NEW_IN_DOT_87
+#define LLDB_API_DEPRECATED_IN_DOT_87
+#define LLDB_API_NEW_IN_DOT_88
+#define LLDB_API_DEPRECATED_IN_DOT_88
+#define LLDB_API_NEW_IN_DOT_89
+#define LLDB_API_DEPRECATED_IN_DOT_89
+#define LLDB_API_NEW_IN_DOT_90
+#define LLDB_API_DEPRECATED_IN_DOT_90
+#define LLDB_API_NEW_IN_DOT_91
+#define LLDB_API_DEPRECATED_IN_DOT_91
+#define LLDB_API_NEW_IN_DOT_92
+#define LLDB_API_DEPRECATED_IN_DOT_92
+#define LLDB_API_NEW_IN_DOT_93
+#define LLDB_API_DEPRECATED_IN_DOT_93
+#define LLDB_API_NEW_IN_DOT_94
+#define LLDB_API_DEPRECATED_IN_DOT_94
+#define LLDB_API_NEW_IN_DOT_95
+#define LLDB_API_DEPRECATED_IN_DOT_95
+#define LLDB_API_NEW_IN_DOT_96
+#define LLDB_API_DEPRECATED_IN_DOT_96
+#define LLDB_API_NEW_IN_DOT_97
+#define LLDB_API_DEPRECATED_IN_DOT_97
+#define LLDB_API_NEW_IN_DOT_98
+#define LLDB_API_DEPRECATED_IN_DOT_98
+#define LLDB_API_NEW_IN_DOT_99
+#define LLDB_API_DEPRECATED_IN_DOT_99
+#endif // defined(LLDB_CHECK_API_VERSIONING) && defined(LLDB_API_MAJOR_VERSION_WANTED) && defined(LLDB_API_MINOR_VERSION_WANTED) && defined (LLDB_API_MAJOR_VERSION)
+
+#endif // LLDB_lldb_versioning_h_ \ No newline at end of file