diff options
-rw-r--r-- | lldb/include/lldb/API/SBDebugger.h | 3 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBFileSpec.h | 2 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBSourceManager.h | 8 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBStream.h | 2 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBTarget.h | 4 | ||||
-rw-r--r-- | lldb/include/lldb/Core/Debugger.h | 21 | ||||
-rw-r--r-- | lldb/include/lldb/Core/SourceManager.h | 36 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBDebugger.i | 2 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBTarget.i | 3 | ||||
-rw-r--r-- | lldb/source/API/SBCommandInterpreter.cpp | 1 | ||||
-rw-r--r-- | lldb/source/API/SBDebugger.cpp | 7 | ||||
-rw-r--r-- | lldb/source/API/SBSourceManager.cpp | 108 | ||||
-rw-r--r-- | lldb/source/API/SBTarget.cpp | 7 | ||||
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Core/SourceManager.cpp | 137 | ||||
-rw-r--r-- | lldb/source/Target/Target.cpp | 2 | ||||
-rw-r--r-- | lldb/tools/driver/Driver.cpp | 1 |
17 files changed, 286 insertions, 61 deletions
diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 07d2be01bfa..2bada692f9f 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -127,7 +127,7 @@ public: lldb::SBTarget GetSelectedTarget (); - lldb::SBSourceManager & + lldb::SBSourceManager GetSourceManager (); // REMOVE: just for a quick fix, need to expose platforms through @@ -234,6 +234,7 @@ private: friend class SBInputReader; friend class SBProcess; friend class SBTarget; + friend class SBSourceManager_impl; lldb::SBTarget FindTargetWithLLDBProcess (const lldb::ProcessSP &processSP); diff --git a/lldb/include/lldb/API/SBFileSpec.h b/lldb/include/lldb/API/SBFileSpec.h index ed6613ad005..9890d59fc33 100644 --- a/lldb/include/lldb/API/SBFileSpec.h +++ b/lldb/include/lldb/API/SBFileSpec.h @@ -63,7 +63,7 @@ private: friend class SBLineEntry; friend class SBModule; friend class SBProcess; - friend class SBSourceManager; + friend class SBSourceManager_impl; friend class SBThread; friend class SBTarget; diff --git a/lldb/include/lldb/API/SBSourceManager.h b/lldb/include/lldb/API/SBSourceManager.h index 397835b0122..fff0f13c6f5 100644 --- a/lldb/include/lldb/API/SBSourceManager.h +++ b/lldb/include/lldb/API/SBSourceManager.h @@ -16,10 +16,14 @@ namespace lldb { +class SBSourceManager_impl; + class SBSourceManager { public: - SBSourceManager (const lldb::SBSourceManager &rhs); + SBSourceManager (const SBDebugger &debugger); + SBSourceManager (const SBTarget &target); + SBSourceManager (const SBSourceManager &rhs); ~SBSourceManager(); @@ -45,7 +49,7 @@ protected: private: - lldb_private::SourceManager *m_opaque_ptr; + std::auto_ptr<SBSourceManager_impl> m_opaque_ap; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBStream.h b/lldb/include/lldb/API/SBStream.h index 5b912a7ca6c..8464a9cd649 100644 --- a/lldb/include/lldb/API/SBStream.h +++ b/lldb/include/lldb/API/SBStream.h @@ -69,7 +69,7 @@ protected: friend class SBInstruction; friend class SBInstructionList; friend class SBModule; - friend class SBSourceManager; + friend class SBSourceManager_impl; friend class SBSymbol; friend class SBSymbolContext; friend class SBTarget; diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index bb0f9717513..4349e21e5b0 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -349,6 +349,9 @@ public: lldb::SBTypeList FindTypes (const char* type); + + SBSourceManager + GetSourceManager(); #ifndef SWIG bool @@ -375,6 +378,7 @@ protected: friend class SBSymbol; friend class SBModule; friend class SBValue; + friend class SBSourceManager_impl; //------------------------------------------------------------------ // Constructors are private, use static Target::Create function to diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index ea224988039..5ca4138726c 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -223,6 +223,8 @@ class Debugger : public UserID, public DebuggerInstanceSettings { +friend class SourceManager; // For GetSourceFileCache. + public: class SettingsController : public UserSettingsController @@ -342,16 +344,17 @@ public: 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 () { - lldb::TargetSP selected_target = GetSelectedTarget(); - if (selected_target) - return selected_target->GetSourceManager(); - else - return m_source_manager; + return m_source_manager; } +public: + lldb::TargetSP GetSelectedTarget () { @@ -455,6 +458,12 @@ protected: m_input_comm.Clear (); } + SourceManager::SourceFileCache & + GetSourceFileCache () + { + return m_source_file_cache; + } + Communication m_input_comm; StreamFile m_input_file; StreamFile m_output_file; @@ -463,6 +472,8 @@ protected: PlatformList m_platform_list; Listener m_listener; SourceManager m_source_manager; // 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::auto_ptr<CommandInterpreter> m_command_interpreter_ap; InputReaderStack m_input_reader_stack; diff --git a/lldb/include/lldb/Core/SourceManager.h b/lldb/include/lldb/Core/SourceManager.h index 94c08953fce..fd8a4ddb5c7 100644 --- a/lldb/include/lldb/Core/SourceManager.h +++ b/lldb/include/lldb/Core/SourceManager.h @@ -26,9 +26,12 @@ 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(); @@ -52,7 +55,7 @@ public: { return m_file_spec; } - + protected: bool @@ -65,6 +68,28 @@ public: typedef std::vector<uint32_t> LineOffsets; LineOffsets m_offsets; }; + +#endif // SWIG + + typedef lldb::SharedPtr<File>::Type 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 @@ -73,11 +98,11 @@ public: //------------------------------------------------------------------ // 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(Target *target); + SourceManager (Debugger &debugger); + SourceManager (Target &target); ~SourceManager(); - typedef lldb::SharedPtr<File>::Type FileSP; FileSP GetLastFile () @@ -134,13 +159,13 @@ protected: //------------------------------------------------------------------ // Classes that inherit from SourceManager can see and modify these //------------------------------------------------------------------ - typedef std::map <FileSpec, FileSP> FileCache; - FileCache m_file_cache; FileSP m_last_file_sp; uint32_t m_last_file_line; uint32_t m_last_file_context_before; uint32_t m_last_file_context_after; Target *m_target; + Debugger *m_debugger; + private: //------------------------------------------------------------------ // For SourceManager only @@ -148,6 +173,7 @@ private: 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/lldb/scripts/Python/interface/SBDebugger.i b/lldb/scripts/Python/interface/SBDebugger.i index 4339572a734..b61a447c849 100644 --- a/lldb/scripts/Python/interface/SBDebugger.i +++ b/lldb/scripts/Python/interface/SBDebugger.i @@ -206,7 +206,7 @@ public: lldb::SBTarget GetSelectedTarget (); - lldb::SBSourceManager & + lldb::SBSourceManager GetSourceManager (); // REMOVE: just for a quick fix, need to expose platforms through diff --git a/lldb/scripts/Python/interface/SBTarget.i b/lldb/scripts/Python/interface/SBTarget.i index 40646209be5..baa151c0101 100644 --- a/lldb/scripts/Python/interface/SBTarget.i +++ b/lldb/scripts/Python/interface/SBTarget.i @@ -327,6 +327,9 @@ public: lldb::SBTypeList FindTypes (const char* type); + lldb::SBSourceManager + GetSourceManager (); + %feature("docstring", " //------------------------------------------------------------------ /// Find global and static variables by name. diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp index 95e1cbc2ad2..61d0a99f975 100644 --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -18,7 +18,6 @@ #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBCommandReturnObject.h" -#include "lldb/API/SBSourceManager.h" #include "lldb/API/SBCommandInterpreter.h" #include "lldb/API/SBProcess.h" #include "lldb/API/SBTarget.h" diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index be6873be414..d0687261e83 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -357,12 +357,11 @@ SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, } } -SBSourceManager & +SBSourceManager SBDebugger::GetSourceManager () { - static SourceManager g_lldb_source_manager(NULL); - static SBSourceManager g_sb_source_manager (&g_lldb_source_manager); - return g_sb_source_manager; + SBSourceManager sb_source_manager (*this); + return sb_source_manager; } diff --git a/lldb/source/API/SBSourceManager.cpp b/lldb/source/API/SBSourceManager.cpp index 0fa98e35dea..7bdeabcee72 100644 --- a/lldb/source/API/SBSourceManager.cpp +++ b/lldb/source/API/SBSourceManager.cpp @@ -7,41 +7,110 @@ // //===----------------------------------------------------------------------===// - +#include "lldb/API/SBDebugger.h" #include "lldb/API/SBSourceManager.h" +#include "lldb/API/SBTarget.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBFileSpec.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/SourceManager.h" +#include "lldb/Target/Target.h" using namespace lldb; using namespace lldb_private; +class lldb::SBSourceManager_impl +{ +public: + SBSourceManager_impl (const SBDebugger &debugger) + { + m_debugger_sp = debugger.m_opaque_sp; + } + + SBSourceManager_impl (const SBTarget &target) + { + m_target_sp = target.m_opaque_sp; + } + + SBSourceManager_impl (const SBSourceManager_impl &rhs) + { + if (&rhs == this) + return; + m_debugger_sp = rhs.m_debugger_sp; + m_target_sp = rhs.m_target_sp; + } + + size_t + DisplaySourceLinesWithLineNumbers + ( + const SBFileSpec &file, + uint32_t line, + uint32_t context_before, + uint32_t context_after, + const char* current_line_cstr, + SBStream &s + ) + { + if (!file.IsValid()) + return 0; + + if (m_debugger_sp) + return m_debugger_sp->GetSourceManager().DisplaySourceLinesWithLineNumbers (*file, + line, + context_before, + context_after, + current_line_cstr, + s.m_opaque_ap.get()); + else if (m_target_sp) + return m_target_sp->GetSourceManager().DisplaySourceLinesWithLineNumbers (*file, + line, + context_before, + context_after, + current_line_cstr, + s.m_opaque_ap.get()); + else + return 0; + } + +private: + lldb::DebuggerSP m_debugger_sp; + lldb::TargetSP m_target_sp; + +}; -SBSourceManager::SBSourceManager (SourceManager* source_manager) : - m_opaque_ptr (source_manager) +SBSourceManager::SBSourceManager (const SBDebugger &debugger) { + m_opaque_ap.reset(new SBSourceManager_impl (debugger)); } -SBSourceManager::~SBSourceManager() +SBSourceManager::SBSourceManager (const SBTarget &target) { + m_opaque_ap.reset(new SBSourceManager_impl (target)); } -SBSourceManager::SBSourceManager(const SBSourceManager &rhs) : - m_opaque_ptr (rhs.m_opaque_ptr) +SBSourceManager::SBSourceManager (const SBSourceManager &rhs) { + if (&rhs == this) + return; + + m_opaque_ap.reset(new SBSourceManager_impl (*(rhs.m_opaque_ap.get()))); } -const SBSourceManager & -SBSourceManager::operator = (const SBSourceManager &rhs) +const lldb::SBSourceManager & +SBSourceManager::operator = (const lldb::SBSourceManager &rhs) { - m_opaque_ptr = rhs.m_opaque_ptr; + m_opaque_ap.reset (new SBSourceManager_impl (*(rhs.m_opaque_ap.get()))); return *this; } +SBSourceManager::~SBSourceManager() +{ +} + size_t SBSourceManager::DisplaySourceLinesWithLineNumbers ( @@ -53,20 +122,13 @@ SBSourceManager::DisplaySourceLinesWithLineNumbers SBStream &s ) { - if (m_opaque_ptr == NULL) - return 0; - - if (s.m_opaque_ap.get() == NULL) + if (m_opaque_ap.get() == NULL) return 0; - if (file.IsValid()) - { - return m_opaque_ptr->DisplaySourceLinesWithLineNumbers (*file, - line, - context_before, - context_after, - current_line_cstr, - s.m_opaque_ap.get()); - } - return 0; + return m_opaque_ap->DisplaySourceLinesWithLineNumbers (file, + line, + context_before, + context_after, + current_line_cstr, + s); } diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 93d3cf18688..3343b48a623 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -16,6 +16,7 @@ #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBListener.h" #include "lldb/API/SBModule.h" +#include "lldb/API/SBSourceManager.h" #include "lldb/API/SBProcess.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBSymbolContextList.h" @@ -958,3 +959,9 @@ SBTarget::FindGlobalVariables (const char *name, uint32_t max_matches) return sb_value_list; } +SBSourceManager +SBTarget::GetSourceManager() +{ + SBSourceManager source_manager (*this); + return source_manager; +} diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 3213ba8ade3..5f7504a9e87 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -237,7 +237,8 @@ Debugger::Debugger () : m_target_list (), m_platform_list (), m_listener ("lldb.Debugger"), - m_source_manager(NULL), + m_source_manager(*this), + m_source_file_cache(), m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), m_input_reader_stack (), m_input_reader_data () diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp index cdf98eb4e98..708bf89bd99 100644 --- a/lldb/source/Core/SourceManager.cpp +++ b/lldb/source/Core/SourceManager.cpp @@ -14,6 +14,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/DataBuffer.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Stream.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/Target.h" @@ -29,13 +30,24 @@ static inline bool is_newline_char(char ch) //---------------------------------------------------------------------- // SourceManager constructor //---------------------------------------------------------------------- -SourceManager::SourceManager(Target *target) : - m_file_cache (), +SourceManager::SourceManager(Target &target) : m_last_file_sp (), m_last_file_line (0), m_last_file_context_before (0), m_last_file_context_after (10), - m_target (target) + m_target (&target), + m_debugger(NULL) +{ + m_debugger = &(m_target->GetDebugger()); +} + +SourceManager::SourceManager(Debugger &debugger) : + m_last_file_sp (), + m_last_file_line (0), + m_last_file_context_before (0), + m_last_file_context_after (10), + m_target (NULL), + m_debugger (&debugger) { } @@ -70,13 +82,12 @@ SourceManager::FileSP SourceManager::GetFile (const FileSpec &file_spec) { FileSP file_sp; - FileCache::iterator pos = m_file_cache.find(file_spec); - if (pos != m_file_cache.end()) - file_sp = pos->second; - else + file_sp = m_debugger->GetSourceFileCache().FindSourceFile (file_spec); + if (!file_sp) { file_sp.reset (new File (file_spec, m_target)); - m_file_cache[file_spec] = file_sp; + + m_debugger->GetSourceFileCache().AddSourceFile(file_sp); } return file_sp; } @@ -92,6 +103,7 @@ SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile const SymbolContextList *bp_locs ) { + size_t return_value = 0; if (line == 0) { if (m_last_file_line != 0 @@ -134,18 +146,21 @@ SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile ::snprintf (prefix, sizeof (prefix), " "); } - s->Printf("%s%2.2s %-4u\t", + return_value += s->Printf("%s%2.2s %-4u\t", prefix, curr_line == line ? current_line_cstr : "", curr_line); - if (m_last_file_sp->DisplaySourceLines (curr_line, 0, 0, s) == 0) + size_t this_line_size = m_last_file_sp->DisplaySourceLines (curr_line, 0, 0, s); + if (this_line_size == 0) { m_last_file_line = UINT32_MAX; break; } + else + return_value += this_line_size; } } - return 0; + return return_value; } size_t @@ -181,7 +196,7 @@ SourceManager::DisplayMoreWithLineNumbers (Stream *s, const SymbolContextList *b { if (m_last_file_line == UINT32_MAX) return 0; - DisplaySourceLinesWithLineNumbersUsingLastFile (0, m_last_file_context_before, m_last_file_context_after, "", s, bp_locs); + return DisplaySourceLinesWithLineNumbersUsingLastFile (0, m_last_file_context_before, m_last_file_context_after, "", s, bp_locs); } return 0; } @@ -226,8 +241,57 @@ SourceManager::File::File(const FileSpec &file_spec, Target *target) : { if (!m_mod_time.IsValid()) { - if (target && target->GetSourcePathMap().RemapPath(file_spec.GetDirectory(), m_file_spec.GetDirectory())) - m_mod_time = file_spec.GetModificationTime(); + if (target) + { + if (!file_spec.GetDirectory() && file_spec.GetFilename()) + { + // If this is just a file name, lets see if we can find it in the target: + bool check_inlines = false; + SymbolContextList sc_list; + size_t num_matches = target->GetImages().ResolveSymbolContextForFilePath (file_spec.GetFilename().AsCString(), + 0, + check_inlines, + lldb::eSymbolContextModule | lldb::eSymbolContextCompUnit, + sc_list); + bool got_multiple = false; + if (num_matches != 0) + { + if (num_matches > 1) + { + SymbolContext sc; + FileSpec *test_cu_spec = NULL; + + for (unsigned i = 0; i < num_matches; i++) + { + sc_list.GetContextAtIndex(i, sc); + if (sc.comp_unit) + { + if (test_cu_spec) + { + if (test_cu_spec != static_cast<FileSpec *> (sc.comp_unit)) + got_multiple = true; + break; + } + else + test_cu_spec = sc.comp_unit; + } + } + } + if (!got_multiple) + { + SymbolContext sc; + sc_list.GetContextAtIndex (0, sc); + m_file_spec = static_cast<FileSpec *>(sc.comp_unit); + m_mod_time = m_file_spec.GetModificationTime(); + } + } + } + else + { + if (target->GetSourcePathMap().RemapPath(file_spec.GetDirectory(), m_file_spec.GetDirectory())) + m_mod_time = file_spec.GetModificationTime(); + } + } } if (m_mod_time.IsValid()) @@ -310,6 +374,26 @@ SourceManager::File::FileSpecMatches (const FileSpec &file_spec) return FileSpec::Equal (m_file_spec, file_spec, false); } +bool +lldb_private::operator== (const SourceManager::File &lhs, const SourceManager::File &rhs) +{ + if (lhs.m_file_spec == rhs.m_file_spec) + { + if (lhs.m_mod_time.IsValid()) + { + if (rhs.m_mod_time.IsValid()) + return lhs.m_mod_time == rhs.m_mod_time; + else + return false; + } + else if (rhs.m_mod_time.IsValid()) + return false; + else + return true; + } + else + return false; +} bool SourceManager::File::CalculateLineOffsets (uint32_t line) @@ -372,3 +456,28 @@ SourceManager::File::CalculateLineOffsets (uint32_t line) } return false; } + +void +SourceManager::SourceFileCache::AddSourceFile (const FileSP &file_sp) +{ + FileSpec file_spec; + FileCache::iterator pos = m_file_cache.find(file_spec); + if (pos == m_file_cache.end()) + m_file_cache[file_spec] = file_sp; + else + { + if (file_sp != pos->second) + m_file_cache[file_spec] = file_sp; + } +} + +SourceManager::FileSP +SourceManager::SourceFileCache::FindSourceFile (const FileSpec &file_spec) const +{ + FileSP file_sp; + FileCache::const_iterator pos = m_file_cache.find(file_spec); + if (pos != m_file_cache.end()) + file_sp = pos->second; + return file_sp; +} + diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 7dfe4558c8f..ac50ef1cd67 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -59,7 +59,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::Plat m_image_search_paths (ImageSearchPathsChanged, this), m_scratch_ast_context_ap (NULL), m_persistent_variables (), - m_source_manager(this), + m_source_manager(*this), m_stop_hooks (), m_stop_hook_next_id (0), m_suppress_stop_hooks (false) diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 0273b20bab5..7929390e446 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -29,7 +29,6 @@ #include "lldb/API/SBEvent.h" #include "lldb/API/SBHostOS.h" #include "lldb/API/SBListener.h" -#include "lldb/API/SBSourceManager.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBTarget.h" #include "lldb/API/SBThread.h" |