From e37d605e7d3ff1b684962a006000dec601b7a1f6 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Tue, 13 Sep 2011 00:29:56 +0000 Subject: [PATCH] SBSourceManager now gets the real source manager either from the Debugger or Target. Also, move the SourceManager file cache into the debugger so it can be shared amongst the targets. llvm-svn: 139564 --- lldb/include/lldb/API/SBDebugger.h | 3 +- lldb/include/lldb/API/SBFileSpec.h | 2 +- lldb/include/lldb/API/SBSourceManager.h | 8 +- lldb/include/lldb/API/SBStream.h | 2 +- lldb/include/lldb/API/SBTarget.h | 4 + lldb/include/lldb/Core/Debugger.h | 21 +++- lldb/include/lldb/Core/SourceManager.h | 36 +++++- lldb/scripts/Python/interface/SBDebugger.i | 2 +- lldb/scripts/Python/interface/SBTarget.i | 3 + lldb/source/API/SBCommandInterpreter.cpp | 1 - lldb/source/API/SBDebugger.cpp | 7 +- lldb/source/API/SBSourceManager.cpp | 122 +++++++++++++----- lldb/source/API/SBTarget.cpp | 7 ++ lldb/source/Core/Debugger.cpp | 3 +- lldb/source/Core/SourceManager.cpp | 137 ++++++++++++++++++--- lldb/source/Target/Target.cpp | 2 +- lldb/tools/driver/Driver.cpp | 1 - 17 files changed, 293 insertions(+), 68 deletions(-) diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 07d2be01bfaa..2bada692f9fa 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 ed6613ad0053..9890d59fc330 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 397835b01220..fff0f13c6f5a 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 m_opaque_ap; }; } // namespace lldb diff --git a/lldb/include/lldb/API/SBStream.h b/lldb/include/lldb/API/SBStream.h index 5b912a7ca6c5..8464a9cd649f 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 bb0f97175130..4349e21e5b0c 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 ea2249880395..5ca4138726c9 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 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 94c08953fcec..fd8a4ddb5c72 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 LineOffsets; LineOffsets m_offsets; }; + +#endif // SWIG + + typedef lldb::SharedPtr::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 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::Type FileSP; FileSP GetLastFile () @@ -134,13 +159,13 @@ protected: //------------------------------------------------------------------ // Classes that inherit from SourceManager can see and modify these //------------------------------------------------------------------ - typedef std::map 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 4339572a7344..b61a447c849e 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 40646209be5e..baa151c01013 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 95e1cbc2ad29..61d0a99f975b 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 be6873be414b..d0687261e83f 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 0fa98e35dea2..7bdeabcee72f 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; - -SBSourceManager::SBSourceManager (SourceManager* source_manager) : - m_opaque_ptr (source_manager) +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 (const SBDebugger &debugger) +{ + m_opaque_ap.reset(new SBSourceManager_impl (debugger)); +} + +SBSourceManager::SBSourceManager (const SBTarget &target) +{ + m_opaque_ap.reset(new SBSourceManager_impl (target)); +} + +SBSourceManager::SBSourceManager (const SBSourceManager &rhs) +{ + if (&rhs == this) + return; + + m_opaque_ap.reset(new SBSourceManager_impl (*(rhs.m_opaque_ap.get()))); +} + +const lldb::SBSourceManager & +SBSourceManager::operator = (const lldb::SBSourceManager &rhs) +{ + m_opaque_ap.reset (new SBSourceManager_impl (*(rhs.m_opaque_ap.get()))); + return *this; } SBSourceManager::~SBSourceManager() { } -SBSourceManager::SBSourceManager(const SBSourceManager &rhs) : - m_opaque_ptr (rhs.m_opaque_ptr) -{ -} - -const SBSourceManager & -SBSourceManager::operator = (const SBSourceManager &rhs) -{ - m_opaque_ptr = rhs.m_opaque_ptr; - return *this; -} - size_t SBSourceManager::DisplaySourceLinesWithLineNumbers ( @@ -53,20 +122,13 @@ SBSourceManager::DisplaySourceLinesWithLineNumbers SBStream &s ) { - if (m_opaque_ptr == NULL) + if (m_opaque_ap.get() == NULL) return 0; - if (s.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 93d3cf186886..3343b48a623d 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 3213ba8ade3c..5f7504a9e879 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 cdf98eb4e989..708bf89bd99b 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 (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(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 7dfe4558c8fe..ac50ef1cd673 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 0273b20bab57..7929390e446e 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"