diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -35,6 +35,7 @@ class DWARFASTParserClang; class PDBASTParser; +class SymbolFileDWARF; namespace lldb_private { @@ -408,7 +409,7 @@ size_t bit_size); // TypeSystem methods - DWARFASTParser *GetDWARFParser() override; + DWARFASTParser *GetDWARFParser(SymbolFileDWARF &dwarf) override; PDBASTParser *GetPDBParser() override; // ClangASTContext callbacks for external source lookups. diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -29,6 +29,7 @@ class DWARFDIE; class DWARFASTParser; class PDBASTParser; +class SymbolFileDWARF; namespace lldb_private { @@ -104,7 +105,9 @@ // removing all the TypeSystems from the TypeSystemMap. virtual void Finalize() {} - virtual DWARFASTParser *GetDWARFParser() { return nullptr; } + virtual DWARFASTParser *GetDWARFParser(SymbolFileDWARF &dwarf) { + return nullptr; + } virtual PDBASTParser *GetPDBParser() { return nullptr; } virtual SymbolFile *GetSymbolFile() const { return m_sym_file; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -9,11 +9,12 @@ #ifndef SymbolFileDWARF_DWARFASTParser_h_ #define SymbolFileDWARF_DWARFASTParser_h_ +#include "DIERef.h" #include "DWARFDefines.h" #include "lldb/Core/PluginInterface.h" -#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" +#include "lldb/Symbol/SymbolFile.h" class DWARFDIE; namespace lldb_private { @@ -39,7 +40,7 @@ lldb_private::CompilerType &compiler_type) = 0; virtual lldb_private::CompilerDecl - GetDeclForUIDFromDWARF(const DWARFDIE &die) = 0; + GetDeclForUIDFromDWARF(SymbolFileDWARF &dwarf, DIERef die_ref) = 0; virtual lldb_private::CompilerDeclContext GetDeclContextForUIDFromDWARF(const DWARFDIE &die) = 0; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -36,7 +36,8 @@ class DWARFASTParserClang : public DWARFASTParser { public: - DWARFASTParserClang(lldb_private::ClangASTContext &ast); + DWARFASTParserClang(lldb_private::ClangASTContext &ast, + SymbolFileDWARF &dwarf); ~DWARFASTParserClang() override; @@ -53,8 +54,8 @@ CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, lldb_private::CompilerType &compiler_type) override; - lldb_private::CompilerDecl - GetDeclForUIDFromDWARF(const DWARFDIE &die) override; + lldb_private::CompilerDecl GetDeclForUIDFromDWARF(SymbolFileDWARF &dwarf, + DIERef die_ref) override; void EnsureAllDIEsInDeclContextHaveBeenParsed( lldb_private::CompilerDeclContext decl_context) override; @@ -83,6 +84,7 @@ typedef llvm::DenseMap DeclToDIEMap; lldb_private::ClangASTContext &m_ast; + SymbolFileDWARF &m_dwarf; DIEToDeclMap m_die_to_decl; DeclToDIEMap m_decl_to_die; DIEToDeclContextMap m_die_to_decl_ctx; @@ -134,7 +136,7 @@ lldb_private::Type *GetTypeForDIE(const DWARFDIE &die); - clang::Decl *GetClangDeclForDIE(const DWARFDIE &die); + clang::Decl *GetClangDeclForDIE(SymbolFileDWARF &dwarf, DIERef die_ref); clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die); @@ -144,6 +146,7 @@ bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die, lldb_private::Type *class_type, + DWARFASTParserClang *dwarf_ast_parser, std::vector &failures); clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -55,8 +55,9 @@ using namespace lldb; using namespace lldb_private; -DWARFASTParserClang::DWARFASTParserClang(ClangASTContext &ast) - : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {} +DWARFASTParserClang::DWARFASTParserClang(ClangASTContext &ast, + SymbolFileDWARF &dwarf) + : m_ast(ast), m_dwarf(dwarf), m_die_to_decl_ctx(), m_decl_ctx_to_die() {} DWARFASTParserClang::~DWARFASTParserClang() {} @@ -135,43 +136,10 @@ return false; } -static DWARFDIE GetContainingClangModuleDIE(const DWARFDIE &die) { - if (die.IsValid()) { - DWARFDIE top_module_die; - // Now make sure this DIE is scoped in a DW_TAG_module tag and return true - // if so - for (DWARFDIE parent = die.GetParent(); parent.IsValid(); - parent = parent.GetParent()) { - const dw_tag_t tag = parent.Tag(); - if (tag == DW_TAG_module) - top_module_die = parent; - else if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) - break; - } - - return top_module_die; - } - return DWARFDIE(); -} - -static lldb::ModuleSP GetContainingClangModule(const DWARFDIE &die) { - if (die.IsValid()) { - DWARFDIE clang_module_die = GetContainingClangModuleDIE(die); - - if (clang_module_die) { - const char *module_name = clang_module_die.GetName(); - if (module_name) - return die.GetDWARF()->GetExternalModule( - lldb_private::ConstString(module_name)); - } - } - return lldb::ModuleSP(); -} - TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, const DWARFDIE &die, Log *log) { - ModuleSP clang_module_sp = GetContainingClangModule(die); + const ModuleSP &clang_module_sp = sc.module_sp; if (!clang_module_sp) return TypeSP(); @@ -184,7 +152,8 @@ // The type in the Clang module must have the same language as the current CU. LanguageSet languages; - languages.Insert(SymbolFileDWARF::GetLanguage(*die.GetCU())); + languages.Insert(!sc.comp_unit ? eLanguageTypeUnknown + : sc.comp_unit->GetLanguage()); llvm::DenseSet searched_symbol_files; clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, searched_symbol_files, pcm_types); @@ -193,7 +162,8 @@ // by this symbol file, search all of them. Instead of calling // sym_file->FindTypes(), which would return this again, go straight // to the imported modules. - auto &sym_file = die.GetCU()->GetSymbolFileDWARF(); + auto &sym_file = + static_cast(*sc.module_sp->GetSymbolFile()); // Well-formed clang modules never form cycles; guard against corrupted // ones by inserting the current file. @@ -469,7 +439,8 @@ CompilerType clang_type; TypeSP type_sp; - LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU()); + LanguageType cu_language = + !sc.comp_unit ? eLanguageTypeUnknown : sc.comp_unit->GetLanguage(); switch (tag) { case DW_TAG_typedef: case DW_TAG_base_type: @@ -700,7 +671,8 @@ return type_sp; DWARFDeclContext die_decl_ctx; - SymbolFileDWARF::GetDWARFDeclContext(die, die_decl_ctx); + die_decl_ctx.SetLanguage(cu_language); + die.GetDIE()->GetDWARFDeclContext(die.GetCU(), die_decl_ctx); type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); @@ -935,8 +907,10 @@ if (class_type_die) { std::vector failures; - CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, - class_type, failures); + CopyUniqueClassMethodTypes( + decl_ctx_die, class_type_die, class_type, + (DWARFASTParserClang *)dwarf->GetDWARFParser(cu_language), + failures); // FIXME do something with these failures that's // smarter than just dropping them on the ground. @@ -1362,7 +1336,8 @@ CompilerType clang_type; const dw_tag_t tag = die.Tag(); SymbolFileDWARF *dwarf = die.GetDWARF(); - LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU()); + LanguageType cu_language = + !sc.comp_unit ? eLanguageTypeUnknown : sc.comp_unit->GetLanguage(); Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS); @@ -1495,7 +1470,8 @@ return type_sp; DWARFDeclContext die_decl_ctx; - SymbolFileDWARF::GetDWARFDeclContext(die, die_decl_ctx); + die_decl_ctx.SetLanguage(cu_language); + die.GetDIE()->GetDWARFDeclContext(die.GetCU(), die_decl_ctx); // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, // type_name_const_str); @@ -2240,12 +2216,17 @@ it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx; it = m_decl_ctx_to_die.erase(it)) for (DWARFDIE decl = it->second.GetFirstChild(); decl; - decl = decl.GetSibling()) - GetClangDeclForDIE(decl); + decl = decl.GetSibling()) { + llvm::Optional decl_ref = decl.GetDIERef(); + if (!decl_ref) + continue; + GetClangDeclForDIE(m_dwarf, *decl_ref); + } } -CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) { - clang::Decl *clang_decl = GetClangDeclForDIE(die); +CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(SymbolFileDWARF &dwarf, + DIERef die_ref) { + clang::Decl *clang_decl = GetClangDeclForDIE(dwarf, die_ref); if (clang_decl != nullptr) return CompilerDecl(&m_ast, clang_decl); return CompilerDecl(); @@ -2424,11 +2405,9 @@ func_name.SetValue(ConstString(mangled), true); else if ((die.GetParent().Tag() == DW_TAG_compile_unit || die.GetParent().Tag() == DW_TAG_partial_unit) && - Language::LanguageIsCPlusPlus( - SymbolFileDWARF::GetLanguage(*die.GetCU())) && - !Language::LanguageIsObjC( - SymbolFileDWARF::GetLanguage(*die.GetCU())) && - name && strcmp(name, "main") != 0) { + Language::LanguageIsCPlusPlus(comp_unit.GetLanguage()) && + !Language::LanguageIsObjC(comp_unit.GetLanguage()) && name && + strcmp(name, "main") != 0) { // If the mangled name is not present in the DWARF, generate the // demangled name using the decl context. We skip if the function is // "main" as its name is never mangled. @@ -2441,7 +2420,8 @@ DWARFDeclContext decl_ctx; StreamString sstr; - SymbolFileDWARF::GetDWARFDeclContext(die, decl_ctx); + decl_ctx.SetLanguage(comp_unit.GetLanguage()); + die.GetDIE()->GetDWARFDeclContext(die.GetCU(), decl_ctx); sstr << decl_ctx.GetQualifiedName(); clang::DeclContext *containing_decl_ctx = @@ -3356,7 +3336,9 @@ return nullptr; } -clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { +clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(SymbolFileDWARF &dwarf, + DIERef die_ref) { + DWARFDIE die = dwarf.GetDIE(die_ref); if (!die) return nullptr; @@ -3376,7 +3358,10 @@ return cache_pos->second; if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) { - clang::Decl *decl = GetClangDeclForDIE(spec_die); + llvm::Optional spec_die_ref = spec_die.GetDIERef(); + if (!spec_die_ref) + return nullptr; + clang::Decl *decl = GetClangDeclForDIE(dwarf, *spec_die_ref); m_die_to_decl[die.GetDIE()] = decl; m_decl_to_die[decl].insert(die.GetDIE()); return decl; @@ -3384,7 +3369,11 @@ if (DWARFDIE abstract_origin_die = die.GetReferencedDIE(DW_AT_abstract_origin)) { - clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die); + llvm::Optional abstract_origin_die_ref = + abstract_origin_die.GetDIERef(); + if (!abstract_origin_die_ref) + return nullptr; + clang::Decl *decl = GetClangDeclForDIE(dwarf, *abstract_origin_die_ref); m_die_to_decl[die.GetDIE()] = decl; m_decl_to_die[decl].insert(die.GetDIE()); return decl; @@ -3395,13 +3384,12 @@ case DW_TAG_variable: case DW_TAG_constant: case DW_TAG_formal_parameter: { - SymbolFileDWARF *dwarf = die.GetDWARF(); Type *type = GetTypeForDIE(die); - if (dwarf && type) { + if (type) { const char *name = die.GetName(); clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext( - dwarf->GetDeclContextContainingUID(die.GetID())); + dwarf.GetDeclContextContainingUID(die.GetID())); decl = m_ast.CreateVariableDeclaration( decl_context, name, ClangUtil::GetQualType(type->GetForwardCompilerType())); @@ -3409,14 +3397,16 @@ break; } case DW_TAG_imported_declaration: { - SymbolFileDWARF *dwarf = die.GetDWARF(); - DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); - if (imported_uid) { - CompilerDecl imported_decl = SymbolFileDWARF::GetDecl(imported_uid); + DWARFDIE imported_die = die.GetAttributeValueAsReferenceDIE(DW_AT_import); + if (imported_die) { + llvm::Optional imported_die_ref = imported_die.GetDIERef(); + if (!imported_die_ref) + return nullptr; + CompilerDecl imported_decl = dwarf.GetDecl(*imported_die_ref); if (imported_decl) { clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext( - dwarf->GetDeclContextContainingUID(die.GetID())); + dwarf.GetDeclContextContainingUID(die.GetID())); if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast( (clang::Decl *)imported_decl.GetOpaqueDecl())) @@ -3427,16 +3417,17 @@ break; } case DW_TAG_imported_module: { - SymbolFileDWARF *dwarf = die.GetDWARF(); - DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); - - if (imported_uid) { + DWARFDIE imported_die = die.GetAttributeValueAsReferenceDIE(DW_AT_import); + if (imported_die) { + llvm::Optional imported_die_ref = imported_die.GetDIERef(); + if (!imported_die_ref) + return nullptr; CompilerDeclContext imported_decl_ctx = - SymbolFileDWARF::GetDeclContext(imported_uid); + dwarf.GetDeclContext(*imported_die_ref); if (imported_decl_ctx) { clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext( - dwarf->GetDeclContextContainingUID(die.GetID())); + dwarf.GetDeclContextContainingUID(die.GetID())); if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl( imported_decl_ctx)) @@ -3668,7 +3659,8 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die, - lldb_private::Type *class_type, std::vector &failures) { + lldb_private::Type *class_type, DWARFASTParserClang *dwarf_ast_parser, + std::vector &failures) { if (!class_type || !src_class_die || !dst_class_die) return false; if (src_class_die.Tag() != dst_class_die.Tag()) @@ -3777,10 +3769,6 @@ } } - DWARFASTParserClang *dwarf_ast_parser = - (DWARFASTParserClang *)SymbolFileDWARF::GetDWARFParser(*src_die.GetCU()); - lldbassert(dwarf_ast_parser == (DWARFASTParserClang *)SymbolFileDWARF::GetDWARFParser(*dst_die.GetCU()); - // Now do the work of linking the DeclContexts and Types. if (fast_path) { // We can do this quickly. Just run across the tables index-for-index diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -36,7 +36,7 @@ // Otherwise, we need to also check that the context matches. If it does not // match, we do nothing. - if (!SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) + if (!dwarf.DIEInDeclContext(&parent_decl_ctx, die, ref)) return; // In case of a full match, we just insert everything we find. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -100,7 +100,8 @@ unit.GetOffset()); } - const LanguageType cu_language = SymbolFileDWARF::GetLanguage(unit); + const LanguageType cu_language = + SymbolFileDWARF::LanguageTypeFromDWARF(unit.GetDWARFLanguageType()); IndexUnitImpl(unit, cu_language, set); @@ -408,7 +409,7 @@ DWARFDIE die = dwarf.GetDIE(die_ref); if (!die) continue; - if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) + if (dwarf.DIEInDeclContext(&parent_decl_ctx, die, die_ref)) dies.push_back(die); } } @@ -419,7 +420,7 @@ DWARFDIE die = dwarf.GetDIE(die_ref); if (!die) continue; - if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) + if (dwarf.DIEInDeclContext(&parent_decl_ctx, die, die_ref)) dies.push_back(die); } offsets.clear(); 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 @@ -275,7 +275,9 @@ return m_external_type_modules; } - virtual DWARFDIE GetDIE(const DIERef &die_ref); + virtual DWARFUnit *GetUnit(DIERef die_ref); + + DWARFDIE GetDIE(DIERef die_ref); DWARFDIE GetDIE(lldb::user_id_t uid); @@ -303,9 +305,9 @@ /// If this is a DWARF object with a single CU, return its DW_AT_dwo_id. llvm::Optional GetDWOId(); - static bool + bool DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx, - const DWARFDIE &die); + const DWARFDIE &die, DIERef die_ref); std::vector> ParseCallEdgesInFunction(UserID func_id) override; @@ -318,26 +320,29 @@ lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx); - static llvm::Expected - GetTypeSystem(DWARFUnit &unit); + lldb::LanguageType GetLanguage(DIERef die_ref); + + DWARFASTParser *GetDWARFParser(lldb::LanguageType language); + + DWARFASTParser *GetDWARFParser(DIERef die_ref); - static DWARFASTParser *GetDWARFParser(DWARFUnit &unit); + DWARFASTParser *GetDWARFParser(lldb::user_id_t die_uid, + DWARFDIE *die = nullptr); // CompilerDecl related functions - static lldb_private::CompilerDecl GetDecl(const DWARFDIE &die); + lldb_private::CompilerDecl GetDecl(lldb::user_id_t die_uid); - static lldb_private::CompilerDeclContext GetDeclContext(const DWARFDIE &die); + lldb_private::CompilerDecl GetDecl(DIERef die_ref); - static lldb_private::CompilerDeclContext - GetContainingDeclContext(const DWARFDIE &die); + lldb_private::CompilerDeclContext GetDeclContext(lldb::user_id_t die_uid); - static void GetDWARFDeclContext(const DWARFDIE &die, - DWARFDeclContext &dwarf_decl_ctx); + lldb_private::CompilerDeclContext GetDeclContext(DIERef die_ref); - static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val); + lldb_private::CompilerDeclContext + GetContainingDeclContext(lldb::user_id_t die_uid); - static lldb::LanguageType GetLanguage(DWARFUnit &unit); + static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val); protected: typedef llvm::DenseMap 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 @@ -800,13 +800,13 @@ if (!die.IsValid()) return nullptr; - auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); + auto type_system_or_err = GetTypeSystemForLanguage(comp_unit.GetLanguage()); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), std::move(err), "Unable to parse function"); return nullptr; } - DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser(); + DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser(*this); if (!dwarf_ast) return nullptr; @@ -825,7 +825,7 @@ std::lock_guard guard(GetModuleMutex()); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) - return GetLanguage(*dwarf_cu); + return LanguageTypeFromDWARF(dwarf_cu->GetDWARFLanguageType()); else return eLanguageTypeUnknown; } @@ -1241,8 +1241,8 @@ void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) { auto *type_system = decl_ctx.GetTypeSystem(); if (type_system != nullptr) - type_system->GetDWARFParser()->EnsureAllDIEsInDeclContextHaveBeenParsed( - decl_ctx); + type_system->GetDWARFParser(*this) + ->EnsureAllDIEsInDeclContextHaveBeenParsed(decl_ctx); } user_id_t SymbolFileDWARF::GetUID(DIERef ref) { @@ -1307,9 +1307,7 @@ // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIE(). See comments inside the // SymbolFileDWARF::GetDIE() for details. - if (DWARFDIE die = GetDIE(type_uid)) - return GetDecl(die); - return CompilerDecl(); + return GetDecl(type_uid); } CompilerDeclContext @@ -1320,9 +1318,7 @@ // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIE(). See comments inside the // SymbolFileDWARF::GetDIE() for details. - if (DWARFDIE die = GetDIE(type_uid)) - return GetDeclContext(die); - return CompilerDeclContext(); + return GetDeclContext(type_uid); } CompilerDeclContext @@ -1331,9 +1327,7 @@ // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIE(). See comments inside the // SymbolFileDWARF::GetDIE() for details. - if (DWARFDIE die = GetDIE(type_uid)) - return GetContainingDeclContext(die); - return CompilerDeclContext(); + return GetContainingDeclContext(type_uid); } Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { @@ -1417,8 +1411,8 @@ llvm::dyn_cast_or_null(type_system); if (!clang_type_system) return false; - DWARFASTParserClang *ast_parser = - static_cast(clang_type_system->GetDWARFParser()); + DWARFASTParserClang *ast_parser = static_cast( + clang_type_system->GetDWARFParser(*this)); return ast_parser->GetClangASTImporter().CanImport(compiler_type); } @@ -1428,8 +1422,8 @@ ClangASTContext *clang_type_system = llvm::dyn_cast_or_null(compiler_type.GetTypeSystem()); if (clang_type_system) { - DWARFASTParserClang *ast_parser = - static_cast(clang_type_system->GetDWARFParser()); + DWARFASTParserClang *ast_parser = static_cast( + clang_type_system->GetDWARFParser(*this)); if (ast_parser && ast_parser->GetClangASTImporter().CanImport(compiler_type)) return ast_parser->GetClangASTImporter().CompleteType(compiler_type); @@ -1445,8 +1439,9 @@ return true; } - DWARFDIE dwarf_die = GetDIE(die_it->getSecond()); - if (dwarf_die) { + DWARFDIE dwarf_die; + DWARFASTParser *dwarf_ast = GetDWARFParser(die_it->getSecond(), &dwarf_die); + if (dwarf_ast) { // Once we start resolving this type, remove it from the forward // declaration map in case anyone child members or other types require this // type to get resolved. The type will get resolved when all of the calls @@ -1463,9 +1458,7 @@ dwarf_die.GetID(), dwarf_die.GetTagAsCString(), type->GetName().AsCString()); assert(compiler_type); - DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()); - if (dwarf_ast) - return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type); + return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type); } return false; } @@ -1538,20 +1531,27 @@ return lldb::ModuleSP(); } -DWARFDIE -SymbolFileDWARF::GetDIE(const DIERef &die_ref) { +DWARFUnit *SymbolFileDWARF::GetUnit(DIERef die_ref) { if (die_ref.dwo_num()) { return DebugInfo() ->GetUnitAtIndex(*die_ref.dwo_num()) ->GetDwoSymbolFile() - ->GetDIE(die_ref); + ->GetUnit(die_ref); } DWARFDebugInfo *debug_info = DebugInfo(); if (debug_info) - return debug_info->GetDIE(die_ref); + return debug_info->GetUnit(die_ref); else - return DWARFDIE(); + return nullptr; +} + +DWARFDIE +SymbolFileDWARF::GetDIE(DIERef die_ref) { + DWARFUnit *unit = GetUnit(die_ref); + if (!unit) + return {}; + return unit->GetDIE(die_ref.die_offset()); } /// Return the DW_AT_(GNU_)dwo_name. @@ -2151,7 +2151,7 @@ sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); if (parent_decl_ctx) { - DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); + DWARFASTParser *dwarf_ast = GetDWARFParser(die_ref); if (dwarf_ast) { CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); @@ -2299,7 +2299,8 @@ } bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx, - const DWARFDIE &die) { + const DWARFDIE &die, DIERef die_ref) { + assert(die.GetOffset() == die_ref.die_offset()); // If we have no parent decl context to match this DIE matches, and if the // parent decl context isn't valid, we aren't trying to look for any // particular decl context so any die matches. @@ -2307,7 +2308,7 @@ return true; if (die) { - DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); + DWARFASTParser *dwarf_ast = GetDWARFParser(die_ref); if (dwarf_ast) { CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); @@ -2482,7 +2483,7 @@ const DIERef &die_ref = die_offsets[i]; DWARFDIE die = GetDIE(die_ref); if (die) { - if (!DIEInDeclContext(parent_decl_ctx, die)) + if (!DIEInDeclContext(parent_decl_ctx, die, die_ref)) continue; // The containing decl contexts don't match Type *matching_type = ResolveType(die, true, true); @@ -2558,7 +2559,7 @@ m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); continue; } - if (!languages[GetLanguage(*die.GetCU())]) + if (!languages[GetLanguage(die_ref)]) continue; llvm::SmallVector die_context; @@ -2612,10 +2613,10 @@ DWARFDIE die = GetDIE(die_ref); if (die) { - if (!DIEInDeclContext(parent_decl_ctx, die)) + if (!DIEInDeclContext(parent_decl_ctx, die, die_ref)) continue; // The containing decl contexts don't match - DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); + DWARFASTParser *dwarf_ast = GetDWARFParser(die_ref); if (dwarf_ast) { namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die); if (namespace_decl_ctx) @@ -2977,7 +2978,7 @@ // looking for. We don't want to find a "Foo" type from Java if we // are looking for a "Foo" type for C, C++, ObjC, or ObjC++. if (type_system && - !type_system->SupportsLanguage(GetLanguage(*type_die.GetCU()))) + !type_system->SupportsLanguage(GetLanguage(die_ref))) continue; bool try_resolving_type = false; @@ -3012,7 +3013,9 @@ if (try_resolving_type) { DWARFDeclContext type_dwarf_decl_ctx; - GetDWARFDeclContext(type_die, type_dwarf_decl_ctx); + type_dwarf_decl_ctx.SetLanguage(dwarf_decl_ctx.GetLanguage()); + type_die.GetDIE()->GetDWARFDeclContext(type_die.GetCU(), + type_dwarf_decl_ctx); if (log) { GetObjectFile()->GetModule()->LogMessage( @@ -3062,14 +3065,15 @@ if (!die) return {}; - auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); + auto type_system_or_err = GetTypeSystemForLanguage( + !sc.comp_unit ? eLanguageTypeUnknown : sc.comp_unit->GetLanguage()); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), std::move(err), "Unable to parse type"); return {}; } - DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser(); + DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser(*this); if (!dwarf_ast) return {}; @@ -3426,10 +3430,14 @@ // declaration context. if ((parent_tag == DW_TAG_compile_unit || parent_tag == DW_TAG_partial_unit) && - Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU()))) { + Language::LanguageIsCPlusPlus(!sc.comp_unit + ? eLanguageTypeUnknown + : sc.comp_unit->GetLanguage())) { DWARFDeclContext decl_ctx; - GetDWARFDeclContext(die, decl_ctx); + decl_ctx.SetLanguage(!sc.comp_unit ? eLanguageTypeUnknown + : sc.comp_unit->GetLanguage()); + die.GetDIE()->GetDWARFDeclContext(die.GetCU(), decl_ctx); mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString(); } } @@ -4002,53 +4010,80 @@ return m_dwp_symfile.get(); } -llvm::Expected SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) { - return unit.GetSymbolFileDWARF().GetTypeSystemForLanguage(GetLanguage(unit)); -} - -DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) { - auto type_system_or_err = GetTypeSystem(unit); +DWARFASTParser *SymbolFileDWARF::GetDWARFParser(LanguageType language) { + auto type_system_or_err = GetTypeSystemForLanguage(language); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), std::move(err), "Unable to get DWARFASTParser"); return nullptr; } - return type_system_or_err->GetDWARFParser(); + return type_system_or_err->GetDWARFParser(*this); +} + +DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DIERef die_ref) { + return GetDWARFParser(GetLanguage(die_ref)); +} + +DWARFASTParser *SymbolFileDWARF::GetDWARFParser(user_id_t die_uid, + DWARFDIE *die) { + llvm::Optional decoded = DecodeUID(die_uid); + if (!decoded) + return nullptr; + if (die) { + *die = decoded->dwarf.GetDIE(decoded->ref); + if (!*die) + return nullptr; + } + return decoded->dwarf.GetDWARFParser(decoded->ref); +} + +CompilerDecl SymbolFileDWARF::GetDecl(lldb::user_id_t die_uid) { + llvm::Optional decoded = DecodeUID(die_uid); + if (!decoded) + return {}; + DWARFASTParser *dwarf_ast = decoded->dwarf.GetDWARFParser(decoded->ref); + if (dwarf_ast) + return dwarf_ast->GetDeclForUIDFromDWARF(decoded->dwarf, decoded->ref); + else + return CompilerDecl(); } -CompilerDecl SymbolFileDWARF::GetDecl(const DWARFDIE &die) { - DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); +CompilerDecl SymbolFileDWARF::GetDecl(DIERef die_ref) { + DWARFASTParser *dwarf_ast = GetDWARFParser(die_ref); if (dwarf_ast) - return dwarf_ast->GetDeclForUIDFromDWARF(die); + return dwarf_ast->GetDeclForUIDFromDWARF(*this, die_ref); else return CompilerDecl(); } -CompilerDeclContext SymbolFileDWARF::GetDeclContext(const DWARFDIE &die) { - DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); +CompilerDeclContext SymbolFileDWARF::GetDeclContext(lldb::user_id_t die_uid) { + DWARFDIE die; + DWARFASTParser *dwarf_ast = GetDWARFParser(die_uid, &die); if (dwarf_ast) return dwarf_ast->GetDeclContextForUIDFromDWARF(die); else return CompilerDeclContext(); } -CompilerDeclContext -SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) { - DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); +CompilerDeclContext SymbolFileDWARF::GetDeclContext(DIERef die_ref) { + DWARFDIE die = GetDIE(die_ref); + if (!die) + return {}; + DWARFASTParser *dwarf_ast = GetDWARFParser(die_ref); if (dwarf_ast) - return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); + return dwarf_ast->GetDeclContextForUIDFromDWARF(die); else return CompilerDeclContext(); } -void SymbolFileDWARF::GetDWARFDeclContext(const DWARFDIE &die, - DWARFDeclContext &dwarf_decl_ctx) { - if (!die.IsValid()) { - dwarf_decl_ctx.Clear(); - return; - } - dwarf_decl_ctx.SetLanguage(GetLanguage(*die.GetCU())); - die.GetDIE()->GetDWARFDeclContext(die.GetCU(), dwarf_decl_ctx); +CompilerDeclContext +SymbolFileDWARF::GetContainingDeclContext(lldb::user_id_t die_uid) { + DWARFDIE die; + DWARFASTParser *dwarf_ast = GetDWARFParser(die_uid, &die); + if (dwarf_ast) + return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); + else + return CompilerDeclContext(); } LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) { @@ -4064,6 +4099,9 @@ } } -LanguageType SymbolFileDWARF::GetLanguage(DWARFUnit &unit) { - return LanguageTypeFromDWARF(unit.GetDWARFLanguageType()); +LanguageType SymbolFileDWARF::GetLanguage(DIERef die_ref) { + DWARFUnit *unit = GetUnit(die_ref); + if (!unit) + return eLanguageTypeUnknown; + return LanguageTypeFromDWARF(unit->GetDWARFLanguageType()); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -44,8 +44,7 @@ llvm::Expected GetTypeSystemForLanguage(lldb::LanguageType language) override; - DWARFDIE - GetDIE(const DIERef &die_ref) override; + DWARFUnit *GetUnit(DIERef die_ref) override; std::unique_ptr GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -147,9 +147,8 @@ return GetBaseSymbolFile().GetTypeSystemForLanguage(language); } -DWARFDIE -SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { +DWARFUnit *SymbolFileDWARFDwo::GetUnit(DIERef die_ref) { if (*die_ref.dwo_num() == GetDwoNum()) - return DebugInfo()->GetDIE(die_ref); - return GetBaseSymbolFile().GetDIE(die_ref); + return DebugInfo()->GetUnit(die_ref); + return GetBaseSymbolFile().GetUnit(die_ref); } diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -9811,9 +9811,9 @@ } } -DWARFASTParser *ClangASTContext::GetDWARFParser() { +DWARFASTParser *ClangASTContext::GetDWARFParser(SymbolFileDWARF &dwarf) { if (!m_dwarf_ast_parser_up) - m_dwarf_ast_parser_up.reset(new DWARFASTParserClang(*this)); + m_dwarf_ast_parser_up.reset(new DWARFASTParserClang(*this, dwarf)); return m_dwarf_ast_parser_up.get(); } diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp --- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -48,7 +48,7 @@ TEST_F(DWARFASTParserClangTests, EnsureAllDIEsInDeclContextHaveBeenParsedParsesOnlyMatchingEntries) { ClangASTContext ast_ctx; - DWARFASTParserClangStub ast_parser(ast_ctx); + DWARFASTParserClangStub ast_parser(ast_ctx, *(SymbolFileDWARF *)1LL); DWARFUnit *unit = nullptr; std::vector dies = {DWARFDIE(unit, (DWARFDebugInfoEntry *)1LL),