diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -36,6 +36,12 @@ namespace lldb_private { +/// Provides public interface for all SymbolFiles. Any protected +/// virtual member functions should go into SymbolFileActual; most +/// SymbolFile implementations should also inherit from SymbolFileActual +/// to override the behaviors except SymbolFileOnDemand which inherits +/// public interfaces from SymbolFile and forward to underlying concrete +/// SymbolFile implementation. class SymbolFile : public PluginInterface { /// LLVM RTTI support. static char ID; @@ -125,8 +131,9 @@ // Compile Unit function calls // Approach 1 - iterator - uint32_t GetNumCompileUnits(); - lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx); + // Make virtual so that SymbolFileOnDemand can override. + virtual uint32_t GetNumCompileUnits() = 0; + virtual lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) = 0; Symtab *GetSymtab(); @@ -297,7 +304,7 @@ "Operation not supported."); } - virtual void Dump(Stream &s); + virtual void Dump(Stream &s) = 0; /// Metrics gathering functions @@ -360,18 +367,11 @@ protected: void AssertModuleLock(); - virtual uint32_t CalculateNumCompileUnits() = 0; - virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0; - virtual TypeList &GetTypeList() { return m_type_list; } - - void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp); lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in // case it isn't the same as the module // object file (debug symbols in a separate // file) - llvm::Optional> m_compile_units; - TypeList m_type_list; Symtab *m_symtab = nullptr; uint32_t m_abilities = 0; bool m_calculated_abilities = false; diff --git a/lldb/include/lldb/Symbol/SymbolFileActual.h b/lldb/include/lldb/Symbol/SymbolFileActual.h new file mode 100644 --- /dev/null +++ b/lldb/include/lldb/Symbol/SymbolFileActual.h @@ -0,0 +1,60 @@ +//===-- SymbolFileActual.h --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SYMBOL_SYMBOLFILEACTUAL_H +#define LLDB_SYMBOL_SYMBOLFILEACTUAL_H + +#include "lldb/Symbol/SymbolFile.h" + +namespace lldb_private { + +/// Containing protected virtual methods for child classes to override. +/// Most actual SymbolFile implementations should inherit from this class. +class SymbolFileActual : public SymbolFile { + /// LLVM RTTI support. + static char ID; + +public: + /// LLVM RTTI support. + /// \{ + bool isA(const void *ClassID) const override { + return ClassID == &ID || SymbolFile::isA(ClassID); + } + static bool classof(const SymbolFileActual *obj) { return obj->isA(&ID); } + /// \} + + // Constructors and Destructors + SymbolFileActual(lldb::ObjectFileSP objfile_sp) + : SymbolFile(std::move(objfile_sp)) {} + + ~SymbolFileActual() override = default; + + // Compile Unit function calls + // Approach 1 - iterator + uint32_t GetNumCompileUnits() override; + lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override; + + void Dump(Stream &s) override; + +protected: + virtual uint32_t CalculateNumCompileUnits() = 0; + virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0; + virtual TypeList &GetTypeList() { return m_type_list; } + void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp); + + llvm::Optional> m_compile_units; + TypeList m_type_list; + +private: + SymbolFileActual(const SymbolFileActual &) = delete; + const SymbolFileActual &operator=(const SymbolFileActual &) = delete; +}; + +} // namespace lldb_private + +#endif // LLDB_SYMBOL_SYMBOLFILEACTUAL_H diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -13,14 +13,14 @@ #include "lldb/Core/FileSpecList.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/PostfixExpression.h" -#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/SymbolFileActual.h" #include "lldb/Symbol/UnwindPlan.h" namespace lldb_private { namespace breakpad { -class SymbolFileBreakpad : public SymbolFile { +class SymbolFileBreakpad : public SymbolFileActual { /// LLVM RTTI support. static char ID; @@ -28,7 +28,7 @@ /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileActual::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} @@ -49,7 +49,7 @@ // Constructors and Destructors SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)) {} + : SymbolFileActual(std::move(objfile_sp)) {} ~SymbolFileBreakpad() override = default; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -23,7 +23,7 @@ #include "lldb/Core/dwarf.h" #include "lldb/Symbol/DebugMacros.h" #include "lldb/Symbol/SymbolContext.h" -#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/SymbolFileActual.h" #include "lldb/Target/Statistics.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Flags.h" @@ -56,7 +56,7 @@ #define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) -class SymbolFileDWARF : public lldb_private::SymbolFile, +class SymbolFileDWARF : public lldb_private::SymbolFileActual, public lldb_private::UserID { /// LLVM RTTI support. static char ID; @@ -65,7 +65,7 @@ /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileActual::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -274,7 +274,7 @@ std::lock_guard guard(GetModuleMutex()); if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) return debug_map_symfile->GetTypeList(); - return SymbolFile::GetTypeList(); + return SymbolFileActual::GetTypeList(); } void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, dw_offset_t max_die_offset, uint32_t type_mask, @@ -407,7 +407,7 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp, SectionList *dwo_section_list) - : SymbolFile(std::move(objfile_sp)), + : SymbolFileActual(std::move(objfile_sp)), UserID(0x7fffffff00000000), // Used by SymbolFileDWARFDebugMap to // when this class parses .o files to // contain the .o file index/ID @@ -3968,7 +3968,7 @@ } void SymbolFileDWARF::Dump(lldb_private::Stream &s) { - SymbolFile::Dump(s); + SymbolFileActual::Dump(s); m_index->Dump(s); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -9,7 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H -#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/SymbolFileActual.h" #include "lldb/Utility/RangeMap.h" #include "llvm/Support/Chrono.h" #include @@ -22,7 +22,7 @@ class DWARFDebugAranges; class DWARFDeclContext; -class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile { +class SymbolFileDWARFDebugMap : public lldb_private::SymbolFileActual { /// LLVM RTTI support. static char ID; @@ -30,7 +30,7 @@ /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileActual::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -237,7 +237,7 @@ } SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(), + : SymbolFileActual(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(), m_func_indexes(), m_glob_indexes(), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -10,7 +10,7 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H #include "lldb/Symbol/LineTable.h" -#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/SymbolFileActual.h" #include "llvm/ADT/DenseMap.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" @@ -39,7 +39,7 @@ namespace npdb { class PdbAstBuilder; -class SymbolFileNativePDB : public SymbolFile { +class SymbolFileNativePDB : public SymbolFileActual { friend class UdtRecordCompleter; /// LLVM RTTI support. @@ -49,7 +49,7 @@ /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileActual::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -254,7 +254,7 @@ } SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)) {} + : SymbolFileActual(std::move(objfile_sp)) {} SymbolFileNativePDB::~SymbolFileNativePDB() = default; @@ -1916,4 +1916,3 @@ // PDB files are a separate file that contains all debug info. return m_index->pdb().getFileSize(); } - diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -10,7 +10,7 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_SYMBOLFILEPDB_H #include "lldb/Core/UniqueCStringMap.h" -#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/SymbolFileActual.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Utility/UserID.h" @@ -21,7 +21,7 @@ class PDBASTParser; -class SymbolFilePDB : public lldb_private::SymbolFile { +class SymbolFilePDB : public lldb_private::SymbolFileActual { /// LLVM RTTI support. static char ID; @@ -29,7 +29,7 @@ /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileActual::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -135,7 +135,7 @@ } SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {} + : SymbolFileActual(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {} SymbolFilePDB::~SymbolFilePDB() = default; diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -12,10 +12,10 @@ #include #include -#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/SymbolFileActual.h" #include "lldb/Symbol/Symtab.h" -class SymbolFileSymtab : public lldb_private::SymbolFile { +class SymbolFileSymtab : public lldb_private::SymbolFileActual { /// LLVM RTTI support. static char ID; @@ -23,7 +23,7 @@ /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileActual::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -51,8 +51,8 @@ lldb_private::TypeList &type_list) {} SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)), m_source_indexes(), m_func_indexes(), - m_code_indexes(), m_objc_class_name_to_index() {} + : SymbolFileActual(std::move(objfile_sp)), m_source_indexes(), + m_func_indexes(), m_code_indexes(), m_objc_class_name_to_index() {} uint32_t SymbolFileSymtab::CalculateAbilities() { uint32_t abilities = 0; diff --git a/lldb/source/Symbol/CMakeLists.txt b/lldb/source/Symbol/CMakeLists.txt --- a/lldb/source/Symbol/CMakeLists.txt +++ b/lldb/source/Symbol/CMakeLists.txt @@ -27,6 +27,7 @@ Symbol.cpp SymbolContext.cpp SymbolFile.cpp + SymbolFileActual.cpp SymbolVendor.cpp Symtab.cpp Type.cpp diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp --- a/lldb/source/Symbol/SymbolFile.cpp +++ b/lldb/source/Symbol/SymbolFile.cpp @@ -154,42 +154,6 @@ #endif } -uint32_t SymbolFile::GetNumCompileUnits() { - std::lock_guard guard(GetModuleMutex()); - if (!m_compile_units) { - // Create an array of compile unit shared pointers -- which will each - // remain NULL until someone asks for the actual compile unit information. - m_compile_units.emplace(CalculateNumCompileUnits()); - } - return m_compile_units->size(); -} - -CompUnitSP SymbolFile::GetCompileUnitAtIndex(uint32_t idx) { - std::lock_guard guard(GetModuleMutex()); - uint32_t num = GetNumCompileUnits(); - if (idx >= num) - return nullptr; - lldb::CompUnitSP &cu_sp = (*m_compile_units)[idx]; - if (!cu_sp) - cu_sp = ParseCompileUnitAtIndex(idx); - return cu_sp; -} - -void SymbolFile::SetCompileUnitAtIndex(uint32_t idx, const CompUnitSP &cu_sp) { - std::lock_guard guard(GetModuleMutex()); - const size_t num_compile_units = GetNumCompileUnits(); - assert(idx < num_compile_units); - (void)num_compile_units; - - // Fire off an assertion if this compile unit already exists for now. The - // partial parsing should take care of only setting the compile unit - // once, so if this assertion fails, we need to make sure that we don't - // have a race condition, or have a second parse of the same compile - // unit. - assert((*m_compile_units)[idx] == nullptr); - (*m_compile_units)[idx] = cu_sp; -} - Symtab *SymbolFile::GetSymtab() { std::lock_guard guard(GetModuleMutex()); if (m_symtab) @@ -214,27 +178,6 @@ m_symtab->SectionFileAddressesChanged(); } -void SymbolFile::Dump(Stream &s) { - s.Format("SymbolFile {0} ({1})\n", GetPluginName(), - GetMainObjectFile()->GetFileSpec()); - s.PutCString("Types:\n"); - m_type_list.Dump(&s, /*show_context*/ false); - s.PutChar('\n'); - - s.PutCString("Compile units:\n"); - if (m_compile_units) { - for (const CompUnitSP &cu_sp : *m_compile_units) { - // We currently only dump the compile units that have been parsed - if (cu_sp) - cu_sp->Dump(&s, /*show_context*/ false); - } - } - s.PutChar('\n'); - - if (Symtab *symtab = GetSymtab()) - symtab->Dump(&s, nullptr, eSortOrderNone); -} - SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default; uint64_t SymbolFile::GetDebugInfoSize() { diff --git a/lldb/source/Symbol/SymbolFileActual.cpp b/lldb/source/Symbol/SymbolFileActual.cpp new file mode 100644 --- /dev/null +++ b/lldb/source/Symbol/SymbolFileActual.cpp @@ -0,0 +1,68 @@ +#include "lldb/Symbol/SymbolFileActual.h" + +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symtab.h" + +using namespace lldb; +using namespace lldb_private; + +char SymbolFileActual::ID; + +uint32_t SymbolFileActual::GetNumCompileUnits() { + std::lock_guard guard(GetModuleMutex()); + if (!m_compile_units) { + // Create an array of compile unit shared pointers -- which will each + // remain NULL until someone asks for the actual compile unit information. + m_compile_units.emplace(CalculateNumCompileUnits()); + } + return m_compile_units->size(); +} + +CompUnitSP SymbolFileActual::GetCompileUnitAtIndex(uint32_t idx) { + std::lock_guard guard(GetModuleMutex()); + uint32_t num = GetNumCompileUnits(); + if (idx >= num) + return nullptr; + lldb::CompUnitSP &cu_sp = (*m_compile_units)[idx]; + if (!cu_sp) + cu_sp = ParseCompileUnitAtIndex(idx); + return cu_sp; +} + +void SymbolFileActual::SetCompileUnitAtIndex(uint32_t idx, + const CompUnitSP &cu_sp) { + std::lock_guard guard(GetModuleMutex()); + const size_t num_compile_units = GetNumCompileUnits(); + assert(idx < num_compile_units); + (void)num_compile_units; + + // Fire off an assertion if this compile unit already exists for now. The + // partial parsing should take care of only setting the compile unit + // once, so if this assertion fails, we need to make sure that we don't + // have a race condition, or have a second parse of the same compile + // unit. + assert((*m_compile_units)[idx] == nullptr); + (*m_compile_units)[idx] = cu_sp; +} + +void SymbolFileActual::Dump(Stream &s) { + s.Format("SymbolFile {0} ({1})\n", GetPluginName(), + GetMainObjectFile()->GetFileSpec()); + s.PutCString("Types:\n"); + m_type_list.Dump(&s, /*show_context*/ false); + s.PutChar('\n'); + + s.PutCString("Compile units:\n"); + if (m_compile_units) { + for (const CompUnitSP &cu_sp : *m_compile_units) { + // We currently only dump the compile units that have been parsed + if (cu_sp) + cu_sp->Dump(&s, /*show_context*/ false); + } + } + s.PutChar('\n'); + + if (Symtab *symtab = GetSymtab()) + symtab->Dump(&s, nullptr, eSortOrderNone); +}