diff --git a/lldb/include/lldb/Symbol/CompileUnit.h b/lldb/include/lldb/Symbol/CompileUnit.h --- a/lldb/include/lldb/Symbol/CompileUnit.h +++ b/lldb/include/lldb/Symbol/CompileUnit.h @@ -22,6 +22,8 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" +class DWARFCompileUnit; + namespace lldb_private { /// \class CompileUnit CompileUnit.h "lldb/Symbol/CompileUnit.h" /// A class that describes a compilation unit. @@ -403,6 +405,8 @@ /// Returns the number of functions in this compile unit size_t GetNumFunctions() const { return m_functions_by_uid.size(); } + DWARFCompileUnit *GetDWARFCompileUnit(); + protected: /// User data for the SymbolFile parser to store information into. void *m_user_data; diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h --- a/lldb/include/lldb/Symbol/SymbolContext.h +++ b/lldb/include/lldb/Symbol/SymbolContext.h @@ -19,6 +19,9 @@ #include "lldb/Utility/Iterable.h" #include "lldb/lldb-private.h" +class DWARFCompileUnit; +class SymbolFileDWARF; + namespace lldb_private { class SymbolContextScope; @@ -313,6 +316,8 @@ SymbolContext &next_frame_sc, Address &inlined_frame_addr) const; + DWARFCompileUnit *GetDWARFCompileUnit(SymbolFileDWARF **dwarf_return = nullptr) const; + // Member variables lldb::TargetSP target_sp; ///< The Target for a given query lldb::ModuleSP module_sp; ///< The Module for a given query 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 @@ -298,6 +298,8 @@ virtual void Dump(Stream &s); + virtual DWARFCompileUnit *GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { return nullptr; } + protected: void AssertModuleLock(); virtual uint32_t CalculateNumCompileUnits() = 0; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h @@ -32,32 +32,47 @@ void Preload() override {} - void - GetGlobalVariables(ConstString basename, - llvm::function_ref callback) override; - void - GetGlobalVariables(const RegularExpression ®ex, - llvm::function_ref callback) override; - void - GetGlobalVariables(const DWARFUnit &cu, - llvm::function_ref callback) override; - void GetObjCMethods(ConstString class_name, - llvm::function_ref callback) override; + void GetGlobalVariables( + ConstString basename, + llvm::function_ref + callback) override; + void GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref + callback) override; + void GetGlobalVariables( + const DWARFUnit &main_unit, + llvm::function_ref + callback) override; + void GetObjCMethods( + ConstString class_name, + llvm::function_ref + callback) override; void GetCompleteObjCClass( ConstString class_name, bool must_be_implementation, - llvm::function_ref callback) override; - void GetTypes(ConstString name, - llvm::function_ref callback) override; - void GetTypes(const DWARFDeclContext &context, - llvm::function_ref callback) override; - void GetNamespaces(ConstString name, - llvm::function_ref callback) override; - void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - llvm::function_ref callback) override; - void GetFunctions(const RegularExpression ®ex, - llvm::function_ref callback) override; + llvm::function_ref + callback) override; + void + GetTypes(ConstString name, + llvm::function_ref + callback) override; + void + GetTypes(const DWARFDeclContext &context, + llvm::function_ref + callback) override; + void GetNamespaces( + ConstString name, + llvm::function_ref + callback) override; + void GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref + callback) override; + void GetFunctions( + const RegularExpression ®ex, + llvm::function_ref + callback) override; void Dump(Stream &s) override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -53,7 +53,9 @@ } void AppleDWARFIndex::GetGlobalVariables( - ConstString basename, llvm::function_ref callback) { + ConstString basename, + llvm::function_ref + callback) { if (!m_apple_names_up) return; m_apple_names_up->FindByName( @@ -63,7 +65,8 @@ void AppleDWARFIndex::GetGlobalVariables( const RegularExpression ®ex, - llvm::function_ref callback) { + llvm::function_ref + callback) { if (!m_apple_names_up) return; @@ -75,18 +78,22 @@ } void AppleDWARFIndex::GetGlobalVariables( - const DWARFUnit &cu, llvm::function_ref callback) { + const DWARFUnit &main_unit, + llvm::function_ref + callback) { if (!m_apple_names_up) return; DWARFMappedHash::DIEInfoArray hash_data; - m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), cu.GetNextUnitOffset(), + m_apple_names_up->AppendAllDIEsInRange(main_unit.GetOffset(), main_unit.GetNextUnitOffset(), hash_data); DWARFMappedHash::ExtractDIEArray(hash_data, DIERefCallback(callback)); } void AppleDWARFIndex::GetObjCMethods( - ConstString class_name, llvm::function_ref callback) { + ConstString class_name, + llvm::function_ref + callback) { if (!m_apple_objc_up) return; m_apple_objc_up->FindByName( @@ -96,7 +103,8 @@ void AppleDWARFIndex::GetCompleteObjCClass( ConstString class_name, bool must_be_implementation, - llvm::function_ref callback) { + llvm::function_ref + callback) { if (!m_apple_types_up) return; m_apple_types_up->FindCompleteObjCClassByName( @@ -106,7 +114,9 @@ } void AppleDWARFIndex::GetTypes( - ConstString name, llvm::function_ref callback) { + ConstString name, + llvm::function_ref + callback) { if (!m_apple_types_up) return; m_apple_types_up->FindByName(name.GetStringRef(), @@ -115,7 +125,8 @@ void AppleDWARFIndex::GetTypes( const DWARFDeclContext &context, - llvm::function_ref callback) { + llvm::function_ref + callback) { if (!m_apple_types_up) return; @@ -169,7 +180,9 @@ } void AppleDWARFIndex::GetNamespaces( - ConstString name, llvm::function_ref callback) { + ConstString name, + llvm::function_ref + callback) { if (!m_apple_namespaces_up) return; m_apple_namespaces_up->FindByName( @@ -179,16 +192,19 @@ void AppleDWARFIndex::GetFunctions( ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - llvm::function_ref callback) { + llvm::function_ref + callback) { m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) { - return ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, - parent_decl_ctx, name_type_mask, callback); + return ProcessFunctionDIE(name.GetStringRef(), nullptr /* main_unit */, + die_ref, dwarf, parent_decl_ctx, name_type_mask, + callback); }); } void AppleDWARFIndex::GetFunctions( const RegularExpression ®ex, - llvm::function_ref callback) { + llvm::function_ref + callback) { if (!m_apple_names_up) return; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h @@ -54,6 +54,15 @@ return m_die_offset < other.m_die_offset; } + bool operator==(DIERef other) const { + if (m_dwo_num_valid != other.m_dwo_num_valid || + m_section != other.m_section || m_die_offset != other.m_die_offset) + return false; + if (m_dwo_num_valid && m_dwo_num != other.m_dwo_num) + return false; + return true; + } + private: uint32_t m_dwo_num : 30; uint32_t m_dwo_num_valid : 1; 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 @@ -35,17 +35,19 @@ const DWARFDIE &die) = 0; virtual bool - CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, + CompleteTypeFromDWARF(DWARFUnit *main_unit, const DWARFDIE &die, lldb_private::Type *type, lldb_private::CompilerType &compiler_type) = 0; virtual lldb_private::CompilerDecl - GetDeclForUIDFromDWARF(const DWARFDIE &die) = 0; + GetDeclForUIDFromDWARF(DWARFUnit *main_unit, const DWARFDIE &die) = 0; virtual lldb_private::CompilerDeclContext - GetDeclContextForUIDFromDWARF(const DWARFDIE &die) = 0; + GetDeclContextForUIDFromDWARF(DWARFUnit *main_unit, + const DWARFDIE &die) = 0; virtual lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) = 0; + GetDeclContextContainingUIDFromDWARF(DWARFUnit *main_unit, + const DWARFDIE &die) = 0; virtual void EnsureAllDIEsInDeclContextHaveBeenParsed( lldb_private::CompilerDeclContext decl_context) = 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 @@ -11,7 +11,7 @@ #include "clang/AST/CharUnits.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "DWARFASTParser.h" @@ -50,20 +50,23 @@ const DWARFDIE &die) override; bool - CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, + CompleteTypeFromDWARF(DWARFUnit *main_unit, const DWARFDIE &die, lldb_private::Type *type, lldb_private::CompilerType &compiler_type) override; lldb_private::CompilerDecl - GetDeclForUIDFromDWARF(const DWARFDIE &die) override; + GetDeclForUIDFromDWARF(DWARFUnit *main_unit, + const DWARFDIE &die) override; void EnsureAllDIEsInDeclContextHaveBeenParsed( lldb_private::CompilerDeclContext decl_context) override; lldb_private::CompilerDeclContext - GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override; + GetDeclContextForUIDFromDWARF(DWARFUnit *main_unit, + const DWARFDIE &die) override; lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override; + GetDeclContextContainingUIDFromDWARF(DWARFUnit *main_unit, + const DWARFDIE &die) override; lldb_private::ClangASTImporter &GetClangASTImporter(); @@ -73,15 +76,22 @@ class DelayedAddObjCClassProperty; typedef std::vector DelayedPropertyList; - typedef llvm::SmallPtrSet DIEPointerSet; - typedef llvm::DenseMap + typedef llvm::SmallSet< + std::pair, 4> + DIEPointerSet; + typedef llvm::DenseMap< + std::pair, + clang::DeclContext *> DIEToDeclContextMap; - typedef std::multimap + typedef std::multimap> DeclContextToDIEMap; - typedef llvm::DenseMap + typedef llvm::DenseMap< + std::pair, + lldb_private::OptionalClangModuleID> DIEToModuleMap; - typedef llvm::DenseMap + typedef llvm::DenseMap< + std::pair, clang::Decl *> DIEToDeclMap; typedef llvm::DenseMap DeclToDIEMap; @@ -94,21 +104,26 @@ std::unique_ptr m_clang_ast_importer_up; /// @} - clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die); + clang::DeclContext *GetDeclContextForBlock(DWARFUnit *main_unit, + const DWARFDIE &die); - clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die); + clang::BlockDecl *ResolveBlockDIE(DWARFUnit *main_unit, + const DWARFDIE &die); - clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die); + clang::NamespaceDecl *ResolveNamespaceDIE(DWARFUnit *main_unit, + const DWARFDIE &die); - bool ParseTemplateDIE(const DWARFDIE &die, + bool ParseTemplateDIE(DWARFUnit *main_unit, const DWARFDIE &die, lldb_private::TypeSystemClang::TemplateParameterInfos &template_param_infos); bool ParseTemplateParameterInfos( - const DWARFDIE &parent_die, + DWARFUnit *main_unit, const DWARFDIE &parent_die, lldb_private::TypeSystemClang::TemplateParameterInfos &template_param_infos); bool ParseChildMembers( + lldb_private::CompileUnit *comp_unit, + DWARFUnit *main_unit, const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type, std::vector> &base_classes, std::vector &member_accessibilities, @@ -118,7 +133,8 @@ lldb_private::ClangASTImporter::LayoutInfo &layout_info); size_t - ParseChildParameters(clang::DeclContext *containing_decl_ctx, + ParseChildParameters(lldb_private::CompileUnit *comp_unit, + clang::DeclContext *containing_decl_ctx, DWARFUnit *main_unit, const DWARFDIE &parent_die, bool skip_artificial, bool &is_static, bool &is_variadic, bool &has_template_params, @@ -135,24 +151,33 @@ const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs); - lldb_private::Type *GetTypeForDIE(const DWARFDIE &die); + lldb_private::Type *GetTypeForDIE(DWARFUnit *main_unit, + const DWARFDIE &die); - clang::Decl *GetClangDeclForDIE(const DWARFDIE &die); + clang::Decl *GetClangDeclForDIE(DWARFUnit *main_unit, + const DWARFDIE &die); - clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die); + clang::DeclContext *GetClangDeclContextForDIE(DWARFUnit *main_unit, + const DWARFDIE &die); - clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die, - DWARFDIE *decl_ctx_die); - lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &die); + clang::DeclContext * + GetClangDeclContextContainingDIE(DWARFUnit *main_unit, + const DWARFDIE &die, DWARFDIE *decl_ctx_die); + lldb_private::OptionalClangModuleID + GetOwningClangModule(DWARFUnit *main_unit, const DWARFDIE &die); - bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die, + bool CopyUniqueClassMethodTypes(DWARFUnit *main_unit, + const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die, lldb_private::Type *class_type, std::vector &failures); - clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die); + clang::DeclContext * + GetCachedClangDeclContextForDIE(DWARFUnit *main_unit, + const DWARFDIE &die); - void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die); + void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, + DWARFUnit *main_unit, const DWARFDIE &die); void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die); @@ -192,7 +217,8 @@ }; void - ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die, + ParseSingleMember(lldb_private::CompileUnit *comp_unit, DWARFUnit *main_unit, const DWARFDIE &die, + const DWARFDIE &parent_die, const lldb_private::CompilerType &class_clang_type, std::vector &member_accessibilities, lldb::AccessType default_accessibility, @@ -200,7 +226,7 @@ lldb_private::ClangASTImporter::LayoutInfo &layout_info, FieldInfo &last_field_info); - bool CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type, + bool CompleteRecordType(DWARFUnit *main_unit, const DWARFDIE &die, lldb_private::Type *type, lldb_private::CompilerType &clang_type); bool CompleteEnumType(const DWARFDIE &die, lldb_private::Type *type, lldb_private::CompilerType &clang_type); @@ -210,12 +236,15 @@ ParsedDWARFTypeAttributes &attrs); lldb::TypeSP ParseEnum(const lldb_private::SymbolContext &sc, const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs); - lldb::TypeSP ParseSubroutine(const DWARFDIE &die, + lldb::TypeSP ParseSubroutine(const lldb_private::SymbolContext &sc, + const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs); // FIXME: attrs should be passed as a const reference. - lldb::TypeSP ParseArrayType(const DWARFDIE &die, + lldb::TypeSP ParseArrayType(const lldb_private::SymbolContext &sc, + const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs); - lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die, + lldb::TypeSP ParsePointerToMemberType(const lldb_private::SymbolContext &sc, + const DWARFDIE &die, const ParsedDWARFTypeAttributes &attrs); }; 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 @@ -9,6 +9,7 @@ #include #include "DWARFASTParserClang.h" +#include "DWARFCompileUnit.h" #include "DWARFDebugInfo.h" #include "DWARFDeclContext.h" #include "DWARFDefines.h" @@ -148,6 +149,9 @@ if (!clang_module_sp) return TypeSP(); + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(&dwarf); + // If this type comes from a Clang module, recursively look in the // DWARF section of the .pcm file in the module cache. Clang // generates DWO skeleton units as breadcrumbs to find them. @@ -157,7 +161,7 @@ // 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(SymbolFileDWARF::GetLanguage(*die.GetMainDWARFUnit(main_unit))); llvm::DenseSet searched_symbol_files; clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, searched_symbol_files, pcm_types); @@ -208,23 +212,23 @@ if (pcm_type.IsDefined()) GetClangASTImporter().RequireCompleteType(ClangUtil::GetQualType(type)); - SymbolFileDWARF *dwarf = die.GetDWARF(); - TypeSP type_sp(new Type(die.GetID(), dwarf, pcm_type_sp->GetName(), - pcm_type_sp->GetByteSize(nullptr), nullptr, + TypeSP type_sp(new Type(die.GetID(main_unit), dwarf, pcm_type_sp->GetName(), + pcm_type_sp->GetByteSize(nullptr), sc.comp_unit, LLDB_INVALID_UID, Type::eEncodingInvalid, &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward, - TypePayloadClang(GetOwningClangModule(die)))); + TypePayloadClang(GetOwningClangModule(main_unit, die)))); dwarf->GetTypeList().Insert(type_sp); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = type_sp.get(); clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type); if (tag_decl) { - LinkDeclContextToDIE(tag_decl, die); + LinkDeclContextToDIE(tag_decl, main_unit, die); } else { - clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die); + clang::DeclContext *defn_decl_ctx = + GetCachedClangDeclContextForDIE(main_unit, die); if (defn_decl_ctx) - LinkDeclContextToDIE(defn_decl_ctx, die); + LinkDeclContextToDIE(defn_decl_ctx, main_unit, die); } return type_sp; @@ -446,11 +450,12 @@ Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS)); - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(&dwarf); if (log) { DWARFDIE context_die; clang::DeclContext *context = - GetClangDeclContextContainingDIE(die, &context_die); + GetClangDeclContextContainingDIE(main_unit, die, &context_die); dwarf->GetObjectFile()->GetModule()->LogMessage( log, @@ -460,23 +465,23 @@ die.GetTagAsCString(), die.GetName()); } - Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE()); + Type *type_ptr = dwarf->GetDIEToType().lookup(die.MainCUtoDIEPair(main_unit)); if (type_ptr == DIE_IS_BEING_PARSED) return nullptr; if (type_ptr) return type_ptr->shared_from_this(); // Set a bit that lets us know that we are currently parsing this - dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = DIE_IS_BEING_PARSED; ParsedDWARFTypeAttributes attrs(die); if (DWARFDIE signature_die = attrs.signature.Reference()) { if (TypeSP type_sp = ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) { - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = type_sp.get(); if (clang::DeclContext *decl_ctx = - GetCachedClangDeclContextForDIE(signature_die)) - LinkDeclContextToDIE(decl_ctx, die); + GetCachedClangDeclContextForDIE(main_unit, signature_die)) + LinkDeclContextToDIE(decl_ctx, main_unit, die); return type_sp; } return nullptr; @@ -519,15 +524,15 @@ case DW_TAG_inlined_subroutine: case DW_TAG_subprogram: case DW_TAG_subroutine_type: { - type_sp = ParseSubroutine(die, attrs); + type_sp = ParseSubroutine(sc, die, attrs); break; } case DW_TAG_array_type: { - type_sp = ParseArrayType(die, attrs); + type_sp = ParseArrayType(sc, die, attrs); break; } case DW_TAG_ptr_to_member_type: { - type_sp = ParsePointerToMemberType(die, attrs); + type_sp = ParsePointerToMemberType(sc, die, attrs); break; } default: @@ -550,9 +555,11 @@ ParsedDWARFTypeAttributes &attrs) { Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS)); - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(&dwarf); const dw_tag_t tag = die.Tag(); - LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU()); + LanguageType cu_language = + SymbolFileDWARF::GetLanguage(*die.GetMainDWARFUnit(main_unit)); Type::ResolveState resolve_state = Type::ResolveState::Unresolved; Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; TypeSP type_sp; @@ -563,7 +570,7 @@ // Type::ResolveCompilerType. PrepareContextToReceiveMembers( m_ast, GetClangASTImporter(), - GetClangDeclContextContainingDIE(die, nullptr), die, + GetClangDeclContextContainingDIE(main_unit, die, nullptr), die, attrs.name.GetCString()); if (attrs.type.IsValid()) { @@ -761,11 +768,12 @@ } type_sp = std::make_shared( - die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, - dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl, - clang_type, resolve_state, TypePayloadClang(GetOwningClangModule(die))); + die.GetID(main_unit), dwarf, attrs.name, attrs.byte_size, sc.comp_unit, + dwarf->GetUID(main_unit, attrs.type.Reference()), encoding_data_type, + &attrs.decl, clang_type, resolve_state, + TypePayloadClang(GetOwningClangModule(main_unit, die))); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = type_sp.get(); return type_sp; } @@ -774,16 +782,17 @@ ParsedDWARFTypeAttributes &attrs) { Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS)); - SymbolFileDWARF *dwarf = die.GetDWARF(); const dw_tag_t tag = die.Tag(); TypeSP type_sp; + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(&dwarf); if (attrs.is_forward_declaration) { type_sp = ParseTypeFromClangModule(sc, die, log); if (type_sp) return type_sp; - DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); + DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(main_unit, die); type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); @@ -811,11 +820,11 @@ // We found a real definition for this type elsewhere so lets use // it and cache the fact that we found a complete type for this // die - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - clang::DeclContext *defn_decl_ctx = - GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID())); + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = type_sp.get(); + clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE( + main_unit, dwarf->GetDIE(type_sp->GetID())); if (defn_decl_ctx) - LinkDeclContextToDIE(defn_decl_ctx, die); + LinkDeclContextToDIE(defn_decl_ctx, main_unit, die); return type_sp; } } @@ -824,12 +833,13 @@ CompilerType enumerator_clang_type; CompilerType clang_type; - clang_type.SetCompilerType( - &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE())); + clang_type.SetCompilerType(&m_ast, + dwarf->GetForwardDeclDieToClangType().lookup( + die.MainCUtoDIEPair(main_unit))); if (!clang_type) { if (attrs.type.IsValid()) { Type *enumerator_type = - dwarf->ResolveTypeUID(attrs.type.Reference(), true); + dwarf->ResolveTypeUID(main_unit, attrs.type.Reference(), true); if (enumerator_type) enumerator_clang_type = enumerator_type->GetFullCompilerType(); } @@ -844,20 +854,22 @@ } clang_type = m_ast.CreateEnumerationType( - attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr), - GetOwningClangModule(die), attrs.decl, enumerator_clang_type, + attrs.name.GetCString(), + GetClangDeclContextContainingDIE(main_unit, die, nullptr), + GetOwningClangModule(main_unit, die), attrs.decl, enumerator_clang_type, attrs.is_scoped_enum); } else { enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type); } - LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die); + LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), + main_unit, die); type_sp = std::make_shared( - die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, - dwarf->GetUID(attrs.type.Reference()), Type::eEncodingIsUID, &attrs.decl, - clang_type, Type::ResolveState::Forward, - TypePayloadClang(GetOwningClangModule(die))); + die.GetID(main_unit), dwarf, attrs.name, attrs.byte_size, sc.comp_unit, + dwarf->GetUID(main_unit, attrs.type.Reference()), Type::eEncodingIsUID, + &attrs.decl, clang_type, Type::ResolveState::Forward, + TypePayloadClang(GetOwningClangModule(main_unit, die))); if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { if (die.HasChildren()) { @@ -877,12 +889,14 @@ return type_sp; } -TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, - ParsedDWARFTypeAttributes &attrs) { +TypeSP DWARFASTParserClang::ParseSubroutine(const SymbolContext &sc, + const DWARFDIE &die, + ParsedDWARFTypeAttributes &attrs) { Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS)); - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(&dwarf); const dw_tag_t tag = die.Tag(); bool is_variadic = false; @@ -905,7 +919,7 @@ Type *func_type = NULL; if (attrs.type.IsValid()) - func_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true); + func_type = dwarf->ResolveTypeUID(main_unit, attrs.type.Reference(), true); if (func_type) return_clang_type = func_type->GetForwardCompilerType(); @@ -919,7 +933,7 @@ DWARFDIE decl_ctx_die; clang::DeclContext *containing_decl_ctx = - GetClangDeclContextContainingDIE(die, &decl_ctx_die); + GetClangDeclContextContainingDIE(main_unit, die, &decl_ctx_die); const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind(); @@ -933,10 +947,10 @@ if (die.HasChildren()) { bool skip_artificial = true; - ParseChildParameters(containing_decl_ctx, die, skip_artificial, is_static, - is_variadic, has_template_params, - function_param_types, function_param_decls, - type_quals); + ParseChildParameters(sc.comp_unit, containing_decl_ctx, main_unit, die, + skip_artificial, is_static, is_variadic, + has_template_params, function_param_types, + function_param_decls, type_quals); } bool ignore_containing_context = false; @@ -995,8 +1009,8 @@ attrs.is_objc_direct_call); type_handled = objc_method_decl != NULL; if (type_handled) { - LinkDeclContextToDIE(objc_method_decl, die); - m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + LinkDeclContextToDIE(objc_method_decl, main_unit, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID(main_unit)); } else { dwarf->GetObjectFile()->GetModule()->ReportError( "{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), " @@ -1008,10 +1022,10 @@ } else if (is_cxx_method) { // Look at the parent of this DIE and see if is is a class or // struct and see if this is actually a C++ method - Type *class_type = dwarf->ResolveType(decl_ctx_die); + Type *class_type = dwarf->ResolveType(main_unit, decl_ctx_die); if (class_type) { bool alternate_defn = false; - if (class_type->GetID() != decl_ctx_die.GetID() || + if (class_type->GetID() != decl_ctx_die.GetID(main_unit) || IsClangModuleFwdDecl(decl_ctx_die)) { alternate_defn = true; @@ -1023,15 +1037,16 @@ if (class_type_die) { std::vector failures; - CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, - class_type, failures); + CopyUniqueClassMethodTypes(main_unit, decl_ctx_die, + class_type_die, class_type, failures); // FIXME do something with these failures that's // smarter than just dropping them on the ground. // Unfortunately classes don't like having stuff added // to them after their definitions are complete... - Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + Type *type_ptr = + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)]; if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { return type_ptr->shared_from_this(); } @@ -1049,14 +1064,14 @@ // die. DWARFDIE spec_die = attrs.specification.Reference(); clang::DeclContext *spec_clang_decl_ctx = - GetClangDeclContextForDIE(spec_die); + GetClangDeclContextForDIE(main_unit, spec_die); if (spec_clang_decl_ctx) { - LinkDeclContextToDIE(spec_clang_decl_ctx, die); + LinkDeclContextToDIE(spec_clang_decl_ctx, main_unit, die); } else { dwarf->GetObjectFile()->GetModule()->ReportWarning( "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x" ") has no decl\n", - die.GetID(), spec_die.GetOffset()); + die.GetID(main_unit), spec_die.GetOffset()); } type_handled = true; } else if (attrs.abstract_origin.IsValid()) { @@ -1068,14 +1083,14 @@ DWARFDIE abs_die = attrs.abstract_origin.Reference(); clang::DeclContext *abs_clang_decl_ctx = - GetClangDeclContextForDIE(abs_die); + GetClangDeclContextForDIE(main_unit, abs_die); if (abs_clang_decl_ctx) { - LinkDeclContextToDIE(abs_clang_decl_ctx, die); + LinkDeclContextToDIE(abs_clang_decl_ctx, main_unit, die); } else { dwarf->GetObjectFile()->GetModule()->ReportWarning( "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x" ") has no decl\n", - die.GetID(), abs_die.GetOffset()); + die.GetID(main_unit), abs_die.GetOffset()); } type_handled = true; } else { @@ -1108,7 +1123,7 @@ if (method_decl->getType() == ClangUtil::GetQualType(clang_type)) { add_method = false; - LinkDeclContextToDIE(method_decl, die); + LinkDeclContextToDIE(method_decl, main_unit, die); type_handled = true; break; @@ -1123,7 +1138,8 @@ "SymbolFileDWARF::ParseType() is adding a method " "%s to class %s in DIE 0x%8.8" PRIx64 " from %s", attrs.name.GetCString(), - class_type->GetName().GetCString(), die.GetID(), + class_type->GetName().GetCString(), + die.GetID(main_unit), dwarf->GetObjectFile() ->GetFileSpec() .GetPath() @@ -1150,10 +1166,10 @@ type_handled |= attrs.is_artificial; if (cxx_method_decl) { - LinkDeclContextToDIE(cxx_method_decl, die); + LinkDeclContextToDIE(cxx_method_decl, main_unit, die); ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); + metadata.SetUserID(die.GetID(main_unit)); if (!object_pointer_name.empty()) { metadata.SetObjectPtrName( @@ -1181,7 +1197,7 @@ // we need to modify the dwarf->GetDIEToType() so it // doesn't think we are trying to parse this DIE // anymore... - dwarf->GetDIEToType()[die.GetDIE()] = NULL; + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = NULL; // Now we get the full type to force our class type to // complete itself using the clang::ExternalASTSource @@ -1191,7 +1207,8 @@ // The type for this DIE should have been filled in the // function call above - Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + Type *type_ptr = + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)]; if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { return type_ptr->shared_from_this(); } @@ -1215,12 +1232,12 @@ if (attrs.abstract_origin.IsValid()) { DWARFDIE abs_die = attrs.abstract_origin.Reference(); - if (dwarf->ResolveType(abs_die)) { + if (dwarf->ResolveType(main_unit, abs_die)) { function_decl = llvm::dyn_cast_or_null( - GetCachedClangDeclContextForDIE(abs_die)); + GetCachedClangDeclContextForDIE(main_unit, abs_die)); if (function_decl) { - LinkDeclContextToDIE(function_decl, die); + LinkDeclContextToDIE(function_decl, main_unit, die); } } } @@ -1241,20 +1258,20 @@ function_decl = m_ast.CreateFunctionDeclaration( ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, - GetOwningClangModule(die), name, clang_type, attrs.storage, - attrs.is_inline); + GetOwningClangModule(main_unit, die), name, clang_type, + attrs.storage, attrs.is_inline); if (has_template_params) { TypeSystemClang::TemplateParameterInfos template_param_infos; - ParseTemplateParameterInfos(die, template_param_infos); + ParseTemplateParameterInfos(main_unit, die, template_param_infos); template_function_decl = m_ast.CreateFunctionDeclaration( ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, - GetOwningClangModule(die), attrs.name.GetStringRef(), clang_type, + GetOwningClangModule(main_unit, die), attrs.name.GetStringRef(), clang_type, attrs.storage, attrs.is_inline); clang::FunctionTemplateDecl *func_template_decl = m_ast.CreateFunctionTemplateDecl( - containing_decl_ctx, GetOwningClangModule(die), + containing_decl_ctx, GetOwningClangModule(main_unit, die), template_function_decl, template_param_infos); m_ast.CreateFunctionTemplateSpecializationInfo( template_function_decl, func_template_decl, template_param_infos); @@ -1263,7 +1280,7 @@ lldbassert(function_decl); if (function_decl) { - LinkDeclContextToDIE(function_decl, die); + LinkDeclContextToDIE(function_decl, main_unit, die); if (!function_param_decls.empty()) { m_ast.SetFunctionParameters(function_decl, @@ -1276,7 +1293,7 @@ } ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); + metadata.SetUserID(die.GetID(main_unit)); if (!object_pointer_name.empty()) { metadata.SetObjectPtrName(object_pointer_name.c_str()); @@ -1291,20 +1308,22 @@ } } } - return std::make_shared( - die.GetID(), dwarf, attrs.name, llvm::None, nullptr, LLDB_INVALID_UID, - Type::eEncodingIsUID, &attrs.decl, clang_type, Type::ResolveState::Full); + return std::make_shared(die.GetID(main_unit), dwarf, attrs.name, + llvm::None, sc.comp_unit, LLDB_INVALID_UID, + Type::eEncodingIsUID, &attrs.decl, clang_type, + Type::ResolveState::Full); } -TypeSP DWARFASTParserClang::ParseArrayType(const DWARFDIE &die, +TypeSP DWARFASTParserClang::ParseArrayType(const SymbolContext &sc, + const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(&dwarf); DWARFDIE type_die = attrs.type.Reference(); - Type *element_type = dwarf->ResolveTypeUID(type_die, true); + Type *element_type = dwarf->ResolveTypeUID(main_unit, type_die, true); if (!element_type) return nullptr; @@ -1340,21 +1359,24 @@ } ConstString empty_name; TypeSP type_sp = std::make_shared( - die.GetID(), dwarf, empty_name, array_element_bit_stride / 8, nullptr, - dwarf->GetUID(type_die), Type::eEncodingIsUID, &attrs.decl, clang_type, - Type::ResolveState::Full); + die.GetID(main_unit), dwarf, empty_name, array_element_bit_stride / 8, + sc.comp_unit, dwarf->GetUID(main_unit, type_die), Type::eEncodingIsUID, + &attrs.decl, clang_type, Type::ResolveState::Full); type_sp->SetEncodingType(element_type); const clang::Type *type = ClangUtil::GetQualType(clang_type).getTypePtr(); - m_ast.SetMetadataAsUserID(type, die.GetID()); + m_ast.SetMetadataAsUserID(type, die.GetID(main_unit)); return type_sp; } TypeSP DWARFASTParserClang::ParsePointerToMemberType( - const DWARFDIE &die, const ParsedDWARFTypeAttributes &attrs) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - Type *pointee_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true); + const SymbolContext &sc, const DWARFDIE &die, + const ParsedDWARFTypeAttributes &attrs) { + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(&dwarf); + Type *pointee_type = + dwarf->ResolveTypeUID(main_unit, attrs.type.Reference(), true); Type *class_type = - dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true); + dwarf->ResolveTypeUID(main_unit, attrs.containing_type.Reference(), true); CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType(); CompilerType class_clang_type = class_type->GetLayoutCompilerType(); @@ -1363,12 +1385,11 @@ class_clang_type, pointee_clang_type); if (llvm::Optional clang_type_size = - clang_type.GetByteSize(nullptr)) { - return std::make_shared(die.GetID(), dwarf, attrs.name, - *clang_type_size, nullptr, LLDB_INVALID_UID, - Type::eEncodingIsUID, nullptr, clang_type, - Type::ResolveState::Forward); - } + clang_type.GetByteSize(nullptr)) + return std::make_shared( + die.GetID(main_unit), dwarf, attrs.name, *clang_type_size, sc.comp_unit, + LLDB_INVALID_UID, Type::eEncodingIsUID, nullptr, clang_type, + Type::ResolveState::Forward); return nullptr; } @@ -1377,7 +1398,8 @@ if (!type_sp) return type_sp; - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(&dwarf); TypeList &type_list = dwarf->GetTypeList(); DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die); dw_tag_t sc_parent_tag = sc_parent_die.Tag(); @@ -1387,13 +1409,16 @@ sc_parent_tag == DW_TAG_partial_unit) { symbol_context_scope = sc.comp_unit; } else if (sc.function != nullptr && sc_parent_die) { - symbol_context_scope = - sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); + symbol_context_scope = sc.function->GetBlock(true).FindBlockByID( + sc_parent_die.GetID(main_unit)); if (symbol_context_scope == nullptr) symbol_context_scope = sc.function; + } else if (sc.comp_unit) { + symbol_context_scope = sc.comp_unit; } else { symbol_context_scope = sc.module_sp.get(); } + lldbassert(symbol_context_scope); if (symbol_context_scope != nullptr) type_sp->SetSymbolContextScope(symbol_context_scope); @@ -1402,7 +1427,7 @@ // level. type_list.Insert(type_sp); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = type_sp.get(); return type_sp; } @@ -1413,8 +1438,9 @@ TypeSP type_sp; CompilerType clang_type; const dw_tag_t tag = die.Tag(); - SymbolFileDWARF *dwarf = die.GetDWARF(); - LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU()); + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(&dwarf); + LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetMainDWARFUnit(main_unit)); Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS); @@ -1439,13 +1465,14 @@ } if (dwarf->GetUniqueDWARFASTTypeMap().Find( - unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1), + unique_typename, main_unit, die, unique_decl, attrs.byte_size.getValueOr(-1), *unique_ast_entry_up)) { type_sp = unique_ast_entry_up->m_type_sp; if (type_sp) { - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - LinkDeclContextToDIE( - GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die); + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = type_sp.get(); + LinkDeclContextToDIE(GetCachedClangDeclContextForDIE( + main_unit, unique_ast_entry_up->m_die), + main_unit, die); return type_sp; } } @@ -1519,7 +1546,7 @@ // We found a real definition for this type elsewhere so lets use // it and cache the fact that we found a complete type for this // die - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = type_sp.get(); return type_sp; } } @@ -1546,7 +1573,7 @@ if (type_sp) return type_sp; - DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); + DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(main_unit, die); // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, // type_name_const_str); @@ -1575,21 +1602,24 @@ // We found a real definition for this type elsewhere so lets use // it and cache the fact that we found a complete type for this die - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = type_sp.get(); + DWARFUnit *type_main_unit; + DWARFDIE type_die = dwarf->GetDIEUnlocked(type_sp->GetID(), &type_main_unit); clang::DeclContext *defn_decl_ctx = - GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID())); + GetCachedClangDeclContextForDIE(type_main_unit, type_die); if (defn_decl_ctx) - LinkDeclContextToDIE(defn_decl_ctx, die); + LinkDeclContextToDIE(defn_decl_ctx, main_unit, die); return type_sp; } } assert(tag_decl_kind != -1); bool clang_type_was_created = false; - clang_type.SetCompilerType( - &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE())); + clang_type.SetCompilerType(&m_ast, + dwarf->GetForwardDeclDieToClangType().lookup( + die.MainCUtoDIEPair(main_unit))); if (!clang_type) { clang::DeclContext *decl_ctx = - GetClangDeclContextContainingDIE(die, nullptr); + GetClangDeclContextContainingDIE(main_unit, die, nullptr); PrepareContextToReceiveMembers(m_ast, GetClangASTImporter(), decl_ctx, die, attrs.name.GetCString()); @@ -1603,16 +1633,17 @@ } ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); + metadata.SetUserID(die.GetID(main_unit)); metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die)); if (attrs.name.GetStringRef().contains('<')) { TypeSystemClang::TemplateParameterInfos template_param_infos; - if (ParseTemplateParameterInfos(die, template_param_infos)) { + if (ParseTemplateParameterInfos(main_unit, die, template_param_infos)) { clang::ClassTemplateDecl *class_template_decl = m_ast.ParseClassTemplateDecl( - decl_ctx, GetOwningClangModule(die), attrs.accessibility, - attrs.name.GetCString(), tag_decl_kind, template_param_infos); + decl_ctx, GetOwningClangModule(main_unit, die), + attrs.accessibility, attrs.name.GetCString(), tag_decl_kind, + template_param_infos); if (!class_template_decl) { if (log) { dwarf->GetObjectFile()->GetModule()->LogMessage( @@ -1627,8 +1658,8 @@ clang::ClassTemplateSpecializationDecl *class_specialization_decl = m_ast.CreateClassTemplateSpecializationDecl( - decl_ctx, GetOwningClangModule(die), class_template_decl, - tag_decl_kind, template_param_infos); + decl_ctx, GetOwningClangModule(main_unit, die), + class_template_decl, tag_decl_kind, template_param_infos); clang_type = m_ast.CreateClassTemplateSpecializationType( class_specialization_decl); clang_type_was_created = true; @@ -1641,7 +1672,7 @@ if (!clang_type_was_created) { clang_type_was_created = true; clang_type = m_ast.CreateRecordType( - decl_ctx, GetOwningClangModule(die), attrs.accessibility, + decl_ctx, GetOwningClangModule(main_unit, die), attrs.accessibility, attrs.name.GetCString(), tag_decl_kind, attrs.class_language, &metadata, attrs.exports_symbols); } @@ -1650,9 +1681,9 @@ // Store a forward declaration to this class type in case any // parameters in any class methods need it for the clang types for // function prototypes. - LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die); + LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), main_unit, die); type_sp = std::make_shared( - die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, + die.GetID(main_unit), dwarf, attrs.name, attrs.byte_size, sc.comp_unit, LLDB_INVALID_UID, Type::eEncodingIsUID, &attrs.decl, clang_type, Type::ResolveState::Forward, TypePayloadClang(OptionalClangModuleID(), attrs.is_complete_objc_class)); @@ -1661,6 +1692,7 @@ // copies of the same type over and over in the ASTContext for our // module unique_ast_entry_up->m_type_sp = type_sp; + unique_ast_entry_up->m_main_unit = main_unit; unique_ast_entry_up->m_die = die; unique_ast_entry_up->m_declaration = unique_decl; unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0); @@ -1719,11 +1751,11 @@ // Can't assume m_ast.GetSymbolFile() is actually a // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple // binaries. - dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = + dwarf->GetForwardDeclDieToClangType()[die.MainCUtoDIEPair(main_unit)] = clang_type.GetOpaqueQualType(); dwarf->GetForwardDeclClangTypeToDie().try_emplace( ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(), - *die.GetDIERef()); + die.GetID(main_unit)); m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); } } @@ -1813,7 +1845,7 @@ }; bool DWARFASTParserClang::ParseTemplateDIE( - const DWARFDIE &die, + DWARFUnit *main_unit, const DWARFDIE &die, TypeSystemClang::TemplateParameterInfos &template_param_infos) { const dw_tag_t tag = die.Tag(); bool is_template_template_argument = false; @@ -1824,7 +1856,8 @@ std::make_unique(); for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); child_die = child_die.GetSibling()) { - if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args)) + if (!ParseTemplateDIE(main_unit, child_die, + *template_param_infos.packed_args)) return false; } if (const char *name = die.GetName()) { @@ -1862,7 +1895,8 @@ case DW_AT_type: if (attributes.ExtractFormValueAtIndex(i, form_value)) { - Type *lldb_type = die.ResolveTypeUID(form_value.Reference()); + Type *lldb_type = + die.ResolveTypeUID(main_unit, form_value.Reference()); if (lldb_type) clang_type = lldb_type->GetForwardCompilerType(); } @@ -1922,7 +1956,7 @@ } bool DWARFASTParserClang::ParseTemplateParameterInfos( - const DWARFDIE &parent_die, + DWARFUnit *main_unit, const DWARFDIE &parent_die, TypeSystemClang::TemplateParameterInfos &template_param_infos) { if (!parent_die) @@ -1937,7 +1971,7 @@ case DW_TAG_template_value_parameter: case DW_TAG_GNU_template_parameter_pack: case DW_TAG_GNU_template_template_param: - ParseTemplateDIE(die, template_param_infos); + ParseTemplateDIE(main_unit, die, template_param_infos); break; default: @@ -1947,11 +1981,17 @@ return template_param_infos.args.size() == template_param_infos.names.size(); } -bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, +bool DWARFASTParserClang::CompleteRecordType(DWARFUnit *main_unit, const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type) { const dw_tag_t tag = die.Tag(); - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf = &main_unit->GetSymbolFileDWARF(); + CompileUnit *comp_unit = + type->GetSymbolContextScope()->CalculateSymbolContextCompileUnit(); + // comp_unit may be a CU with DIE being only declaration. + // Then 'die' will be a definition in a different CU with different 'main_unit'. + // This assertion will therefore not work: + // lldbassert(&sc.GetDWARFCompileUnit(&dwarf)->GetNonSkeletonUnit() == sc.GetDWARFCompileUnit(&dwarf)); ClangASTImporter::LayoutInfo layout_info; @@ -1984,21 +2024,22 @@ std::vector member_function_dies; DelayedPropertyList delayed_properties; - ParseChildMembers(die, clang_type, bases, member_accessibilities, + ParseChildMembers(comp_unit, main_unit, die, clang_type, bases, member_accessibilities, member_function_dies, delayed_properties, default_accessibility, is_a_class, layout_info); // Now parse any methods if there were any... for (const DWARFDIE &die : member_function_dies) - dwarf->ResolveType(die); + dwarf->ResolveType(main_unit, die); if (type_is_objc_object_or_interface) { ConstString class_name(clang_type.GetTypeName()); if (class_name) { - dwarf->GetObjCMethods(class_name, [&](DWARFDIE method_die) { - method_die.ResolveType(); - return true; - }); + dwarf->GetObjCMethods( + class_name, [&](DWARFUnit *main_unit, DWARFDIE method_die) { + method_die.ResolveType(main_unit); + return true; + }); for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end(); @@ -2084,10 +2125,10 @@ return (bool)clang_type; } -bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, +bool DWARFASTParserClang::CompleteTypeFromDWARF(DWARFUnit *main_unit, const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type) { - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf = &main_unit->GetSymbolFileDWARF(); std::lock_guard guard( dwarf->GetObjectFile()->GetModule()->GetMutex()); @@ -2106,14 +2147,14 @@ if (log) dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace( log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", - die.GetID(), die.GetTagAsCString(), type->GetName().AsCString()); + die.GetID(main_unit), die.GetTagAsCString(), type->GetName().AsCString()); assert(clang_type); DWARFAttributes attributes; switch (tag) { case DW_TAG_structure_type: case DW_TAG_union_type: case DW_TAG_class_type: - return CompleteRecordType(die, type, clang_type); + return CompleteRecordType(main_unit, die, type, clang_type); case DW_TAG_enumeration_type: return CompleteEnumType(die, type, clang_type); default: @@ -2130,31 +2171,37 @@ (clang::DeclContext *)decl_context.GetOpaqueDeclContext(); for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx); 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; + it = m_decl_ctx_to_die.erase(it)) { + DWARFUnit *main_unit = it->second.first; + for (DWARFDIE decl = it->second.second.GetFirstChild(); decl; decl = decl.GetSibling()) - GetClangDeclForDIE(decl); + GetClangDeclForDIE(main_unit, decl); + } } -CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) { - clang::Decl *clang_decl = GetClangDeclForDIE(die); +CompilerDecl +DWARFASTParserClang::GetDeclForUIDFromDWARF(DWARFUnit *main_unit, + const DWARFDIE &die) { + clang::Decl *clang_decl = GetClangDeclForDIE(main_unit, die); if (clang_decl != nullptr) return m_ast.GetCompilerDecl(clang_decl); return CompilerDecl(); } CompilerDeclContext -DWARFASTParserClang::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) { - clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE(die); +DWARFASTParserClang::GetDeclContextForUIDFromDWARF(DWARFUnit *main_unit, + const DWARFDIE &die) { + clang::DeclContext *clang_decl_ctx = + GetClangDeclContextForDIE(main_unit, die); if (clang_decl_ctx) return m_ast.CreateDeclContext(clang_decl_ctx); return CompilerDeclContext(); } -CompilerDeclContext -DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) { +CompilerDeclContext DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF( + DWARFUnit *main_unit, const DWARFDIE &die) { clang::DeclContext *clang_decl_ctx = - GetClangDeclContextContainingDIE(die, nullptr); + GetClangDeclContextContainingDIE(main_unit, die, nullptr); if (clang_decl_ctx) return m_ast.CreateDeclContext(clang_decl_ctx); return CompilerDeclContext(); @@ -2263,15 +2310,17 @@ } if (func_range.GetBaseAddress().IsValid()) { + DWARFUnit *main_unit = comp_unit.GetDWARFCompileUnit(); + SymbolFileDWARF *dwarf = &main_unit->GetSymbolFileDWARF(); Mangled func_name; if (mangled) 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())) && + SymbolFileDWARF::GetLanguage(*die.GetMainDWARFUnit(main_unit))) && !Language::LanguageIsObjC( - SymbolFileDWARF::GetLanguage(*die.GetCU())) && + SymbolFileDWARF::GetLanguage(*die.GetMainDWARFUnit(main_unit))) && 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 @@ -2284,14 +2333,14 @@ std::vector param_decls; StreamString sstr; - DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); + DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(main_unit, die); sstr << decl_ctx.GetQualifiedName(); clang::DeclContext *containing_decl_ctx = - GetClangDeclContextContainingDIE(die, nullptr); - ParseChildParameters(containing_decl_ctx, die, true, is_static, - is_variadic, has_template_params, param_types, - param_decls, type_quals); + GetClangDeclContextContainingDIE(main_unit, die, nullptr); + ParseChildParameters(&comp_unit, containing_decl_ctx, main_unit, die, true, + is_static, is_variadic, has_template_params, + param_types, param_decls, type_quals); sstr << "("; for (size_t i = 0; i < param_types.size(); i++) { if (i > 0) @@ -2314,14 +2363,14 @@ decl_up = std::make_unique(die.GetCU()->GetFile(decl_file), decl_line, decl_column); - SymbolFileDWARF *dwarf = die.GetDWARF(); // Supply the type _only_ if it has already been parsed - Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE()); + Type *func_type = + dwarf->GetDIEToType().lookup(die.MainCUtoDIEPair(main_unit)); assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED); if (dwarf->FixupAddress(func_range.GetBaseAddress())) { - const user_id_t func_user_id = die.GetID(); + const user_id_t func_user_id = die.GetID(main_unit); func_sp = std::make_shared(&comp_unit, func_user_id, // UserID is the DIE offset @@ -2340,8 +2389,7 @@ return nullptr; } -void DWARFASTParserClang::ParseSingleMember( - const DWARFDIE &die, const DWARFDIE &parent_die, +void DWARFASTParserClang::ParseSingleMember(lldb_private::CompileUnit *comp_unit, DWARFUnit *main_unit, const DWARFDIE &die, const DWARFDIE &parent_die, const lldb_private::CompilerType &class_clang_type, std::vector &member_accessibilities, lldb::AccessType default_accessibility, @@ -2527,7 +2575,7 @@ // Handle static members if (is_external && member_byte_offset == UINT32_MAX) { - Type *var_type = die.ResolveTypeUID(encoding_form.Reference()); + Type *var_type = die.ResolveTypeUID(main_unit, encoding_form.Reference()); if (var_type) { if (accessibility == eAccessNone) @@ -2540,7 +2588,7 @@ } if (!is_artificial) { - Type *member_type = die.ResolveTypeUID(encoding_form.Reference()); + Type *member_type = die.ResolveTypeUID(main_unit, encoding_form.Reference()); clang::FieldDecl *field_decl = nullptr; const uint64_t character_width = 8; @@ -2594,7 +2642,7 @@ "bit offset (0x%8.8" PRIx64 ") member will be ignored. Please file a bug against the " "compiler and include the preprocessed output for %s\n", - die.GetID(), DW_TAG_value_to_name(tag), name, + die.GetID(main_unit), DW_TAG_value_to_name(tag), name, this_field_info.bit_offset, GetUnitName(parent_die).c_str()); return; } @@ -2703,8 +2751,8 @@ "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x" " which extends beyond the bounds of 0x%8.8" PRIx64, - die.GetID(), name, encoding_form.Reference().GetOffset(), - parent_die.GetID()); + die.GetID(main_unit), name, encoding_form.Reference().GetOffset(), + parent_die.GetID(main_unit)); } member_clang_type = @@ -2719,7 +2767,7 @@ class_clang_type, name, member_clang_type, accessibility, bit_size); - m_ast.SetMetadataAsUserID(field_decl, die.GetID()); + m_ast.SetMetadataAsUserID(field_decl, die.GetID(main_unit)); layout_info.field_offsets.insert( std::make_pair(field_decl, field_bit_offset)); @@ -2728,12 +2776,12 @@ module_sp->ReportError( "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x" " which was unable to be parsed", - die.GetID(), name, encoding_form.Reference().GetOffset()); + die.GetID(main_unit), name, encoding_form.Reference().GetOffset()); else module_sp->ReportError( "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x" " which was unable to be parsed", - die.GetID(), encoding_form.Reference().GetOffset()); + die.GetID(main_unit), encoding_form.Reference().GetOffset()); } } @@ -2746,19 +2794,20 @@ } ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); + metadata.SetUserID(die.GetID(main_unit)); delayed_properties.push_back(DelayedAddObjCClassProperty( class_clang_type, prop_name, member_type->GetLayoutCompilerType(), ivar_decl, prop_setter_name, prop_getter_name, prop_attributes, &metadata)); if (ivar_decl) - m_ast.SetMetadataAsUserID(ivar_decl, die.GetID()); + m_ast.SetMetadataAsUserID(ivar_decl, die.GetID(main_unit)); } } } bool DWARFASTParserClang::ParseChildMembers( + CompileUnit *comp_unit, DWARFUnit *main_unit, const DWARFDIE &parent_die, CompilerType &class_clang_type, std::vector> &base_classes, std::vector &member_accessibilities, @@ -2783,7 +2832,7 @@ switch (tag) { case DW_TAG_member: case DW_TAG_APPLE_property: - ParseSingleMember(die, parent_die, class_clang_type, + ParseSingleMember(comp_unit, main_unit, die, parent_die, class_clang_type, member_accessibilities, default_accessibility, delayed_properties, layout_info, last_field_info); break; @@ -2857,7 +2906,8 @@ } } - Type *base_class_type = die.ResolveTypeUID(encoding_form.Reference()); + Type *base_class_type = + die.ResolveTypeUID(main_unit, encoding_form.Reference()); if (base_class_type == nullptr) { module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to " "resolve the base class at 0x%8.8x" @@ -2917,9 +2967,11 @@ } size_t DWARFASTParserClang::ParseChildParameters( - clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die, - bool skip_artificial, bool &is_static, bool &is_variadic, - bool &has_template_params, std::vector &function_param_types, + CompileUnit *comp_unit, clang::DeclContext *containing_decl_ctx, + DWARFUnit *main_unit, + const DWARFDIE &parent_die, bool skip_artificial, bool &is_static, + bool &is_variadic, bool &has_template_params, + std::vector &function_param_types, std::vector &function_param_decls, unsigned &type_quals) { if (!parent_die) @@ -2982,7 +3034,7 @@ // the formal parameter DIE... (name == nullptr || ::strcmp(name, "this") == 0)) { Type *this_type = - die.ResolveTypeUID(param_type_die_form.Reference()); + die.ResolveTypeUID(main_unit, param_type_die_form.Reference()); if (this_type) { uint32_t encoding_mask = this_type->GetEncodingMask(); if (encoding_mask & Type::eEncodingIsPointerUID) { @@ -2999,18 +3051,19 @@ } if (!skip) { - Type *type = die.ResolveTypeUID(param_type_die_form.Reference()); + Type *type = + die.ResolveTypeUID(main_unit, param_type_die_form.Reference()); if (type) { function_param_types.push_back(type->GetForwardCompilerType()); clang::ParmVarDecl *param_var_decl = m_ast.CreateParameterDeclaration( - containing_decl_ctx, GetOwningClangModule(die), name, - type->GetForwardCompilerType(), storage); + containing_decl_ctx, GetOwningClangModule(main_unit, die), + name, type->GetForwardCompilerType(), storage); assert(param_var_decl); function_param_decls.push_back(param_var_decl); - m_ast.SetMetadataAsUserID(param_var_decl, die.GetID()); + m_ast.SetMetadataAsUserID(param_var_decl, die.GetID(main_unit)); } } } @@ -3133,9 +3186,11 @@ return array_info; } -Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) { +Type *DWARFASTParserClang::GetTypeForDIE(DWARFUnit *main_unit, + const DWARFDIE &die) { if (die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf = + &die.GetMainDWARFUnit(main_unit)->GetSymbolFileDWARF(); DWARFAttributes attributes; const size_t num_attributes = die.GetAttributes(attributes); if (num_attributes > 0) { @@ -3146,7 +3201,7 @@ if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value)) - return dwarf->ResolveTypeUID(form_value.Reference(), true); + return dwarf->ResolveTypeUID(main_unit, form_value.Reference(), true); } } } @@ -3154,7 +3209,9 @@ return nullptr; } -clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { +clang::Decl * +DWARFASTParserClang::GetClangDeclForDIE(DWARFUnit *main_unit, + const DWARFDIE &die) { if (!die) return nullptr; @@ -3169,52 +3226,54 @@ return nullptr; } - DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE()); + auto diepair = die.MainCUtoDIEPair(main_unit); + DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(diepair); if (cache_pos != m_die_to_decl.end()) return cache_pos->second; if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) { - clang::Decl *decl = GetClangDeclForDIE(spec_die); - m_die_to_decl[die.GetDIE()] = decl; - m_decl_to_die[decl].insert(die.GetDIE()); + clang::Decl *decl = GetClangDeclForDIE(main_unit, spec_die); + m_die_to_decl[diepair] = decl; + m_decl_to_die[decl].insert(diepair); return decl; } if (DWARFDIE abstract_origin_die = die.GetReferencedDIE(DW_AT_abstract_origin)) { - clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die); - m_die_to_decl[die.GetDIE()] = decl; - m_decl_to_die[decl].insert(die.GetDIE()); + clang::Decl *decl = GetClangDeclForDIE(main_unit, abstract_origin_die); + m_die_to_decl[diepair] = decl; + m_decl_to_die[decl].insert(diepair); return decl; } + SymbolFileDWARF *dwarf = &die.GetMainDWARFUnit(main_unit)->GetSymbolFileDWARF(); + clang::Decl *decl = nullptr; switch (die.Tag()) { case DW_TAG_variable: case DW_TAG_constant: case DW_TAG_formal_parameter: { - SymbolFileDWARF *dwarf = die.GetDWARF(); - Type *type = GetTypeForDIE(die); + Type *type = GetTypeForDIE(main_unit, die); if (dwarf && type) { const char *name = die.GetName(); clang::DeclContext *decl_context = TypeSystemClang::DeclContextGetAsDeclContext( - dwarf->GetDeclContextContainingUID(die.GetID())); + dwarf->GetDeclContextContainingUID(die.GetID(main_unit))); decl = m_ast.CreateVariableDeclaration( - decl_context, GetOwningClangModule(die), name, + decl_context, GetOwningClangModule(main_unit, die), name, ClangUtil::GetQualType(type->GetForwardCompilerType())); } 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); + CompilerDecl imported_decl = + SymbolFileDWARF::GetDecl(main_unit, imported_uid); if (imported_decl) { clang::DeclContext *decl_context = TypeSystemClang::DeclContextGetAsDeclContext( - dwarf->GetDeclContextContainingUID(die.GetID())); + dwarf->GetDeclContextContainingUID(die.GetID(main_unit))); if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast( (clang::Decl *)imported_decl.GetOpaqueDecl())) @@ -3225,16 +3284,15 @@ break; } case DW_TAG_imported_module: { - SymbolFileDWARF *dwarf = die.GetDWARF(); DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); if (imported_uid) { CompilerDeclContext imported_decl_ctx = - SymbolFileDWARF::GetDeclContext(imported_uid); + SymbolFileDWARF::GetDeclContext(main_unit, imported_uid); if (imported_decl_ctx) { clang::DeclContext *decl_context = TypeSystemClang::DeclContextGetAsDeclContext( - dwarf->GetDeclContextContainingUID(die.GetID())); + dwarf->GetDeclContextContainingUID(die.GetID(main_unit))); if (clang::NamespaceDecl *ns_decl = TypeSystemClang::DeclContextGetAsNamespaceDecl( imported_decl_ctx)) @@ -3248,16 +3306,18 @@ break; } - m_die_to_decl[die.GetDIE()] = decl; - m_decl_to_die[decl].insert(die.GetDIE()); + m_die_to_decl[diepair] = decl; + m_decl_to_die[decl].insert(diepair); return decl; } clang::DeclContext * -DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) { +DWARFASTParserClang::GetClangDeclContextForDIE(DWARFUnit *main_unit, + const DWARFDIE &die) { if (die) { - clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(die); + clang::DeclContext *decl_ctx = + GetCachedClangDeclContextForDIE(main_unit, die); if (decl_ctx) return decl_ctx; @@ -3270,12 +3330,12 @@ break; case DW_TAG_namespace: - decl_ctx = ResolveNamespaceDIE(die); + decl_ctx = ResolveNamespaceDIE(main_unit, die); try_parsing_type = false; break; case DW_TAG_lexical_block: - decl_ctx = GetDeclContextForBlock(die); + decl_ctx = GetDeclContextForBlock(main_unit, die); try_parsing_type = false; break; @@ -3284,13 +3344,15 @@ } if (decl_ctx == nullptr && try_parsing_type) { - Type *type = die.GetDWARF()->ResolveType(die); + Type *type = + die.GetMainDWARFUnit(main_unit)->GetSymbolFileDWARF().ResolveType( + main_unit, die); if (type) - decl_ctx = GetCachedClangDeclContextForDIE(die); + decl_ctx = GetCachedClangDeclContextForDIE(main_unit, die); } if (decl_ctx) { - LinkDeclContextToDIE(decl_ctx, die); + LinkDeclContextToDIE(decl_ctx, main_unit, die); return decl_ctx; } } @@ -3298,7 +3360,8 @@ } OptionalClangModuleID -DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) { +DWARFASTParserClang::GetOwningClangModule(DWARFUnit *main_unit, + const DWARFDIE &die) { if (!die.IsValid()) return {}; @@ -3307,16 +3370,16 @@ const dw_tag_t tag = parent.Tag(); if (tag == DW_TAG_module) { DWARFDIE module_die = parent; - auto it = m_die_to_module.find(module_die.GetDIE()); + auto it = m_die_to_module.find(module_die.MainCUtoDIEPair(main_unit)); if (it != m_die_to_module.end()) return it->second; const char *name = module_die.GetAttributeValueAsString(DW_AT_name, 0); if (!name) return {}; - OptionalClangModuleID id = - m_ast.GetOrCreateClangModule(name, GetOwningClangModule(module_die)); - m_die_to_module.insert({module_die.GetDIE(), id}); + OptionalClangModuleID id = m_ast.GetOrCreateClangModule( + name, GetOwningClangModule(main_unit, module_die)); + m_die_to_module.insert({module_die.MainCUtoDIEPair(main_unit), id}); return id; } } @@ -3372,34 +3435,37 @@ } clang::DeclContext * -DWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die) { +DWARFASTParserClang::GetDeclContextForBlock(DWARFUnit *main_unit, + const DWARFDIE &die) { assert(die.Tag() == DW_TAG_lexical_block); DWARFDIE containing_function_with_abstract_origin = GetContainingFunctionWithAbstractOrigin(die); if (!containing_function_with_abstract_origin) { - return (clang::DeclContext *)ResolveBlockDIE(die); + return (clang::DeclContext *)ResolveBlockDIE(main_unit, die); } DWARFDIE child = FindFirstChildWithAbstractOrigin( die, containing_function_with_abstract_origin); CompilerDeclContext decl_context = - GetDeclContextContainingUIDFromDWARF(child); + GetDeclContextContainingUIDFromDWARF(main_unit, child); return (clang::DeclContext *)decl_context.GetOpaqueDeclContext(); } -clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) { +clang::BlockDecl * +DWARFASTParserClang::ResolveBlockDIE(DWARFUnit *main_unit, + const DWARFDIE &die) { if (die && die.Tag() == DW_TAG_lexical_block) { - clang::BlockDecl *decl = - llvm::cast_or_null(m_die_to_decl_ctx[die.GetDIE()]); + clang::BlockDecl *decl = llvm::cast_or_null( + m_die_to_decl_ctx[die.MainCUtoDIEPair(main_unit)]); if (!decl) { DWARFDIE decl_context_die; clang::DeclContext *decl_context = - GetClangDeclContextContainingDIE(die, &decl_context_die); - decl = - m_ast.CreateBlockDeclaration(decl_context, GetOwningClangModule(die)); + GetClangDeclContextContainingDIE(main_unit, die, &decl_context_die); + decl = m_ast.CreateBlockDeclaration(decl_context, + GetOwningClangModule(main_unit, die)); if (decl) - LinkDeclContextToDIE((clang::DeclContext *)decl, die); + LinkDeclContextToDIE((clang::DeclContext *)decl, main_unit, die); } return decl; @@ -3408,35 +3474,37 @@ } clang::NamespaceDecl * -DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) { +DWARFASTParserClang::ResolveNamespaceDIE(DWARFUnit *main_unit, + const DWARFDIE &die) { if (die && die.Tag() == DW_TAG_namespace) { // See if we already parsed this namespace DIE and associated it with a // uniqued namespace declaration - clang::NamespaceDecl *namespace_decl = - static_cast(m_die_to_decl_ctx[die.GetDIE()]); + clang::NamespaceDecl *namespace_decl = static_cast( + m_die_to_decl_ctx[die.MainCUtoDIEPair(main_unit)]); if (namespace_decl) return namespace_decl; else { const char *namespace_name = die.GetName(); clang::DeclContext *containing_decl_ctx = - GetClangDeclContextContainingDIE(die, nullptr); + GetClangDeclContextContainingDIE(main_unit, die, nullptr); bool is_inline = die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0; namespace_decl = m_ast.GetUniqueNamespaceDeclaration( - namespace_name, containing_decl_ctx, GetOwningClangModule(die), - is_inline); + namespace_name, containing_decl_ctx, + GetOwningClangModule(main_unit, die), is_inline); Log *log = nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); if (log) { - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf = + &die.GetMainDWARFUnit(main_unit)->GetSymbolFileDWARF(); if (namespace_name) { dwarf->GetObjectFile()->GetModule()->LogMessage( log, "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace with DW_AT_name(\"%s\") => " "clang::NamespaceDecl *%p (original = %p)", - static_cast(&m_ast.getASTContext()), die.GetID(), + static_cast(&m_ast.getASTContext()), die.GetID(main_unit), namespace_name, static_cast(namespace_decl), static_cast(namespace_decl->getOriginalNamespace())); } else { @@ -3445,14 +3513,15 @@ "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p " "(original = %p)", - static_cast(&m_ast.getASTContext()), die.GetID(), + static_cast(&m_ast.getASTContext()), die.GetID(main_unit), static_cast(namespace_decl), static_cast(namespace_decl->getOriginalNamespace())); } } if (namespace_decl) - LinkDeclContextToDIE((clang::DeclContext *)namespace_decl, die); + LinkDeclContextToDIE((clang::DeclContext *)namespace_decl, main_unit, + die); return namespace_decl; } } @@ -3460,8 +3529,9 @@ } clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE( - const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) { - SymbolFileDWARF *dwarf = die.GetDWARF(); + DWARFUnit *main_unit, const DWARFDIE &die, + DWARFDIE *decl_ctx_die_copy) { + SymbolFileDWARF *dwarf = &die.GetMainDWARFUnit(main_unit)->GetSymbolFileDWARF(); DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE(die); @@ -3470,17 +3540,18 @@ if (decl_ctx_die) { clang::DeclContext *clang_decl_ctx = - GetClangDeclContextForDIE(decl_ctx_die); + GetClangDeclContextForDIE(main_unit, decl_ctx_die); if (clang_decl_ctx) return clang_decl_ctx; } return m_ast.GetTranslationUnitDecl(); } -clang::DeclContext * -DWARFASTParserClang::GetCachedClangDeclContextForDIE(const DWARFDIE &die) { +clang::DeclContext *DWARFASTParserClang::GetCachedClangDeclContextForDIE( + DWARFUnit *main_unit, const DWARFDIE &die) { if (die) { - DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE()); + DIEToDeclContextMap::iterator pos = + m_die_to_decl_ctx.find(die.MainCUtoDIEPair(main_unit)); if (pos != m_die_to_decl_ctx.end()) return pos->second; } @@ -3488,16 +3559,19 @@ } void DWARFASTParserClang::LinkDeclContextToDIE(clang::DeclContext *decl_ctx, + DWARFUnit *main_unit, const DWARFDIE &die) { - m_die_to_decl_ctx[die.GetDIE()] = decl_ctx; + m_die_to_decl_ctx[die.MainCUtoDIEPair(main_unit)] = decl_ctx; // There can be many DIEs for a single decl context // m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE()); - m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die)); + m_decl_ctx_to_die.insert( + std::make_pair(decl_ctx, die.MainCUtoDWARFDIEPair(main_unit))); } bool DWARFASTParserClang::CopyUniqueClassMethodTypes( - const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die, - lldb_private::Type *class_type, std::vector &failures) { + DWARFUnit *main_unit, const DWARFDIE &src_class_die, + const DWARFDIE &dst_class_die, lldb_private::Type *class_type, + std::vector &failures) { if (!class_type || !src_class_die || !dst_class_die) return false; if (src_class_die.Tag() != dst_class_die.Tag()) @@ -3608,10 +3682,10 @@ DWARFASTParserClang *src_dwarf_ast_parser = static_cast( - SymbolFileDWARF::GetDWARFParser(*src_die.GetCU())); + SymbolFileDWARF::GetDWARFParser(*src_class_die.GetMainDWARFUnit(main_unit))); DWARFASTParserClang *dst_dwarf_ast_parser = static_cast( - SymbolFileDWARF::GetDWARFParser(*dst_die.GetCU())); + SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetMainDWARFUnit(main_unit))); // Now do the work of linking the DeclContexts and Types. if (fast_path) { @@ -3622,12 +3696,14 @@ dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); clang::DeclContext *src_decl_ctx = - src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; + src_dwarf_ast_parser + ->m_die_to_decl_ctx[src_die.MainCUtoDIEPair(main_unit)]; if (src_decl_ctx) { LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x", static_cast(src_decl_ctx), src_die.GetOffset(), dst_die.GetOffset()); - dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); + dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, main_unit, + dst_die); } else { LLDB_LOGF(log, "warning: tried to unique decl context from 0x%8.8x for " @@ -3636,14 +3712,16 @@ } Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; + dst_die.GetDWARF() + ->GetDIEToType()[src_die.MainCUtoDIEPair(main_unit)]; if (src_child_type) { LLDB_LOGF(log, "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", static_cast(src_child_type), src_child_type->GetID(), src_die.GetOffset(), dst_die.GetOffset()); - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; + dst_die.GetDWARF()->GetDIEToType()[dst_die.MainCUtoDIEPair(main_unit)] = + src_child_type; } else { LLDB_LOGF(log, "warning: tried to unique lldb_private::Type from " @@ -3666,12 +3744,14 @@ if (src_die && (src_die.Tag() == dst_die.Tag())) { clang::DeclContext *src_decl_ctx = - src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; + src_dwarf_ast_parser + ->m_die_to_decl_ctx[src_die.MainCUtoDIEPair(main_unit)]; if (src_decl_ctx) { LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x", static_cast(src_decl_ctx), src_die.GetOffset(), dst_die.GetOffset()); - dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); + dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, main_unit, + dst_die); } else { LLDB_LOGF(log, "warning: tried to unique decl context from 0x%8.8x " @@ -3680,14 +3760,16 @@ } Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; + dst_die.GetDWARF() + ->GetDIEToType()[src_die.MainCUtoDIEPair(main_unit)]; if (src_child_type) { LLDB_LOGF( log, "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", static_cast(src_child_type), src_child_type->GetID(), src_die.GetOffset(), dst_die.GetOffset()); - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = + dst_die.GetDWARF() + ->GetDIEToType()[dst_die.MainCUtoDIEPair(main_unit)] = src_child_type; } else { LLDB_LOGF(log, @@ -3721,12 +3803,14 @@ if (dst_die) { // Both classes have the artificial types, link them clang::DeclContext *src_decl_ctx = - src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; + src_dwarf_ast_parser + ->m_die_to_decl_ctx[src_die.MainCUtoDIEPair(main_unit)]; if (src_decl_ctx) { LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x", static_cast(src_decl_ctx), src_die.GetOffset(), dst_die.GetOffset()); - dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); + dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, main_unit, + dst_die); } else { LLDB_LOGF(log, "warning: tried to unique decl context from 0x%8.8x " @@ -3735,14 +3819,17 @@ } Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; + dst_die.GetDWARF() + ->GetDIEToType()[src_die.MainCUtoDIEPair(main_unit)]; if (src_child_type) { LLDB_LOGF( log, "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", static_cast(src_child_type), src_child_type->GetID(), src_die.GetOffset(), dst_die.GetOffset()); - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; + dst_die.GetDWARF() + ->GetDIEToType()[dst_die.MainCUtoDIEPair(main_unit)] = + src_child_type; } else { LLDB_LOGF(log, "warning: tried to unique lldb_private::Type from " diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h @@ -17,10 +17,12 @@ class DIERef; class DWARFASTParser; class DWARFAttributes; +class DWARFCompileUnit; class DWARFUnit; class DWARFDebugInfoEntry; class DWARFDeclContext; class SymbolFileDWARF; +class DWARFCompileUnit; class DWARFBaseDIE { public: @@ -55,7 +57,7 @@ DWARFDebugInfoEntry *GetDIE() const { return m_die; } - llvm::Optional GetDIERef() const; + llvm::Optional GetDIERef(DWARFUnit *main_unit) const; void Set(DWARFUnit *cu, DWARFDebugInfoEntry *die) { if (cu && die) { @@ -86,12 +88,6 @@ dw_offset_t GetOffset() const; - // Get the LLDB user ID for this DIE. This is often just the DIE offset, - // but it might have a SymbolFileDWARF::GetID() in the high 32 bits if - // we are doing Darwin DWARF in .o file, or DWARF stand alone debug - // info. - lldb::user_id_t GetID() const; - const char *GetName() const; lldb::ModuleSP GetModule() const; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp @@ -8,8 +8,10 @@ #include "DWARFBaseDIE.h" -#include "DWARFUnit.h" +#include "DWARFCompileUnit.h" #include "DWARFDebugInfoEntry.h" +#include "DWARFTypeUnit.h" +#include "DWARFUnit.h" #include "SymbolFileDWARF.h" #include "lldb/Core/Module.h" @@ -18,10 +20,15 @@ using namespace lldb_private; -llvm::Optional DWARFBaseDIE::GetDIERef() const { +llvm::Optional DWARFBaseDIE::GetDIERef(DWARFUnit *main_unit) const { if (!IsValid()) return llvm::None; + if (m_cu->GetSymbolFileDWARF().GetDwoNum().hasValue()) + main_unit = nullptr; + if (m_cu == main_unit) + main_unit = nullptr; + return DIERef(m_cu->GetSymbolFileDWARF().GetDwoNum(), m_cu->GetDebugSection(), m_die->GetOffset()); } @@ -61,12 +68,6 @@ return fail_value; } -lldb::user_id_t DWARFBaseDIE::GetID() const { - if (IsValid()) - return GetDWARF()->GetUID(*this); - return LLDB_INVALID_UID; -} - const char *DWARFBaseDIE::GetName() const { if (IsValid()) return m_die->GetName(m_cu); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -24,6 +24,12 @@ DWARFDIE LookupAddress(const dw_addr_t address); + virtual DWARFUnit *GetMainDWARFUnit(DWARFUnit *main_unit) override; + + DWARFDIE DIE() { return {this, DIEPtr()}; } + + lldb_private::CompileUnit *GetCompUnit(); + private: DWARFCompileUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid, const DWARFUnitHeader &header, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -9,6 +9,7 @@ #include "DWARFCompileUnit.h" #include "DWARFDebugAranges.h" #include "SymbolFileDWARFDebugMap.h" +#include "SymbolFileDWARFDwo.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" @@ -114,3 +115,15 @@ } return DWARFDIE(); } + +DWARFUnit *DWARFCompileUnit::GetMainDWARFUnit(DWARFUnit *main_unit) { + main_unit = &main_unit->GetNonSkeletonUnit(); + return main_unit; +} + +CompileUnit *DWARFCompileUnit::GetCompUnit() { + lldbassert(this); + CompileUnit *comp_unit = GetNonSkeletonUnit().GetSymbolFileDWARF().GetCompUnitForDWARFCompUnit(*this); + lldbassert(comp_unit); + return comp_unit; +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -23,6 +23,12 @@ // Accessors + // Get the LLDB user ID for this DIE. This is often just the DIE offset, + // but it might have a SymbolFileDWARF::GetID() in the high 32 bits if + // we are doing Darwin DWARF in .o file, or DWARF stand alone debug + // info. + lldb::user_id_t GetID(DWARFUnit *main_unit) const; + // Accessing information about a DIE const char *GetMangledName() const; @@ -35,10 +41,11 @@ void AppendTypeName(lldb_private::Stream &s) const; - lldb_private::Type *ResolveType() const; + lldb_private::Type *ResolveType(DWARFUnit *main_unit) const; // Resolve a type by UID using this DIE's DWARF file - lldb_private::Type *ResolveTypeUID(const DWARFDIE &die) const; + lldb_private::Type *ResolveTypeUID(DWARFUnit *main_unit, + const DWARFDIE &die) const; // Functions for obtaining DIE relations and references @@ -88,6 +95,12 @@ int &decl_line, int &decl_column, int &call_file, int &call_line, int &call_column, lldb_private::DWARFExpression *frame_base) const; + + DWARFUnit *GetMainDWARFUnit(DWARFUnit *main_unit) const; + std::pair + MainCUtoDWARFDIEPair(DWARFUnit *main_unit) const; + std::pair + MainCUtoDIEPair(DWARFUnit *main_unit) const; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -9,10 +9,11 @@ #include "DWARFDIE.h" #include "DWARFASTParser.h" +#include "DWARFCompileUnit.h" #include "DWARFDebugInfo.h" #include "DWARFDebugInfoEntry.h" #include "DWARFDeclContext.h" -#include "DWARFUnit.h" +#include "SymbolFileDWARFDwo.h" using namespace lldb_private; @@ -200,6 +201,12 @@ return result; } +lldb::user_id_t DWARFDIE::GetID(DWARFUnit *main_unit) const { + if (IsValid()) + return GetDWARF()->GetUID(main_unit, *this); + return LLDB_INVALID_UID; +} + const char *DWARFDIE::GetMangledName() const { if (IsValid()) return m_die->GetMangledName(m_cu); @@ -345,16 +352,18 @@ } } -lldb_private::Type *DWARFDIE::ResolveType() const { +lldb_private::Type *DWARFDIE::ResolveType(DWARFUnit *main_unit) const { if (IsValid()) - return GetDWARF()->ResolveType(*this, true); + return GetMainDWARFUnit(main_unit)->GetSymbolFileDWARF().ResolveType( + main_unit, *this, true); else return nullptr; } -lldb_private::Type *DWARFDIE::ResolveTypeUID(const DWARFDIE &die) const { - if (SymbolFileDWARF *dwarf = GetDWARF()) - return dwarf->ResolveTypeUID(die, true); +lldb_private::Type *DWARFDIE::ResolveTypeUID(DWARFUnit *main_unit, + const DWARFDIE &die) const { + if (SymbolFileDWARF *dwarf = &GetMainDWARFUnit(main_unit)->GetSymbolFileDWARF()) + return dwarf->ResolveTypeUID(main_unit, die, true); return nullptr; } @@ -448,3 +457,18 @@ } else return false; } + +DWARFUnit *DWARFDIE::GetMainDWARFUnit(DWARFUnit *main_unit) const { + lldbassert(IsValid()); + return GetCU()->GetMainDWARFUnit(main_unit); +} + +std::pair +DWARFDIE::MainCUtoDWARFDIEPair(DWARFUnit *main_unit) const { + return std::make_pair(GetMainDWARFUnit(main_unit), *this); +} + +std::pair +DWARFDIE::MainCUtoDIEPair(DWARFUnit *main_unit) const { + return std::make_pair(GetMainDWARFUnit(main_unit), GetDIE()); +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -41,11 +41,12 @@ DWARFUnit *GetUnitContainingDIEOffset(DIERef::Section section, dw_offset_t die_offset); DWARFUnit *GetUnit(const DIERef &die_ref); + DWARFUnit *GetMainUnit(const DIERef &die_ref); DWARFTypeUnit *GetTypeUnitForHash(uint64_t hash); bool ContainsTypeUnits(); DWARFDIE GetDIEForDIEOffset(DIERef::Section section, dw_offset_t die_offset); - DWARFDIE GetDIE(const DIERef &die_ref); + DWARFDIE GetDIE(const DIERef &die_ref, DWARFUnit **main_unit_return = nullptr); enum { eDumpFlag_Verbose = (1 << 0), // Verbose dumping @@ -56,6 +57,10 @@ llvm::Expected GetCompileUnitAranges(); + lldb::user_id_t GetUID(DWARFUnit *main_unit, DIERef ref) const { + return m_dwarf.GetUID(main_unit, ref); + } + protected: typedef std::vector UnitColl; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -58,6 +58,8 @@ for (size_t idx = 0; idx < num_units; ++idx) { DWARFUnit *cu = GetUnitAtIndex(idx); + if (cu->GetUnitDIEOnly().Tag() == DW_TAG_partial_unit) + continue; dw_offset_t offset = cu->GetOffset(); if (cus_with_data.find(offset) == cus_with_data.end()) cu->BuildAddressRangeTable(m_cu_aranges_up.get()); @@ -157,6 +159,11 @@ return GetUnitContainingDIEOffset(die_ref.section(), die_ref.die_offset()); } +DWARFUnit *DWARFDebugInfo::GetMainUnit(const DIERef &die_ref) { + DWARFUnit *main_unit = GetUnit(die_ref); + return main_unit; +} + DWARFUnit * DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section, dw_offset_t die_offset) { @@ -193,9 +200,15 @@ // // Get the DIE (Debug Information Entry) with the specified offset. DWARFDIE -DWARFDebugInfo::GetDIE(const DIERef &die_ref) { +DWARFDebugInfo::GetDIE(const DIERef &die_ref, DWARFUnit **main_unit_return) { DWARFUnit *cu = GetUnit(die_ref); - if (cu) - return cu->GetNonSkeletonUnit().GetDIE(die_ref.die_offset()); + if (cu) { + DWARFUnit *main_unit = GetMainUnit(die_ref); + if (main_unit == cu) + cu = main_unit = &main_unit->GetNonSkeletonUnit(); + if (main_unit_return) + *main_unit_return = main_unit; + return cu->GetDIE(die_ref.die_offset()); + } return DWARFDIE(); // Not found } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -727,6 +727,7 @@ } } +// DIE.GetCU(), not main_unit. DWARFDeclContext DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnit *cu) const { return GetDWARFDeclContextStatic(this, cu); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -27,37 +27,48 @@ /// Finds global variables with the given base name. Any additional filtering /// (e.g., to only retrieve variables from a given context) should be done by /// the consumer. - virtual void - GetGlobalVariables(ConstString basename, - llvm::function_ref callback) = 0; + virtual void GetGlobalVariables( + ConstString basename, + llvm::function_ref + callback) = 0; + virtual void GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref + callback) = 0; + virtual void GetGlobalVariables( + const DWARFUnit &main_unit, + llvm::function_ref + callback) = 0; + virtual void GetObjCMethods( + ConstString class_name, + llvm::function_ref + callback) = 0; + virtual void GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref + callback) = 0; virtual void - GetGlobalVariables(const RegularExpression ®ex, - llvm::function_ref callback) = 0; - virtual void - GetGlobalVariables(const DWARFUnit &cu, - llvm::function_ref callback) = 0; - virtual void - GetObjCMethods(ConstString class_name, - llvm::function_ref callback) = 0; - virtual void - GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, - llvm::function_ref callback) = 0; - virtual void GetTypes(ConstString name, - llvm::function_ref callback) = 0; - virtual void GetTypes(const DWARFDeclContext &context, - llvm::function_ref callback) = 0; + GetTypes(ConstString name, + llvm::function_ref + callback) = 0; virtual void - GetNamespaces(ConstString name, - llvm::function_ref callback) = 0; - virtual void - GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - llvm::function_ref callback) = 0; - virtual void - GetFunctions(const RegularExpression ®ex, - llvm::function_ref callback) = 0; + GetTypes(const DWARFDeclContext &context, + llvm::function_ref + callback) = 0; + virtual void GetNamespaces( + ConstString name, + llvm::function_ref + callback) = 0; + virtual void GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref + callback) = 0; + virtual void GetFunctions( + const RegularExpression ®ex, + llvm::function_ref + callback) = 0; virtual void Dump(Stream &s) = 0; @@ -68,32 +79,53 @@ /// the function given by "ref" matches search criteria given by /// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies" /// vector. - bool ProcessFunctionDIE(llvm::StringRef name, DIERef ref, - SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - llvm::function_ref callback); + bool ProcessFunctionDIE( + llvm::StringRef name, DWARFUnit *main_unit, DIERef ref, + SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + llvm::function_ref + callback); - class DIERefCallbackImpl { + class DIECallbackImpl { public: - DIERefCallbackImpl(const DWARFIndex &index, - llvm::function_ref callback, - llvm::StringRef name); - bool operator()(DIERef ref) const; + DIECallbackImpl( + const DWARFIndex &index, + llvm::function_ref + callback, + llvm::StringRef name); - private: + protected: const DWARFIndex &m_index; SymbolFileDWARF &m_dwarf; - const llvm::function_ref m_callback; + const llvm::function_ref + m_callback; const llvm::StringRef m_name; }; - DIERefCallbackImpl - DIERefCallback(llvm::function_ref callback, - llvm::StringRef name = {}) const { + class DIERefCallbackImpl : protected DIECallbackImpl { + public: + using DIECallbackImpl::DIECallbackImpl; + bool operator()(DIERef ref) const; + }; + class DIEUIDCallbackImpl : protected DIECallbackImpl { + public: + using DIECallbackImpl::DIECallbackImpl; + bool operator()(lldb::user_id_t uid) const; + }; + DIERefCallbackImpl DIERefCallback( + llvm::function_ref + callback, + llvm::StringRef name = {}) const { return DIERefCallbackImpl(*this, callback, name); } + DIEUIDCallbackImpl DIEUIDCallback( + llvm::function_ref + callback, + llvm::StringRef name = {}) const { + return DIEUIDCallbackImpl(*this, callback, name); + } void ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const; + void ReportInvalidDIEUID(lldb::user_id_t, llvm::StringRef name) const; }; } // namespace lldb_private 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 @@ -8,6 +8,7 @@ #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" +#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" @@ -19,14 +20,17 @@ DWARFIndex::~DWARFIndex() = default; bool DWARFIndex::ProcessFunctionDIE( - llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - llvm::function_ref callback) { + llvm::StringRef name, DWARFUnit *main_unit, DIERef ref, + SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + llvm::function_ref + callback) { DWARFDIE die = dwarf.GetDIE(ref); if (!die) { ReportInvalidDIERef(ref, name); return true; } + main_unit = die.GetMainDWARFUnit(main_unit); // Exit early if we're searching exclusively for methods or selectors and // we have a context specified (no methods in namespaces). @@ -37,18 +41,18 @@ // 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 (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, main_unit, die)) return true; // In case of a full match, we just insert everything we find. if (name_type_mask & eFunctionNameTypeFull) - return callback(die); + return callback(main_unit, die); // If looking for ObjC selectors, we need to also check if the name is a // possible selector. if (name_type_mask & eFunctionNameTypeSelector && ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) - return callback(die); + return callback(main_unit, die); bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod; bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase; @@ -58,29 +62,48 @@ // searching for. if ((looking_for_methods && looking_for_functions) || looking_for_methods == die.IsMethod()) - return callback(die); + return callback(main_unit, die); } return true; } -DWARFIndex::DIERefCallbackImpl::DIERefCallbackImpl( - const DWARFIndex &index, llvm::function_ref callback, +DWARFIndex::DIECallbackImpl::DIECallbackImpl( + const DWARFIndex &index, + llvm::function_ref + callback, llvm::StringRef name) : m_index(index), m_dwarf(*llvm::cast(index.m_module.GetSymbolFile())), m_callback(callback), m_name(name) {} bool DWARFIndex::DIERefCallbackImpl::operator()(DIERef ref) const { - if (DWARFDIE die = m_dwarf.GetDIE(ref)) - return m_callback(die); + DWARFUnit *main_unit; + if (DWARFDIE die = m_dwarf.GetDIE(ref, &main_unit)) + return m_callback(main_unit, die); m_index.ReportInvalidDIERef(ref, m_name); return true; } +bool DWARFIndex::DIEUIDCallbackImpl::operator()(user_id_t uid) const { + DWARFUnit *main_unit; + if (DWARFDIE die = m_dwarf.GetDIEUnlocked(uid, &main_unit)) + return m_callback(main_unit, die); + m_index.ReportInvalidDIEUID(uid, m_name); + return true; +} + void DWARFIndex::ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const { m_module.ReportErrorIfModifyDetected( "the DWARF debug information has been modified (accelerator table had " - "bad die 0x%8.8x for '%s')\n", + "bad DIERef 0x%8.8x for '%s')\n", ref.die_offset(), name.str().c_str()); } + +void DWARFIndex::ReportInvalidDIEUID(user_id_t uid, + llvm::StringRef name) const { + m_module.ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (accelerator table had " + "bad user_id_t 0x%8.8lx for '%s')\n", + uid, name.str().c_str()); +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h @@ -24,6 +24,8 @@ static bool classof(const DWARFUnit *unit) { return unit->IsTypeUnit(); } + virtual DWARFUnit *GetMainDWARFUnit(DWARFUnit *main_unit) override; + private: DWARFTypeUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid, const DWARFUnitHeader &header, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp @@ -8,7 +8,7 @@ #include "DWARFTypeUnit.h" -#include "SymbolFileDWARF.h" +#include "SymbolFileDWARFDwo.h" #include "lldb/Utility/Stream.h" using namespace lldb; @@ -21,3 +21,9 @@ GetOffset(), GetLength(), GetVersion(), GetAbbrevOffset(), GetAddressByteSize(), GetNextUnitOffset()); } + +DWARFUnit *DWARFTypeUnit::GetMainDWARFUnit(DWARFUnit *main_unit) { + main_unit = this; + main_unit = &main_unit->GetNonSkeletonUnit(); + return main_unit; +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -263,6 +263,8 @@ lldb_private::DWARFDataExtractor GetLocationData() const; + virtual DWARFUnit *GetMainDWARFUnit(DWARFUnit *main_unit)=0; + protected: DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid, const DWARFUnitHeader &header, @@ -292,7 +294,7 @@ } SymbolFileDWARF &m_dwarf; - std::shared_ptr m_dwo; + std::shared_ptr m_dwo; DWARFUnitHeader m_header; const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr; void *m_user_data = nullptr; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -359,7 +359,7 @@ if (!dwo_symbol_file) return; - DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(m_dwo_id); + DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(m_dwo_id); if (!dwo_cu) return; // Can't fetch the compile unit from the dwo file. @@ -393,7 +393,7 @@ dwo_cu->SetLoclistsBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); dwo_cu->SetBaseAddress(GetBaseAddress()); - m_dwo = std::shared_ptr(std::move(dwo_symbol_file), dwo_cu); + m_dwo = std::shared_ptr(std::move(dwo_symbol_file), dwo_cu); } size_t DWARFUnit::GetDebugInfoSize() const { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -25,33 +25,47 @@ void Preload() override { m_fallback.Preload(); } - void - GetGlobalVariables(ConstString basename, - llvm::function_ref callback) override; - void - GetGlobalVariables(const RegularExpression ®ex, - llvm::function_ref callback) override; - void - GetGlobalVariables(const DWARFUnit &cu, - llvm::function_ref callback) override; - void - GetObjCMethods(ConstString class_name, - llvm::function_ref callback) override {} + void GetGlobalVariables( + ConstString basename, + llvm::function_ref + callback) override; + void GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref + callback) override; + void GetGlobalVariables( + const DWARFUnit &main_unit, + llvm::function_ref + callback) override; + void GetObjCMethods( + ConstString class_name, + llvm::function_ref + callback) override {} void GetCompleteObjCClass( ConstString class_name, bool must_be_implementation, - llvm::function_ref callback) override; - void GetTypes(ConstString name, - llvm::function_ref callback) override; - void GetTypes(const DWARFDeclContext &context, - llvm::function_ref callback) override; - void GetNamespaces(ConstString name, - llvm::function_ref callback) override; - void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - llvm::function_ref callback) override; - void GetFunctions(const RegularExpression ®ex, - llvm::function_ref callback) override; + llvm::function_ref + callback) override; + void + GetTypes(ConstString name, + llvm::function_ref + callback) override; + void + GetTypes(const DWARFDeclContext &context, + llvm::function_ref + callback) override; + void GetNamespaces( + ConstString name, + llvm::function_ref + callback) override; + void GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref + callback) override; + void GetFunctions( + const RegularExpression ®ex, + llvm::function_ref + callback) override; void Dump(Stream &s) override; @@ -78,9 +92,11 @@ ManualDWARFIndex m_fallback; llvm::Optional ToDIERef(const DebugNames::Entry &entry); - bool ProcessEntry(const DebugNames::Entry &entry, - llvm::function_ref callback, - llvm::StringRef name); + bool ProcessEntry( + const DebugNames::Entry &entry, + llvm::function_ref + callback, + llvm::StringRef name); static void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h" +#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h" #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h" @@ -60,7 +61,9 @@ bool DebugNamesDWARFIndex::ProcessEntry( const DebugNames::Entry &entry, - llvm::function_ref callback, llvm::StringRef name) { + llvm::function_ref + callback, + llvm::StringRef name) { llvm::Optional ref = ToDIERef(entry); if (!ref) return true; @@ -69,7 +72,9 @@ DWARFDIE die = dwarf.GetDIE(*ref); if (!die) return true; - return callback(die); + // FIXME: DWZ + DWARFUnit *main_unit = die.GetMainDWARFUnit(nullptr); + return callback(main_unit, die); } void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error, @@ -84,7 +89,9 @@ } void DebugNamesDWARFIndex::GetGlobalVariables( - ConstString basename, llvm::function_ref callback) { + ConstString basename, + llvm::function_ref + callback) { for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(basename.GetStringRef())) { if (entry.tag() != DW_TAG_variable) @@ -99,7 +106,8 @@ void DebugNamesDWARFIndex::GetGlobalVariables( const RegularExpression ®ex, - llvm::function_ref callback) { + llvm::function_ref + callback) { for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { if (!regex.Execute(nte.getString())) @@ -123,8 +131,10 @@ } void DebugNamesDWARFIndex::GetGlobalVariables( - const DWARFUnit &cu, llvm::function_ref callback) { - uint64_t cu_offset = cu.GetOffset(); + const DWARFUnit &main_unit, + llvm::function_ref + callback) { + uint64_t cu_offset = main_unit.GetOffset(); for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { uint64_t entry_offset = nte.getEntryOffset(); @@ -143,14 +153,16 @@ } } - m_fallback.GetGlobalVariables(cu, callback); + m_fallback.GetGlobalVariables(main_unit, callback); } void DebugNamesDWARFIndex::GetCompleteObjCClass( ConstString class_name, bool must_be_implementation, - llvm::function_ref callback) { + llvm::function_ref + callback) { // Keep a list of incomplete types as fallback for when we don't find the // complete type. + // FIXME: DWZ DIEArray incomplete_types; for (const DebugNames::Entry &entry : @@ -177,12 +189,14 @@ if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) { // If we find the complete version we're done. - callback(die); + // FIXME: DWZ + callback(nullptr /* main_unit */, die); return; } incomplete_types.push_back(*ref); } + // FIXME: DWZ auto dierefcallback = DIERefCallback(callback, class_name.GetStringRef()); for (DIERef ref : incomplete_types) if (!dierefcallback(ref)) @@ -192,7 +206,9 @@ } void DebugNamesDWARFIndex::GetTypes( - ConstString name, llvm::function_ref callback) { + ConstString name, + llvm::function_ref + callback) { for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { if (isType(entry.tag())) { @@ -206,7 +222,8 @@ void DebugNamesDWARFIndex::GetTypes( const DWARFDeclContext &context, - llvm::function_ref callback) { + llvm::function_ref + callback) { auto name = context[0].name; for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name)) { if (entry.tag() == context[0].tag) { @@ -219,7 +236,9 @@ } void DebugNamesDWARFIndex::GetNamespaces( - ConstString name, llvm::function_ref callback) { + ConstString name, + llvm::function_ref + callback) { for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { if (entry.tag() == DW_TAG_namespace) { @@ -234,8 +253,10 @@ void DebugNamesDWARFIndex::GetFunctions( ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - llvm::function_ref callback) { + llvm::function_ref + callback) { + // FIXME: DWZ std::set seen; for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { @@ -244,12 +265,19 @@ continue; if (llvm::Optional ref = ToDIERef(entry)) { - if (!ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx, - name_type_mask, [&](DWARFDIE die) { - if (!seen.insert(die.GetDIE()).second) - return true; - return callback(die); - })) + // FIXME: DWZ + DWARFUnit *main_unit = nullptr; + if (!ProcessFunctionDIE( + name.GetStringRef(), main_unit, *ref, dwarf, parent_decl_ctx, + name_type_mask, + [&](DWARFUnit *main_unit_check, DWARFDIE die) { + // FIXME: DWZ + //lldbassert(main_unit_check == main_unit); + if (!seen.insert(die.GetDIE()).second) + return true; + // FIXME: DWZ + return callback(main_unit_check, die); + })) return; } } @@ -260,7 +288,8 @@ void DebugNamesDWARFIndex::GetFunctions( const RegularExpression ®ex, - llvm::function_ref callback) { + llvm::function_ref + callback) { for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { if (!regex.Execute(nte.getString())) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -16,6 +16,7 @@ #include "lldb/Utility/RegularExpression.h" #include "lldb/lldb-defines.h" +#include "DIERef.h" #include "DWARFDefines.h" #include "DWARFFormValue.h" #include "NameToDIE.h" diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -26,32 +26,47 @@ void Preload() override { Index(); } - void - GetGlobalVariables(ConstString basename, - llvm::function_ref callback) override; - void - GetGlobalVariables(const RegularExpression ®ex, - llvm::function_ref callback) override; - void - GetGlobalVariables(const DWARFUnit &unit, - llvm::function_ref callback) override; - void GetObjCMethods(ConstString class_name, - llvm::function_ref callback) override; + void GetGlobalVariables( + ConstString basename, + llvm::function_ref + callback) override; + void GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref + callback) override; + void GetGlobalVariables( + const DWARFUnit &main_unit, + llvm::function_ref + callback) override; + void GetObjCMethods( + ConstString class_name, + llvm::function_ref + callback) override; void GetCompleteObjCClass( ConstString class_name, bool must_be_implementation, - llvm::function_ref callback) override; - void GetTypes(ConstString name, - llvm::function_ref callback) override; - void GetTypes(const DWARFDeclContext &context, - llvm::function_ref callback) override; - void GetNamespaces(ConstString name, - llvm::function_ref callback) override; - void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - llvm::function_ref callback) override; - void GetFunctions(const RegularExpression ®ex, - llvm::function_ref callback) override; + llvm::function_ref + callback) override; + void + GetTypes(ConstString name, + llvm::function_ref + callback) override; + void + GetTypes(const DWARFDeclContext &context, + llvm::function_ref + callback) override; + void GetNamespaces( + ConstString name, + llvm::function_ref + callback) override; + void GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref + callback) override; + void GetFunctions( + const RegularExpression ®ex, + llvm::function_ref + callback) override; void Dump(Stream &s) override; @@ -69,7 +84,7 @@ void Index(); void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set); - static void IndexUnitImpl(DWARFUnit &unit, + static void IndexUnitImpl(DWARFUnit &unit, DWARFUnit *main_unit, const lldb::LanguageType cu_language, IndexSet &set); 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 @@ -8,6 +8,7 @@ #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" +#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h" #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h" #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" @@ -122,23 +123,24 @@ const LanguageType cu_language = SymbolFileDWARF::GetLanguage(unit); - IndexUnitImpl(unit, cu_language, set); + IndexUnitImpl(unit, &unit, cu_language, set); if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) { // Type units in a dwp file are indexed separately, so we just need to // process the split unit here. However, if the split unit is in a dwo file, // then we need to process type units here. if (dwo_symbol_file == dwp) { - IndexUnitImpl(unit.GetNonSkeletonUnit(), cu_language, set); + IndexUnitImpl(unit.GetNonSkeletonUnit(), &unit, cu_language, set); } else { DWARFDebugInfo &dwo_info = dwo_symbol_file->DebugInfo(); for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) - IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set); + IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), &unit, cu_language, set); } } } void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, + DWARFUnit *main_unit, const LanguageType cu_language, IndexSet &set) { for (const DWARFDebugInfoEntry &die : unit.dies()) { @@ -223,7 +225,7 @@ } } - DIERef ref = *DWARFDIE(&unit, &die).GetDIERef(); + DIERef ref = *DWARFDIE(&unit, &die).GetDIERef(main_unit); switch (tag) { case DW_TAG_inlined_subroutine: case DW_TAG_subprogram: @@ -328,7 +330,9 @@ } void ManualDWARFIndex::GetGlobalVariables( - ConstString basename, llvm::function_ref callback) { + ConstString basename, + llvm::function_ref + callback) { Index(); m_set.globals.Find(basename, DIERefCallback(callback, basename.GetStringRef())); @@ -336,19 +340,24 @@ void ManualDWARFIndex::GetGlobalVariables( const RegularExpression ®ex, - llvm::function_ref callback) { + llvm::function_ref + callback) { Index(); m_set.globals.Find(regex, DIERefCallback(callback, regex.GetText())); } void ManualDWARFIndex::GetGlobalVariables( - const DWARFUnit &unit, llvm::function_ref callback) { + const DWARFUnit &main_unit, + llvm::function_ref + callback) { Index(); - m_set.globals.FindAllEntriesForUnit(unit, DIERefCallback(callback)); + m_set.globals.FindAllEntriesForUnit(main_unit, DIERefCallback(callback)); } void ManualDWARFIndex::GetObjCMethods( - ConstString class_name, llvm::function_ref callback) { + ConstString class_name, + llvm::function_ref + callback) { Index(); m_set.objc_class_selectors.Find( class_name, DIERefCallback(callback, class_name.GetStringRef())); @@ -356,21 +365,25 @@ void ManualDWARFIndex::GetCompleteObjCClass( ConstString class_name, bool must_be_implementation, - llvm::function_ref callback) { + llvm::function_ref + callback) { Index(); m_set.types.Find(class_name, DIERefCallback(callback, class_name.GetStringRef())); } void ManualDWARFIndex::GetTypes( - ConstString name, llvm::function_ref callback) { + ConstString name, + llvm::function_ref + callback) { Index(); m_set.types.Find(name, DIERefCallback(callback, name.GetStringRef())); } void ManualDWARFIndex::GetTypes( const DWARFDeclContext &context, - llvm::function_ref callback) { + llvm::function_ref + callback) { Index(); auto name = context[0].name; m_set.types.Find(ConstString(name), @@ -378,7 +391,9 @@ } void ManualDWARFIndex::GetNamespaces( - ConstString name, llvm::function_ref callback) { + ConstString name, + llvm::function_ref + callback) { Index(); m_set.namespaces.Find(name, DIERefCallback(callback, name.GetStringRef())); } @@ -386,17 +401,18 @@ void ManualDWARFIndex::GetFunctions( ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - llvm::function_ref callback) { + llvm::function_ref + callback) { Index(); if (name_type_mask & eFunctionNameTypeFull) { if (!m_set.function_fullnames.Find( name, DIERefCallback( - [&](DWARFDIE die) { + [&](DWARFUnit *main_unit, DWARFDIE die) { if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, - die)) + main_unit, die)) return true; - return callback(die); + return callback(main_unit, die); }, name.GetStringRef()))) return; @@ -404,11 +420,11 @@ if (name_type_mask & eFunctionNameTypeBase) { if (!m_set.function_basenames.Find( name, DIERefCallback( - [&](DWARFDIE die) { + [&](DWARFUnit *main_unit, DWARFDIE die) { if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, - die)) + main_unit, die)) return true; - return callback(die); + return callback(main_unit, die); }, name.GetStringRef()))) return; @@ -430,7 +446,8 @@ void ManualDWARFIndex::GetFunctions( const RegularExpression ®ex, - llvm::function_ref callback) { + llvm::function_ref + callback) { Index(); if (!m_set.function_basenames.Find(regex, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "NameToDIE.h" -#include "DWARFUnit.h" +#include "DWARFCompileUnit.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/RegularExpression.h" 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 @@ -142,7 +142,8 @@ bool CompleteType(lldb_private::CompilerType &compiler_type) override; - lldb_private::Type *ResolveType(const DWARFDIE &die, + lldb_private::Type *ResolveType(DWARFUnit *main_unit, + const DWARFDIE &die, bool assert_not_being_parsed = true, bool resolve_function_context = false); @@ -240,8 +241,10 @@ lldb_private::CompileUnit * GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu); - virtual void GetObjCMethods(lldb_private::ConstString class_name, - llvm::function_ref callback); + virtual void GetObjCMethods( + lldb_private::ConstString class_name, + llvm::function_ref + callback); bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu); @@ -259,19 +262,21 @@ return m_external_type_modules; } - virtual DWARFDIE GetDIE(const DIERef &die_ref); + virtual DWARFDIE GetDIE(const DIERef &die_ref, DWARFUnit **main_unit_return = nullptr); DWARFDIE GetDIE(lldb::user_id_t uid); - lldb::user_id_t GetUID(const DWARFBaseDIE &die) { - return GetUID(die.GetDIERef()); - } + DWARFDIE GetDIEUnlocked(lldb::user_id_t uid, + DWARFUnit **main_unit_return = nullptr); + + lldb::user_id_t GetUID(DWARFUnit *main_unit, const DWARFDIE &die); - lldb::user_id_t GetUID(const llvm::Optional &ref) { - return ref ? GetUID(*ref) : LLDB_INVALID_UID; + lldb::user_id_t GetUID(DWARFUnit *main_unit, + const llvm::Optional &ref) { + return ref ? GetUID(main_unit, *ref) : LLDB_INVALID_UID; } - lldb::user_id_t GetUID(DIERef ref); + lldb::user_id_t GetUID(DWARFUnit *main_unit, DIERef ref); std::shared_ptr GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu, @@ -284,7 +289,7 @@ static bool DIEInDeclContext(const lldb_private::CompilerDeclContext &parent_decl_ctx, - const DWARFDIE &die); + DWARFUnit *main_unit, const DWARFDIE &die); std::vector> ParseCallEdgesInFunction(UserID func_id) override; @@ -306,28 +311,44 @@ // CompilerDecl related functions - static lldb_private::CompilerDecl GetDecl(const DWARFDIE &die); + static lldb_private::CompilerDecl GetDecl(DWARFUnit *main_unit, + const DWARFDIE &die); - static lldb_private::CompilerDeclContext GetDeclContext(const DWARFDIE &die); + static lldb_private::CompilerDeclContext + GetDeclContext(DWARFUnit *main_unit, const DWARFDIE &die); static lldb_private::CompilerDeclContext - GetContainingDeclContext(const DWARFDIE &die); + GetContainingDeclContext(DWARFUnit *main_unit, const DWARFDIE &die); - static DWARFDeclContext GetDWARFDeclContext(const DWARFDIE &die); + static DWARFDeclContext GetDWARFDeclContext(DWARFUnit *main_unit, const DWARFDIE &die); static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val); static lldb::LanguageType GetLanguage(DWARFUnit &unit); + struct DecodedUID { + SymbolFileDWARF &dwarf; + DIERef ref; + }; + llvm::Optional DecodeUIDUnlocked(lldb::user_id_t uid); + + llvm::Optional GetDWARFUnitIndex(uint32_t cu_idx); + protected: - typedef llvm::DenseMap + typedef llvm::DenseMap< + std::pair, + lldb_private::Type *> DIEToTypePtr; - typedef llvm::DenseMap + typedef llvm::DenseMap< + std::pair, + lldb::VariableSP> DIEToVariableSP; - typedef llvm::DenseMap + typedef llvm::DenseMap< + std::pair, + lldb::opaque_compiler_type_t> DIEToClangType; - typedef llvm::DenseMap ClangTypeToDIE; + typedef llvm::DenseMap + ClangTypeToDIE; SymbolFileDWARF(const SymbolFileDWARF &) = delete; const SymbolFileDWARF &operator=(const SymbolFileDWARF &) = delete; @@ -346,12 +367,12 @@ lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu); - virtual DWARFCompileUnit * - GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit); + DWARFCompileUnit *GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override; DWARFUnit *GetNextUnparsedDWARFCompileUnit(DWARFUnit *prev_cu); - bool GetFunction(const DWARFDIE &die, lldb_private::SymbolContext &sc); + bool GetFunction(DWARFUnit *main_unit, const DWARFDIE &die, + lldb_private::SymbolContext &sc); lldb_private::Function *ParseFunction(lldb_private::CompileUnit &comp_unit, const DWARFDIE &die); @@ -367,10 +388,12 @@ lldb::TypeSP ParseType(const lldb_private::SymbolContext &sc, const DWARFDIE &die, bool *type_is_new); - lldb_private::Type *ResolveTypeUID(const DWARFDIE &die, + lldb_private::Type *ResolveTypeUID(DWARFUnit *main_unit, + const DWARFDIE &die, bool assert_not_being_parsed); - lldb_private::Type *ResolveTypeUID(const DIERef &die_ref); + lldb_private::Type *ResolveTypeUID(DWARFUnit *main_unit, + const DIERef &die_ref); lldb::VariableSP ParseVariableDIE(const lldb_private::SymbolContext &sc, const DWARFDIE &die, @@ -385,7 +408,8 @@ bool ClassOrStructIsVirtual(const DWARFDIE &die); // Given a die_offset, figure out the symbol context representing that die. - bool ResolveFunction(const DWARFDIE &die, bool include_inlines, + bool ResolveFunction(DWARFUnit *main_unit, const DWARFDIE &die, + bool include_inlines, lldb_private::SymbolContextList &sc_list); /// Resolve functions and (possibly) blocks for the given file address and a @@ -405,7 +429,7 @@ lldb_private::Symbol * GetObjCClassSymbol(lldb_private::ConstString objc_class_name); - lldb::TypeSP GetTypeForDIE(const DWARFDIE &die, + lldb::TypeSP GetTypeForDIE(DWARFUnit *main_unit, const DWARFDIE &die, bool resolve_function_context = false); void SetDebugMapModule(const lldb::ModuleSP &module_sp) { @@ -445,9 +469,9 @@ typedef llvm::SetVector TypeSet; - void GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, - dw_offset_t max_die_offset, uint32_t type_mask, - TypeSet &type_set); + void GetTypes(DWARFUnit *main_unit, const DWARFDIE &die, + dw_offset_t min_die_offset, dw_offset_t max_die_offset, + uint32_t type_mask, TypeSet &type_set); typedef lldb_private::RangeDataVector @@ -470,12 +494,7 @@ } void BuildCuTranslationTable(); - llvm::Optional GetDWARFUnitIndex(uint32_t cu_idx); - struct DecodedUID { - SymbolFileDWARF &dwarf; - DIERef ref; - }; llvm::Optional DecodeUID(lldb::user_id_t uid); void FindDwpSymbolFile(); 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 @@ -294,7 +294,8 @@ return debug_map_symfile->GetTypeList(); return SymbolFile::GetTypeList(); } -void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, +void SymbolFileDWARF::GetTypes(DWARFUnit *main_unit, const DWARFDIE &die, + dw_offset_t min_die_offset, dw_offset_t max_die_offset, uint32_t type_mask, TypeSet &type_set) { if (die) { @@ -352,7 +353,7 @@ if (add_type) { const bool assert_not_being_parsed = true; - Type *type = ResolveTypeUID(die, assert_not_being_parsed); + Type *type = ResolveTypeUID(main_unit, die, assert_not_being_parsed); if (type) type_set.insert(type); } @@ -360,7 +361,8 @@ for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); child_die = child_die.GetSibling()) { - GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set); + GetTypes(main_unit, child_die, min_die_offset, max_die_offset, type_mask, + type_set); } } } @@ -380,7 +382,7 @@ if (!unit) return; unit = &unit->GetNonSkeletonUnit(); - GetTypes(unit->DIE(), unit->GetOffset(), unit->GetNextUnitOffset(), + GetTypes(unit, unit->DIE(), unit->GetOffset(), unit->GetNextUnitOffset(), type_mask, type_set); }; if (comp_unit) { @@ -635,13 +637,21 @@ if (!comp_unit) return nullptr; + if (SymbolFileDWARFDwo *dwo = llvm::dyn_cast(this)) + return dwo->GetBaseSymbolFile().GetDWARFCompileUnit(comp_unit); + // The compile unit ID is the index of the DWARF unit. DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(comp_unit->GetID()); - if (dwarf_cu && dwarf_cu->GetUserData() == nullptr) + if (!dwarf_cu) + return nullptr; + + if (dwarf_cu->GetUserData() == nullptr) dwarf_cu->SetUserData(comp_unit); + else + lldbassert(dwarf_cu->GetUserData() == comp_unit); // It must be DWARFCompileUnit when it created a CompileUnit. - return llvm::cast_or_null(dwarf_cu); + return llvm::cast(dwarf_cu); } DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() { @@ -704,6 +714,7 @@ *GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language, is_optimized ? eLazyBoolYes : eLazyBoolNo); + lldbassert(cu_sp->GetID()==*GetDWARFUnitIndex(dwarf_cu.GetID())); dwarf_cu.SetUserData(cu_sp.get()); SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp); @@ -762,7 +773,9 @@ if (!die.IsValid()) return nullptr; - auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); + DWARFUnit *main_unit = comp_unit.GetDWARFCompileUnit(); + + auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetMainDWARFUnit(main_unit))); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), std::move(err), "Unable to parse function"); @@ -830,7 +843,7 @@ size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) { LLDB_SCOPED_TIMER(); std::lock_guard guard(GetModuleMutex()); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); + DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (!dwarf_cu) return 0; @@ -841,7 +854,7 @@ continue; DWARFDIE die(dwarf_cu, &entry); - if (comp_unit.FindFunctionByUID(die.GetID())) + if (comp_unit.FindFunctionByUID(die.GetID(dwarf_cu))) continue; if (ParseFunction(comp_unit, die)) ++functions_added; @@ -960,8 +973,9 @@ const lldb_private::SymbolContext &sc, std::vector &imported_modules) { std::lock_guard guard(GetModuleMutex()); - assert(sc.comp_unit); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + SymbolFileDWARF *dwarf_check; + DWARFUnit *dwarf_cu = sc.GetDWARFCompileUnit(&dwarf_check); + lldbassert(dwarf_check == this); if (!dwarf_cu) return false; if (!ClangModulesDeclVendor::LanguageSupportsClangModules( @@ -1135,7 +1149,8 @@ block = parent_block; } else { - BlockSP block_sp(new Block(die.GetID())); + DWARFCompileUnit *dwarf_cu = comp_unit.GetDWARFCompileUnit(); + BlockSP block_sp(new Block(die.GetID(dwarf_cu))); parent_block->AddChild(block_sp); block = block_sp.get(); } @@ -1261,21 +1276,49 @@ decl_ctx); } -user_id_t SymbolFileDWARF::GetUID(DIERef ref) { +user_id_t SymbolFileDWARF::GetUID(DWARFUnit *main_unit, + const DWARFDIE &die) { + if (!die.IsValid()) + return LLDB_INVALID_UID; + // if (die.GetCU()->GetUnitDIEOnly().Tag() != DW_TAG_partial_unit) + main_unit = nullptr; + return GetUID(main_unit, die.GetDIERef(main_unit)); +} + +user_id_t SymbolFileDWARF::GetUID(DWARFUnit *main_unit, DIERef ref) { if (GetDebugMapSymfile()) return GetID() | ref.die_offset(); - lldbassert(GetDwoNum().getValueOr(0) <= 0x3fffffff); - return user_id_t(GetDwoNum().getValueOr(0)) << 32 | ref.die_offset() | - lldb::user_id_t(GetDwoNum().hasValue()) << 62 | + if (main_unit) + main_unit = &main_unit->GetNonSkeletonUnit(); + if (ref.dwo_num().hasValue()) + lldbassert(main_unit == nullptr); + +#ifndef NDEBUG + DWARFDIE dwarfdie_check = GetDIE(ref); + lldbassert(dwarfdie_check.IsValid()); + lldbassert(*dwarfdie_check.GetDIERef(main_unit) == ref); +#endif + + // WARNING: Use ref.dwo_num() as GetDwoNum() may not be valid in 'this'. + static_assert(sizeof(ref.die_offset()) * 8 == 32, ""); + lldbassert(!ref.dwo_num().hasValue()||*ref.dwo_num()<=0x3fffffff); + user_id_t retval = user_id_t(ref.dwo_num().getValueOr(0)) << 32 | + ref.die_offset() | + lldb::user_id_t(ref.dwo_num().hasValue()) << 62 | lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63; + +#ifndef NDEBUG + DWARFUnit *main_unit_check; + DWARFDIE dwarfdie_check2 = GetDIEUnlocked(retval, &main_unit_check); + lldbassert(dwarfdie_check2 == dwarfdie_check); +#endif + + return retval; } llvm::Optional -SymbolFileDWARF::DecodeUID(lldb::user_id_t uid) { - // This method can be called without going through the symbol vendor so we - // need to lock the module. - std::lock_guard guard(GetModuleMutex()); +SymbolFileDWARF::DecodeUIDUnlocked(lldb::user_id_t uid) { // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple @@ -1304,20 +1347,37 @@ return DecodedUID{*this, {dwo_num, section, die_offset}}; } -DWARFDIE -SymbolFileDWARF::GetDIE(lldb::user_id_t uid) { +llvm::Optional +SymbolFileDWARF::DecodeUID(lldb::user_id_t uid) { // This method can be called without going through the symbol vendor so we // need to lock the module. std::lock_guard guard(GetModuleMutex()); - llvm::Optional decoded = DecodeUID(uid); + return DecodeUIDUnlocked(uid); +} - if (decoded) - return decoded->dwarf.GetDIE(decoded->ref); +DWARFDIE +SymbolFileDWARF::GetDIEUnlocked(lldb::user_id_t uid, + DWARFUnit **main_unit_return) { + llvm::Optional decoded = DecodeUIDUnlocked(uid); + + if (decoded) { + DWARFDIE die = decoded->dwarf.GetDIE(decoded->ref, main_unit_return); + return die; + } return DWARFDIE(); } +DWARFDIE +SymbolFileDWARF::GetDIE(lldb::user_id_t uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); + + return GetDIEUnlocked(uid); +} + CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { // This method can be called without going through the symbol vendor so we // need to lock the module. @@ -1325,8 +1385,9 @@ // 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); + DWARFUnit *main_unit; + if (DWARFDIE die = GetDIEUnlocked(type_uid, &main_unit)) + return GetDecl(main_unit, die); return CompilerDecl(); } @@ -1338,8 +1399,9 @@ // 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); + DWARFUnit *main_unit; + if (DWARFDIE die = GetDIEUnlocked(type_uid, &main_unit)) + return GetDeclContext(main_unit, die); return CompilerDeclContext(); } @@ -1349,8 +1411,9 @@ // 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); + DWARFUnit *main_unit; + if (DWARFDIE die = GetDIEUnlocked(type_uid, &main_unit)) + return GetContainingDeclContext(main_unit, die); return CompilerDeclContext(); } @@ -1359,8 +1422,9 @@ // 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 type_die = GetDIE(type_uid)) - return type_die.ResolveType(); + DWARFUnit *main_unit; + if (DWARFDIE type_die = GetDIEUnlocked(type_uid, &main_unit)) + return type_die.ResolveType(main_unit); else return nullptr; } @@ -1375,11 +1439,13 @@ return llvm::None; } -Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) { - return ResolveType(GetDIE(die_ref), true); +Type *SymbolFileDWARF::ResolveTypeUID(DWARFUnit *main_unit, + const DIERef &die_ref) { + return ResolveType(main_unit, GetDIE(die_ref), true); } -Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die, +Type *SymbolFileDWARF::ResolveTypeUID(DWARFUnit *main_unit, + const DWARFDIE &die, bool assert_not_being_parsed) { if (die) { Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); @@ -1413,7 +1479,7 @@ } } } - return ResolveType(die); + return ResolveType(main_unit, die); } return nullptr; } @@ -1463,7 +1529,8 @@ return true; } - DWARFDIE dwarf_die = GetDIE(die_it->getSecond()); + DWARFUnit *main_unit; + DWARFDIE dwarf_die = GetDIEUnlocked(die_it->getSecond(), &main_unit); if (dwarf_die) { // Once we start resolving this type, remove it from the forward // declaration map in case anyone child members or other types require this @@ -1471,27 +1538,29 @@ // to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done. GetForwardDeclClangTypeToDie().erase(die_it); - Type *type = GetDIEToType().lookup(dwarf_die.GetDIE()); + Type *type = GetDIEToType().lookup(dwarf_die.MainCUtoDIEPair(main_unit)); + lldbassert(type); Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION)); if (log) GetObjectFile()->GetModule()->LogMessageVerboseBacktrace( log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", - dwarf_die.GetID(), dwarf_die.GetTagAsCString(), + dwarf_die.GetID(nullptr), dwarf_die.GetTagAsCString(), type->GetName().AsCString()); assert(compiler_type); - if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU())) - return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type); + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetMainDWARFUnit(main_unit))) + return dwarf_ast->CompleteTypeFromDWARF(main_unit, dwarf_die, type, compiler_type); } return false; } -Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die, +Type *SymbolFileDWARF::ResolveType(DWARFUnit *main_unit, + const DWARFDIE &die, bool assert_not_being_parsed, bool resolve_function_context) { if (die) { - Type *type = GetTypeForDIE(die, resolve_function_context).get(); + Type *type = GetTypeForDIE(main_unit, die, resolve_function_context).get(); if (assert_not_being_parsed) { if (type != DIE_IS_BEING_PARSED) @@ -1526,29 +1595,32 @@ } void SymbolFileDWARF::GetObjCMethods( - ConstString class_name, llvm::function_ref callback) { + ConstString class_name, + llvm::function_ref + callback) { m_index->GetObjCMethods(class_name, callback); } -bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) { +bool SymbolFileDWARF::GetFunction(DWARFUnit *main_unit, + const DWARFDIE &die, SymbolContext &sc) { sc.Clear(false); + if (!die) + return false; - if (die && llvm::isa(die.GetCU())) { - // Check if the symbol vendor already knows about this compile unit? - sc.comp_unit = - GetCompUnitForDWARFCompUnit(llvm::cast(*die.GetCU())); - - sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get(); - if (sc.function == nullptr) - sc.function = ParseFunction(*sc.comp_unit, die); + // Check if the symbol vendor already knows about this compile unit? + DWARFCompileUnit *main_cu = llvm::dyn_cast_or_null(main_unit); + if (!main_cu) + return false; + sc.comp_unit = main_cu->GetCompUnit(); - if (sc.function) { - sc.module_sp = sc.function->CalculateSymbolContextModule(); - return true; - } - } + sc.function = sc.comp_unit->FindFunctionByUID(die.GetID(main_unit)).get(); + if (sc.function == nullptr) + sc.function = ParseFunction(*sc.comp_unit, die); + if (sc.function == nullptr) + return false; - return false; + sc.module_sp = sc.function->CalculateSymbolContextModule(); + return true; } lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) { @@ -1561,17 +1633,17 @@ } DWARFDIE -SymbolFileDWARF::GetDIE(const DIERef &die_ref) { +SymbolFileDWARF::GetDIE(const DIERef &die_ref, DWARFUnit **main_unit_return) { if (die_ref.dwo_num()) { SymbolFileDWARF *dwarf = *die_ref.dwo_num() == 0x3fffffff ? m_dwp_symfile.get() : this->DebugInfo() .GetUnitAtIndex(*die_ref.dwo_num()) ->GetDwoSymbolFile(); - return dwarf->DebugInfo().GetDIE(die_ref); + return dwarf->DebugInfo().GetDIE(die_ref, main_unit_return); } - return DebugInfo().GetDIE(die_ref); + return DebugInfo().GetDIE(die_ref, main_unit_return); } /// Return the DW_AT_(GNU_)dwo_name. @@ -1809,13 +1881,14 @@ void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr, bool lookup_block, SymbolContext &sc) { - assert(sc.comp_unit); - DWARFCompileUnit &cu = - GetDWARFCompileUnit(sc.comp_unit)->GetNonSkeletonUnit(); - DWARFDIE function_die = cu.LookupAddress(file_vm_addr); + DWARFCompileUnit *cu = sc.GetDWARFCompileUnit(); + lldbassert(cu); + cu = &cu->GetNonSkeletonUnit(); + DWARFDIE function_die = cu->LookupAddress(file_vm_addr); DWARFDIE block_die; if (function_die) { - sc.function = sc.comp_unit->FindFunctionByUID(function_die.GetID()).get(); + sc.function = + sc.comp_unit->FindFunctionByUID(function_die.GetID(cu)).get(); if (sc.function == nullptr) sc.function = ParseFunction(*sc.comp_unit, function_die); @@ -1828,9 +1901,9 @@ Block &block = sc.function->GetBlock(true); if (block_die) - sc.block = block.FindBlockByID(block_die.GetID()); + sc.block = block.FindBlockByID(block_die.GetID(cu)); else - sc.block = block.FindBlockByID(function_die.GetID()); + sc.block = block.FindBlockByID(function_die.GetID(cu)); } uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, @@ -2111,41 +2184,42 @@ uint32_t pruned_idx = original_size; SymbolContext sc; - m_index->GetGlobalVariables(ConstString(basename), [&](DWARFDIE die) { - if (!sc.module_sp) - sc.module_sp = m_objfile_sp->GetModule(); - assert(sc.module_sp); - - if (die.Tag() != DW_TAG_variable) - return true; + m_index->GetGlobalVariables( + ConstString(basename), [&](DWARFUnit *main_unit, DWARFDIE die) { + if (!sc.module_sp) + sc.module_sp = m_objfile_sp->GetModule(); + assert(sc.module_sp); - auto *dwarf_cu = llvm::dyn_cast(die.GetCU()); - if (!dwarf_cu) - return true; - sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); - - if (parent_decl_ctx) { - if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) { - CompilerDeclContext actual_parent_decl_ctx = - dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); - if (!actual_parent_decl_ctx || - actual_parent_decl_ctx != parent_decl_ctx) + if (die.Tag() != DW_TAG_variable) return true; - } - } - ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); - while (pruned_idx < variables.GetSize()) { - VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx); - if (name_is_mangled || - var_sp->GetName().GetStringRef().contains(name.GetStringRef())) - ++pruned_idx; - else - variables.RemoveVariableAtIndex(pruned_idx); - } + DWARFCompileUnit *main_cu = llvm::dyn_cast_or_null(main_unit); + if (!main_cu) + return false; + sc.comp_unit = main_cu->GetCompUnit(); + + if (parent_decl_ctx) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainDWARFUnit(main_unit))) { + CompilerDeclContext actual_parent_decl_ctx = + dwarf_ast->GetDeclContextContainingUIDFromDWARF(main_unit, die); + if (!actual_parent_decl_ctx || + actual_parent_decl_ctx != parent_decl_ctx) + return true; + } + } - return variables.GetSize() - original_size < max_matches; - }); + ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); + while (pruned_idx < variables.GetSize()) { + VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx); + if (name_is_mangled || + var_sp->GetName().GetStringRef().contains(name.GetStringRef())) + ++pruned_idx; + else + variables.RemoveVariableAtIndex(pruned_idx); + } + + return variables.GetSize() - original_size < max_matches; + }); // Return the number of variable that were appended to the list const uint32_t num_matches = variables.GetSize() - original_size; @@ -2177,23 +2251,25 @@ const uint32_t original_size = variables.GetSize(); SymbolContext sc; - m_index->GetGlobalVariables(regex, [&](DWARFDIE die) { - if (!sc.module_sp) - sc.module_sp = m_objfile_sp->GetModule(); - assert(sc.module_sp); + m_index->GetGlobalVariables( + regex, [&](DWARFUnit *main_unit, DWARFDIE die) { + if (!sc.module_sp) + sc.module_sp = m_objfile_sp->GetModule(); + assert(sc.module_sp); - DWARFCompileUnit *dwarf_cu = llvm::dyn_cast(die.GetCU()); - if (!dwarf_cu) - return true; - sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); + DWARFCompileUnit *main_cu = llvm::dyn_cast_or_null(main_unit); + if (!main_cu) + return false; + sc.comp_unit = main_cu->GetCompUnit(); - ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); + ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); - return variables.GetSize() - original_size < max_matches; - }); + return variables.GetSize() - original_size < max_matches; + }); } -bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, +bool SymbolFileDWARF::ResolveFunction(DWARFUnit *main_unit, + const DWARFDIE &orig_die, bool include_inlines, SymbolContextList &sc_list) { SymbolContext sc; @@ -2222,12 +2298,12 @@ } } assert(die && die.Tag() == DW_TAG_subprogram); - if (GetFunction(die, sc)) { + if (GetFunction(main_unit, die, sc)) { Address addr; // Parse all blocks if needed if (inlined_die) { Block &function_block = sc.function->GetBlock(true); - sc.block = function_block.FindBlockByID(inlined_die.GetID()); + sc.block = function_block.FindBlockByID(inlined_die.GetID(main_unit)); if (sc.block == nullptr) sc.block = function_block.FindBlockByID(inlined_die.GetOffset()); if (sc.block == nullptr || !sc.block->GetStartAddress(addr)) @@ -2250,6 +2326,7 @@ } bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx, + DWARFUnit *main_unit, const DWARFDIE &die) { // 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 @@ -2258,9 +2335,10 @@ return true; if (die) { - if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) { + if (DWARFASTParser *dwarf_ast = + GetDWARFParser(*die.GetMainDWARFUnit(main_unit))) { if (CompilerDeclContext actual_decl_ctx = - dwarf_ast->GetDeclContextContainingUIDFromDWARF(die)) + dwarf_ast->GetDeclContextContainingUIDFromDWARF(main_unit, die)) return decl_ctx.IsContainedInLookup(actual_decl_ctx); } } @@ -2301,14 +2379,17 @@ const uint32_t original_size = sc_list.GetSize(); - llvm::DenseSet resolved_dies; + llvm::DenseSet> + resolved_dies; - m_index->GetFunctions(name, *this, parent_decl_ctx, name_type_mask, - [&](DWARFDIE die) { - if (resolved_dies.insert(die.GetDIE()).second) - ResolveFunction(die, include_inlines, sc_list); - return true; - }); + m_index->GetFunctions( + name, *this, parent_decl_ctx, name_type_mask, + [&](DWARFUnit *main_unit, DWARFDIE die) { + if (resolved_dies.insert(std::make_pair(main_unit, die.GetDIE())) + .second) + ResolveFunction(main_unit, die, include_inlines, sc_list); + return true; + }); // Return the number of variable that were appended to the list const uint32_t num_matches = sc_list.GetSize() - original_size; @@ -2338,10 +2419,11 @@ regex.GetText().str().c_str()); } - llvm::DenseSet resolved_dies; - m_index->GetFunctions(regex, [&](DWARFDIE die) { - if (resolved_dies.insert(die.GetDIE()).second) - ResolveFunction(die, include_inlines, sc_list); + llvm::DenseSet> + resolved_dies; + m_index->GetFunctions(regex, [&](DWARFUnit *main_unit, DWARFDIE die) { + if (resolved_dies.insert(std::make_pair(main_unit, die.GetDIE())).second) + ResolveFunction(main_unit, die, include_inlines, sc_list); return true; }); } @@ -2399,11 +2481,11 @@ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return; - m_index->GetTypes(name, [&](DWARFDIE die) { - if (!DIEInDeclContext(parent_decl_ctx, die)) + m_index->GetTypes(name, [&](DWARFUnit *main_unit, DWARFDIE die) { + if (!DIEInDeclContext(parent_decl_ctx, main_unit, die)) return true; // The containing decl contexts don't match - Type *matching_type = ResolveType(die, true, true); + Type *matching_type = ResolveType(main_unit, die, true, true); if (!matching_type) return true; @@ -2461,8 +2543,8 @@ if (!name) return; - m_index->GetTypes(name, [&](DWARFDIE die) { - if (!languages[GetLanguage(*die.GetCU())]) + m_index->GetTypes(name, [&](DWARFUnit *main_unit, DWARFDIE die) { + if (!languages[GetLanguage(*die.GetMainDWARFUnit(main_unit))]) return true; llvm::SmallVector die_context; @@ -2470,7 +2552,7 @@ if (!contextMatches(die_context, pattern)) return true; - if (Type *matching_type = ResolveType(die, true, true)) { + if (Type *matching_type = ResolveType(main_unit, die, true, true)) { // We found a type pointer, now find the shared pointer form our type // list. types.InsertUnique(matching_type->shared_from_this()); @@ -2506,15 +2588,16 @@ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return namespace_decl_ctx; - m_index->GetNamespaces(name, [&](DWARFDIE die) { - if (!DIEInDeclContext(parent_decl_ctx, die)) + m_index->GetNamespaces(name, [&](DWARFUnit *main_unit, DWARFDIE die) { + if (!DIEInDeclContext(parent_decl_ctx, main_unit, die)) return true; // The containing decl contexts don't match - DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); + DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainDWARFUnit(main_unit)); if (!dwarf_ast) return true; - namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die); + namespace_decl_ctx = + dwarf_ast->GetDeclContextForUIDFromDWARF(main_unit, die); return !namespace_decl_ctx.IsValid(); }); @@ -2532,15 +2615,17 @@ return namespace_decl_ctx; } -TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die, +TypeSP SymbolFileDWARF::GetTypeForDIE(DWARFUnit *main_unit, + const DWARFDIE &die, bool resolve_function_context) { TypeSP type_sp; if (die) { - Type *type_ptr = GetDIEToType().lookup(die.GetDIE()); + Type *type_ptr = GetDIEToType().lookup(die.MainCUtoDIEPair(main_unit)); if (type_ptr == nullptr) { SymbolContextScope *scope; - if (auto *dwarf_cu = llvm::dyn_cast(die.GetCU())) - scope = GetCompUnitForDWARFCompUnit(*dwarf_cu); + DWARFCompileUnit *main_cu = llvm::dyn_cast_or_null(main_unit); + if (main_cu) + scope = main_cu->GetCompUnit(); else scope = GetObjectFile()->GetModule().get(); assert(scope); @@ -2553,7 +2638,7 @@ } SymbolContext sc_backup = sc; if (resolve_function_context && parent_die != nullptr && - !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc)) + !GetFunction(main_unit, DWARFDIE(die.GetCU(), parent_die), sc)) sc = sc_backup; type_sp = ParseType(sc, die, nullptr); @@ -2672,7 +2757,8 @@ return type_sp; m_index->GetCompleteObjCClass( - type_name, must_be_implementation, [&](DWARFDIE type_die) { + type_name, must_be_implementation, + [&](DWARFUnit *main_unit, DWARFDIE type_die) { bool try_resolving_type = false; // Don't try and resolve the DIE we are looking for with the DIE @@ -2697,7 +2783,7 @@ if (!try_resolving_type) return true; - Type *resolved_type = ResolveType(type_die, false, true); + Type *resolved_type = ResolveType(main_unit, type_die, false, true); if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) return true; @@ -2709,7 +2795,7 @@ type_die.GetID(), type_cu->GetID()); if (die) - GetDIEToType()[die.GetDIE()] = resolved_type; + GetDIEToType()[die.MainCUtoDIEPair(main_unit)] = resolved_type; type_sp = resolved_type->shared_from_this(); return false; }); @@ -2843,12 +2929,13 @@ } } - m_index->GetTypes(dwarf_decl_ctx, [&](DWARFDIE type_die) { + m_index->GetTypes(dwarf_decl_ctx, [&](DWARFUnit *main_unit, + DWARFDIE type_die) { // Make sure type_die's langauge matches the type system we are // 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(*type_die.GetMainDWARFUnit(main_unit)))) return true; bool try_resolving_type = false; @@ -2897,7 +2984,7 @@ return true; } - DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die); + DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(main_unit, type_die); if (log) { GetObjectFile()->GetModule()->LogMessage( @@ -2914,7 +3001,7 @@ if (dwarf_decl_ctx != type_dwarf_decl_ctx) return true; - Type *resolved_type = ResolveType(type_die, false); + Type *resolved_type = ResolveType(main_unit, type_die, false); if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) return true; @@ -2931,7 +3018,8 @@ if (!die) return {}; - auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(); + auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetMainDWARFUnit(main_unit))); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), std::move(err), "Unable to parse type"); @@ -2947,12 +3035,13 @@ GetTypeList().Insert(type_sp); if (die.Tag() == DW_TAG_subprogram) { - std::string scope_qualified_name(GetDeclContextForUID(die.GetID()) - .GetScopeQualifiedName() - .AsCString("")); + std::string scope_qualified_name( + GetDeclContextForUID(die.GetID(main_unit)) + .GetScopeQualifiedName() + .AsCString("")); if (scope_qualified_name.size()) { m_function_scope_qualified_name_map[scope_qualified_name].insert( - *die.GetDIERef()); + *die.GetDIERef(main_unit)); } } } @@ -2983,8 +3072,10 @@ if (parse_children && die.HasChildren()) { if (die.Tag() == DW_TAG_subprogram) { + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(); SymbolContext child_sc(sc); - child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get(); + child_sc.function = + sc.comp_unit->FindFunctionByUID(die.GetID(main_unit)).get(); types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true); } else types_added += ParseTypes(sc, die.GetFirstChild(), true, true); @@ -3028,6 +3119,7 @@ if (dwarf_cu_die && dwarf_cu_die.HasChildren()) { SymbolContext sc; sc.comp_unit = &comp_unit; + sc.module_sp = sc.comp_unit->GetModule(); types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true); } } @@ -3056,10 +3148,10 @@ return num_variables; } } else if (sc.comp_unit) { - DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(sc.comp_unit->GetID()); - - if (dwarf_cu == nullptr) + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(); + if (!main_unit) return 0; + main_unit = &main_unit->GetNonSkeletonUnit(); uint32_t vars_added = 0; VariableListSP variables(sc.comp_unit->GetVariableList(false)); @@ -3069,7 +3161,9 @@ sc.comp_unit->SetVariableList(variables); m_index->GetGlobalVariables( - dwarf_cu->GetNonSkeletonUnit(), [&](DWARFDIE die) { + *main_unit, + [&](DWARFUnit *main_unit_check, DWARFDIE die) { + lldbassert(main_unit_check == main_unit || main_unit_check == nullptr); VariableSP var_sp( ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS)); if (var_sp) { @@ -3088,13 +3182,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, const DWARFDIE &die, const lldb::addr_t func_low_pc) { - if (die.GetDWARF() != this) - return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc); + // if (die.GetDWARF() != this) + // return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc); if (!die) return nullptr; - if (VariableSP var_sp = GetDIEToVariable()[die.GetDIE()]) + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(); + + if (VariableSP var_sp = GetDIEToVariable()[die.MainCUtoDIEPair(main_unit)]) return var_sp; // Already been parsed! const dw_tag_t tag = die.Tag(); @@ -3258,9 +3354,9 @@ // declaration context. if ((parent_tag == DW_TAG_compile_unit || parent_tag == DW_TAG_partial_unit) && - Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU()))) + Language::LanguageIsCPlusPlus(GetLanguage(*die.GetMainDWARFUnit(main_unit)))) mangled = - GetDWARFDeclContext(die).GetQualifiedNameAsConstString().GetCString(); + GetDWARFDeclContext(main_unit, die).GetQualifiedNameAsConstString().GetCString(); } if (tag == DW_TAG_formal_parameter) @@ -3393,7 +3489,7 @@ case DW_TAG_lexical_block: if (sc.function) { symbol_context_scope = - sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); + sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID(main_unit)); if (symbol_context_scope == nullptr) symbol_context_scope = sc.function; } @@ -3407,7 +3503,7 @@ if (symbol_context_scope) { auto type_sp = std::make_shared( - *this, GetUID(type_die_form.Reference())); + *this, GetUID(main_unit, type_die_form.Reference())); if (use_type_size_for_value && type_sp->GetType()) location.UpdateValue( @@ -3416,7 +3512,7 @@ die.GetCU()->GetAddressByteSize()); var_sp = std::make_shared( - die.GetID(), name, mangled, type_sp, scope, symbol_context_scope, + die.GetID(main_unit), name, mangled, type_sp, scope, symbol_context_scope, scope_ranges, &decl, location, is_external, is_artificial, location_is_const_value_data, is_static_member); } else { @@ -3429,9 +3525,9 @@ // missing vital information to be able to be displayed in the debugger // (missing location due to optimization, etc)) so we don't re-parse this // DIE over and over later... - GetDIEToVariable()[die.GetDIE()] = var_sp; + GetDIEToVariable()[die.MainCUtoDIEPair(main_unit)] = var_sp; if (spec_die) - GetDIEToVariable()[spec_die.GetDIE()] = var_sp; + GetDIEToVariable()[spec_die.MainCUtoDIEPair(main_unit)] = var_sp; return var_sp; } @@ -3490,6 +3586,7 @@ return 0; VariableListSP variable_list_sp; + DWARFUnit *main_unit = sc.GetDWARFCompileUnit(); size_t vars_added = 0; DWARFDIE die = orig_die; @@ -3497,7 +3594,7 @@ dw_tag_t tag = die.Tag(); // Check to see if we have already parsed this variable or constant? - VariableSP var_sp = GetDIEToVariable()[die.GetDIE()]; + VariableSP var_sp = GetDIEToVariable()[die.MainCUtoDIEPair(main_unit)]; if (var_sp) { if (cc_variable_list) cc_variable_list->AddVariableIfUnique(var_sp); @@ -3520,8 +3617,8 @@ GetObjectFile()->GetModule()->ReportError( "parent 0x%8.8" PRIx64 " %s with no valid compile unit in " "symbol context for 0x%8.8" PRIx64 " %s.\n", - sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(), - orig_die.GetID(), orig_die.GetTagAsCString()); + sc_parent_die.GetID(nullptr), sc_parent_die.GetTagAsCString(), + orig_die.GetID(nullptr), orig_die.GetTagAsCString()); } break; @@ -3533,7 +3630,7 @@ // given scope Block *block = sc.function->GetBlock(true).FindBlockByID( - sc_parent_die.GetID()); + sc_parent_die.GetID(main_unit)); if (block == nullptr) { // This must be a specification or abstract origin with a // concrete block counterpart in the current function. We need @@ -3545,7 +3642,7 @@ sc_parent_die.GetOffset()); if (concrete_block_die) block = sc.function->GetBlock(true).FindBlockByID( - concrete_block_die.GetID()); + concrete_block_die.GetID(main_unit)); } if (block != nullptr) { @@ -3563,7 +3660,7 @@ GetObjectFile()->GetModule()->ReportError( "didn't find appropriate parent DIE for variable list for " "0x%8.8" PRIx64 " %s.\n", - orig_die.GetID(), orig_die.GetTagAsCString()); + orig_die.GetID(nullptr), orig_die.GetTagAsCString()); break; } } @@ -3892,31 +3989,34 @@ return type_system_or_err->GetDWARFParser(); } -CompilerDecl SymbolFileDWARF::GetDecl(const DWARFDIE &die) { - if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) - return dwarf_ast->GetDeclForUIDFromDWARF(die); +CompilerDecl SymbolFileDWARF::GetDecl(DWARFUnit *main_unit, + const DWARFDIE &die) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainDWARFUnit(main_unit))) + return dwarf_ast->GetDeclForUIDFromDWARF(main_unit, die); return CompilerDecl(); } -CompilerDeclContext SymbolFileDWARF::GetDeclContext(const DWARFDIE &die) { - if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) - return dwarf_ast->GetDeclContextForUIDFromDWARF(die); +CompilerDeclContext SymbolFileDWARF::GetDeclContext(DWARFUnit *main_unit, + const DWARFDIE &die) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainDWARFUnit(main_unit))) + return dwarf_ast->GetDeclContextForUIDFromDWARF(main_unit, die); return CompilerDeclContext(); } CompilerDeclContext -SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) { - if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) - return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); +SymbolFileDWARF::GetContainingDeclContext(DWARFUnit *main_unit, + const DWARFDIE &die) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainDWARFUnit(main_unit))) + return dwarf_ast->GetDeclContextContainingUIDFromDWARF(main_unit, die); return CompilerDeclContext(); } -DWARFDeclContext SymbolFileDWARF::GetDWARFDeclContext(const DWARFDIE &die) { +DWARFDeclContext SymbolFileDWARF::GetDWARFDeclContext(DWARFUnit *main_unit, const DWARFDIE &die) { if (!die.IsValid()) return {}; DWARFDeclContext dwarf_decl_ctx = - die.GetDIE()->GetDWARFDeclContext(die.GetCU()); - dwarf_decl_ctx.SetLanguage(GetLanguage(*die.GetCU())); + die.GetDIE()->GetDWARFDeclContext(die.GetCU()); // DIE.GetCU(), not main_unit. + dwarf_decl_ctx.SetLanguage(GetLanguage(*die.GetMainDWARFUnit(main_unit))); return dwarf_decl_ctx; } 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 @@ -376,6 +376,8 @@ size_t AddOSOARanges(SymbolFileDWARF *dwarf2Data, DWARFDebugAranges *debug_aranges); + + DWARFCompileUnit *GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H 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 @@ -1440,3 +1440,9 @@ } return num_line_entries_added; } + +DWARFCompileUnit *SymbolFileDWARFDebugMap::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { + if (!comp_unit) + return nullptr; + return GetSymbolFile(*comp_unit)->GetDWARFCompileUnit(comp_unit); +} 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 @@ -31,17 +31,21 @@ DWARFCompileUnit *GetDWOCompileUnitForHash(uint64_t hash); - void GetObjCMethods(lldb_private::ConstString class_name, - llvm::function_ref callback) override; + void GetObjCMethods( + lldb_private::ConstString class_name, + llvm::function_ref + callback) override; llvm::Expected GetTypeSystemForLanguage(lldb::LanguageType language) override; DWARFDIE - GetDIE(const DIERef &die_ref) override; + GetDIE(const DIERef &die_ref, DWARFUnit **main_unit_return = nullptr) override; llvm::Optional GetDwoNum() override { return GetID() >> 32; } + SymbolFileDWARF &GetBaseSymbolFile() { return m_base_symbol_file; } + protected: DIEToTypePtr &GetDIEToType() override; @@ -60,8 +64,6 @@ const DWARFDIE &die, lldb_private::ConstString type_name, bool must_be_implementation) override; - SymbolFileDWARF &GetBaseSymbolFile() { return m_base_symbol_file; } - /// If this file contains exactly one compile unit, this function will return /// it. Otherwise it returns nullptr. DWARFCompileUnit *FindSingleCompileUnit(); 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 @@ -96,7 +96,8 @@ void SymbolFileDWARFDwo::GetObjCMethods( lldb_private::ConstString class_name, - llvm::function_ref callback) { + llvm::function_ref + callback) { GetBaseSymbolFile().GetObjCMethods(class_name, callback); } @@ -123,8 +124,8 @@ } DWARFDIE -SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { +SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref, DWARFUnit **main_unit_return) { if (die_ref.dwo_num() == GetDwoNum()) - return DebugInfo().GetDIE(die_ref); - return GetBaseSymbolFile().GetDIE(die_ref); + return DebugInfo().GetDIE(die_ref, main_unit_return); + return GetBaseSymbolFile().GetDIE(die_ref, main_unit_return); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h --- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h @@ -20,18 +20,18 @@ public: // Constructors and Destructors UniqueDWARFASTType() - : m_type_sp(), m_die(), m_declaration(), + : m_type_sp(), m_main_unit(nullptr), m_die(), m_declaration(), m_byte_size( -1) // Set to negative value to make sure we have a valid value {} - UniqueDWARFASTType(lldb::TypeSP &type_sp, const DWARFDIE &die, + UniqueDWARFASTType(lldb::TypeSP &type_sp, DWARFUnit *main_unit, const DWARFDIE &die, const lldb_private::Declaration &decl, int32_t byte_size) - : m_type_sp(type_sp), m_die(die), m_declaration(decl), + : m_type_sp(type_sp), m_main_unit(main_unit), m_die(die), m_declaration(decl), m_byte_size(byte_size) {} UniqueDWARFASTType(const UniqueDWARFASTType &rhs) - : m_type_sp(rhs.m_type_sp), m_die(rhs.m_die), + : m_type_sp(rhs.m_type_sp), m_main_unit(rhs.m_main_unit), m_die(rhs.m_die), m_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size) {} ~UniqueDWARFASTType() {} @@ -39,6 +39,7 @@ UniqueDWARFASTType &operator=(const UniqueDWARFASTType &rhs) { if (this != &rhs) { m_type_sp = rhs.m_type_sp; + m_main_unit = rhs.m_main_unit; m_die = rhs.m_die; m_declaration = rhs.m_declaration; m_byte_size = rhs.m_byte_size; @@ -47,6 +48,7 @@ } lldb::TypeSP m_type_sp; + DWARFUnit *m_main_unit; DWARFDIE m_die; lldb_private::Declaration m_declaration; int32_t m_byte_size; @@ -64,7 +66,7 @@ m_collection.push_back(entry); } - bool Find(const DWARFDIE &die, const lldb_private::Declaration &decl, + bool Find(DWARFUnit *main_unit, const DWARFDIE &die, const lldb_private::Declaration &decl, const int32_t byte_size, UniqueDWARFASTType &entry) const; protected: @@ -83,13 +85,13 @@ m_collection[name.GetCString()].Append(entry); } - bool Find(lldb_private::ConstString name, const DWARFDIE &die, + bool Find(lldb_private::ConstString name, DWARFUnit *main_unit, const DWARFDIE &die, const lldb_private::Declaration &decl, const int32_t byte_size, UniqueDWARFASTType &entry) const { const char *unique_name_cstr = name.GetCString(); collection::const_iterator pos = m_collection.find(unique_name_cstr); if (pos != m_collection.end()) { - return pos->second.Find(die, decl, byte_size, entry); + return pos->second.Find(main_unit, die, decl, byte_size, entry); } return false; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -10,13 +10,13 @@ #include "lldb/Symbol/Declaration.h" -bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die, +bool UniqueDWARFASTTypeList::Find(DWARFUnit *main_unit, const DWARFDIE &die, const lldb_private::Declaration &decl, const int32_t byte_size, UniqueDWARFASTType &entry) const { for (const UniqueDWARFASTType &udt : m_collection) { // Make sure the tags match - if (udt.m_die.Tag() == die.Tag()) { + if (udt.m_die.Tag() == die.Tag() && udt.m_main_unit == main_unit) { // Validate byte sizes of both types only if both are valid. if (udt.m_byte_size < 0 || byte_size < 0 || udt.m_byte_size == byte_size) { diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp --- a/lldb/source/Symbol/CompileUnit.cpp +++ b/lldb/source/Symbol/CompileUnit.cpp @@ -368,3 +368,10 @@ } void *CompileUnit::GetUserData() const { return m_user_data; } + +DWARFCompileUnit *CompileUnit::GetDWARFCompileUnit() { + SymbolFile *symfile = GetModule()->GetSymbolFile(); + if (!symfile) + return nullptr; + return symfile->GetDWARFCompileUnit(this); +} diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -22,6 +22,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" +#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" using namespace lldb; using namespace lldb_private; @@ -1322,3 +1323,22 @@ const SymbolContextList &rhs) { return !(lhs == rhs); } + +DWARFCompileUnit *SymbolContext::GetDWARFCompileUnit(SymbolFileDWARF **dwarf_return) const { + SymbolFileDWARF *dwarf = nullptr; + if (module_sp) + dwarf = llvm::dyn_cast(module_sp->GetSymbolFile()); + DWARFCompileUnit *retval = nullptr; + if (comp_unit == nullptr) + lldbassert(dwarf); + else { + retval = comp_unit->GetDWARFCompileUnit(); + if (dwarf) + lldbassert(dwarf == &retval->GetSymbolFileDWARF()); + else + dwarf = &retval->GetSymbolFileDWARF(); + } + if (dwarf_return) + *dwarf_return = dwarf; + return retval; +} diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -209,8 +209,11 @@ } CompilerDecl Variable::GetDecl() { - Type *type = GetType(); - return type ? type->GetSymbolFile()->GetDeclForUID(GetID()) : CompilerDecl(); + if (!m_symfile_type_sp) + return {}; + // GetType()->GetSymbolFile() may be a different file - the file where type + // of this variable is defined but not the file of this variable definition. + return m_symfile_type_sp->GetSymbolFile().GetDeclForUID(GetID()); } void Variable::CalculateSymbolContext(SymbolContext *sc) { 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 @@ -95,7 +95,7 @@ TypeSystemClang ast_ctx("dummy ASTContext", HostInfoBase::GetTargetTriple()); DWARFASTParserClangStub ast_parser(ast_ctx); - DWARFUnit *unit = t.GetDwarfUnit(); + DWARFCompileUnit *unit = llvm::cast(t.GetDwarfUnit()); const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE(); const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild(); const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling(); @@ -108,7 +108,7 @@ (clang::DeclContext *)1LL, (clang::DeclContext *)2LL, (clang::DeclContext *)2LL, (clang::DeclContext *)3LL}; for (int i = 0; i < 4; ++i) - ast_parser.LinkDeclContextToDIE(decl_ctxs[i], dies[i]); + ast_parser.LinkDeclContextToDIE(decl_ctxs[i], unit, dies[i]); ast_parser.EnsureAllDIEsInDeclContextHaveBeenParsed( CompilerDeclContext(nullptr, decl_ctxs[1]));