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,44 @@ 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 &main_unit, + 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 &cu, - llvm::function_ref callback) override; - void GetObjCMethods(ConstString class_name, - llvm::function_ref callback) override; + GetObjCMethods(ConstString class_name, + llvm::function_ref + callback) override; void GetCompleteObjCClass( ConstString class_name, bool must_be_implementation, - llvm::function_ref callback) override; + llvm::function_ref callback) + override; void GetTypes(ConstString name, - llvm::function_ref callback) override; + llvm::function_ref + callback) override; void GetTypes(const DWARFDeclContext &context, - llvm::function_ref callback) override; - void GetNamespaces(ConstString name, - llvm::function_ref callback) override; + 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; + llvm::function_ref + callback) override; void GetFunctions(const RegularExpression ®ex, - llvm::function_ref callback) override; + 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,8 @@ } 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 +64,7 @@ void AppleDWARFIndex::GetGlobalVariables( const RegularExpression ®ex, - llvm::function_ref callback) { + llvm::function_ref callback) { if (!m_apple_names_up) return; @@ -75,18 +76,20 @@ } 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(), - hash_data); + 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 +99,7 @@ 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 +109,8 @@ } 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 +119,7 @@ void AppleDWARFIndex::GetTypes( const DWARFDeclContext &context, - llvm::function_ref callback) { + llvm::function_ref callback) { if (!m_apple_types_up) return; @@ -169,7 +173,8 @@ } 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 +184,17 @@ 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 @@ -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,20 @@ class DelayedAddObjCClassProperty; typedef std::vector DelayedPropertyList; - typedef llvm::SmallPtrSet DIEPointerSet; - typedef llvm::DenseMap + typedef llvm::SmallSet, 4> + DIEPointerSet; + typedef llvm::DenseMap, + 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, + clang::Decl *> DIEToDeclMap; typedef llvm::DenseMap DeclToDIEMap; @@ -94,21 +102,24 @@ 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,9 +129,10 @@ lldb_private::ClangASTImporter::LayoutInfo &layout_info); size_t - ParseChildParameters(clang::DeclContext *containing_decl_ctx, - const DWARFDIE &parent_die, bool skip_artificial, - bool &is_static, bool &is_variadic, + 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, std::vector &function_args, std::vector &function_param_decls, @@ -135,24 +147,30 @@ 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, + clang::DeclContext *GetClangDeclContextContainingDIE(DWARFUnit *main_unit, + const DWARFDIE &die, DWARFDIE *decl_ctx_die); - lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &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 +210,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 +219,8 @@ 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 +230,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 = DWARFCompileUnit::GetMainUnit(sc, &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,8 @@ // The type in the Clang module must have the same language as the current CU. LanguageSet languages; - languages.Insert(SymbolFileDWARF::GetLanguage(*die.GetCU())); + languages.Insert( + 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 +213,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, - LLDB_INVALID_UID, Type::eEncodingInvalid, - &pcm_type_sp->GetDeclaration(), type, - Type::ResolveState::Forward, - TypePayloadClang(GetOwningClangModule(die)))); + 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(main_unit, die)))); dwarf->GetTypeList().Insert(type_sp); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.MainUnitToDIEPair(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 +451,12 @@ Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS)); - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = DWARFCompileUnit::GetMainUnit(sc, &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 +466,24 @@ die.GetTagAsCString(), die.GetName()); } - Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE()); + Type *type_ptr = + dwarf->GetDIEToType().lookup(die.MainUnitToDIEPair(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.MainUnitToDIEPair(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.MainUnitToDIEPair(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 +526,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 +557,11 @@ ParsedDWARFTypeAttributes &attrs) { Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS)); - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = DWARFCompileUnit::GetMainUnit(sc, &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 +572,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 +770,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.MainUnitToDIEPair(main_unit)] = type_sp.get(); return type_sp; } @@ -774,16 +784,18 @@ 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 = DWARFCompileUnit::GetMainUnit(sc, &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 +823,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.MainUnitToDIEPair(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 +836,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.MainUnitToDIEPair(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 +857,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 +892,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 = DWARFCompileUnit::GetMainUnit(sc, &dwarf); const dw_tag_t tag = die.Tag(); bool is_variadic = false; @@ -905,7 +922,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 +936,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 +950,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 +1012,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 +1025,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 +1040,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.MainUnitToDIEPair(main_unit)]; if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { return type_ptr->shared_from_this(); } @@ -1049,14 +1067,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 +1086,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 +1126,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 +1141,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 +1169,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 +1200,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.MainUnitToDIEPair(main_unit)] = NULL; // Now we get the full type to force our class type to // complete itself using the clang::ExternalASTSource @@ -1191,7 +1210,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.MainUnitToDIEPair(main_unit)]; if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { return type_ptr->shared_from_this(); } @@ -1215,12 +1235,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 +1261,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, - attrs.storage, attrs.is_inline); + 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 +1283,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 +1296,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 +1311,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 = DWARFCompileUnit::GetMainUnit(sc, &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 +1362,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 = DWARFCompileUnit::GetMainUnit(sc, &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 +1388,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 +1401,8 @@ if (!type_sp) return type_sp; - SymbolFileDWARF *dwarf = die.GetDWARF(); + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = DWARFCompileUnit::GetMainUnit(sc, &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 +1412,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 +1430,7 @@ // level. type_list.Insert(type_sp); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.MainUnitToDIEPair(main_unit)] = type_sp.get(); return type_sp; } @@ -1413,8 +1441,10 @@ 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 = DWARFCompileUnit::GetMainUnit(sc, &dwarf); + LanguageType cu_language = + SymbolFileDWARF::GetLanguage(*die.GetMainDWARFUnit(main_unit)); Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS); @@ -1439,13 +1469,14 @@ } if (dwarf->GetUniqueDWARFASTTypeMap().Find( - unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1), - *unique_ast_entry_up)) { + 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.MainUnitToDIEPair(main_unit)] = type_sp.get(); + LinkDeclContextToDIE(GetCachedClangDeclContextForDIE( + main_unit, unique_ast_entry_up->m_die), + main_unit, die); return type_sp; } } @@ -1519,7 +1550,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.MainUnitToDIEPair(main_unit)] = type_sp.get(); return type_sp; } } @@ -1546,7 +1577,8 @@ 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 +1607,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.MainUnitToDIEPair(main_unit)] = type_sp.get(); + DWARFUnit *type_main_unit; + DWARFDIE type_die = dwarf->GetDIE(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.MainUnitToDIEPair(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 +1638,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 +1663,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 +1677,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 +1686,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 +1697,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 +1756,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.MainUnitToDIEPair(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 +1850,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 +1861,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 +1900,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 +1961,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 +1976,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 +1986,19 @@ 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 a declaration. + // Then 'die' will be a definition in a different CU with different + // 'main_unit'. This assertion therefore would not work: + // lldbassert(&sc.GetDWARFCompileUnit(&dwarf)->GetNonSkeletonUnit() == + // sc.GetDWARFCompileUnit(&dwarf)); ClangASTImporter::LayoutInfo layout_info; @@ -1984,21 +2031,23 @@ std::vector member_function_dies; DelayedPropertyList delayed_properties; - ParseChildMembers(die, clang_type, bases, member_accessibilities, - member_function_dies, delayed_properties, - default_accessibility, is_a_class, layout_info); + 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 +2133,11 @@ 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 +2156,15 @@ 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 +2181,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) { +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(); @@ -2264,15 +2321,17 @@ } if (func_range.GetBaseAddress().IsValid()) { + SymbolFileDWARF *dwarf; + DWARFUnit *main_unit = DWARFCompileUnit::GetMainUnit(comp_unit, &dwarf); 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())) && - !Language::LanguageIsObjC( - SymbolFileDWARF::GetLanguage(*die.GetCU())) && + Language::LanguageIsCPlusPlus(SymbolFileDWARF::GetLanguage( + *die.GetMainDWARFUnit(main_unit))) && + !Language::LanguageIsObjC(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 @@ -2285,14 +2344,15 @@ 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) @@ -2315,14 +2375,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.MainUnitToDIEPair(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 @@ -2342,6 +2402,7 @@ } 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, @@ -2528,7 +2589,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) @@ -2541,7 +2602,8 @@ } 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; @@ -2595,7 +2657,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; } @@ -2704,8 +2766,9 @@ "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 = @@ -2720,21 +2783,22 @@ 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)); } else { if (name) - 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()); + 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(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()); } } @@ -2747,20 +2811,21 @@ } 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( - const DWARFDIE &parent_die, CompilerType &class_clang_type, + CompileUnit *comp_unit, DWARFUnit *main_unit, const DWARFDIE &parent_die, + CompilerType &class_clang_type, std::vector> &base_classes, std::vector &member_accessibilities, std::vector &member_function_dies, @@ -2784,7 +2849,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; @@ -2858,7 +2923,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" @@ -2918,9 +2984,10 @@ } 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) @@ -2983,7 +3050,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) { @@ -3000,18 +3067,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)); } } } @@ -3134,9 +3202,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) { @@ -3147,7 +3217,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); } } } @@ -3155,7 +3225,8 @@ return nullptr; } -clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { +clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(DWARFUnit *main_unit, + const DWARFDIE &die) { if (!die) return nullptr; @@ -3170,52 +3241,55 @@ return nullptr; } - DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE()); + auto diepair = die.MainUnitToDIEPair(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())) @@ -3226,16 +3300,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)) @@ -3249,16 +3322,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; @@ -3271,12 +3346,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; @@ -3285,13 +3360,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; } } @@ -3299,7 +3376,8 @@ } OptionalClangModuleID -DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) { +DWARFASTParserClang::GetOwningClangModule(DWARFUnit *main_unit, + const DWARFDIE &die) { if (!die.IsValid()) return {}; @@ -3308,16 +3386,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.MainUnitToDIEPair(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.MainUnitToDIEPair(main_unit), id}); return id; } } @@ -3373,34 +3451,36 @@ } 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.MainUnitToDIEPair(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; @@ -3409,35 +3489,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.MainUnitToDIEPair(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 { @@ -3446,14 +3528,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; } } @@ -3461,8 +3544,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); @@ -3471,7 +3555,7 @@ 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; } @@ -3479,9 +3563,11 @@ } clang::DeclContext * -DWARFASTParserClang::GetCachedClangDeclContextForDIE(const DWARFDIE &die) { +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.MainUnitToDIEPair(main_unit)); if (pos != m_die_to_decl_ctx.end()) return pos->second; } @@ -3489,16 +3575,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.MainUnitToDIEPair(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.MainUnitToDWARFDIEPair(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,11 +3697,11 @@ } DWARFASTParserClang *src_dwarf_ast_parser = - static_cast( - SymbolFileDWARF::GetDWARFParser(*src_die.GetCU())); + static_cast(SymbolFileDWARF::GetDWARFParser( + *src_class_die.GetMainDWARFUnit(main_unit))); DWARFASTParserClang *dst_dwarf_ast_parser = - static_cast( - SymbolFileDWARF::GetDWARFParser(*dst_die.GetCU())); + static_cast(SymbolFileDWARF::GetDWARFParser( + *dst_class_die.GetMainDWARFUnit(main_unit))); // Now do the work of linking the DeclContexts and Types. if (fast_path) { @@ -3623,12 +3712,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.MainUnitToDIEPair(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 " @@ -3637,14 +3728,17 @@ } Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; + dst_die.GetDWARF() + ->GetDIEToType()[src_die.MainUnitToDIEPair(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.MainUnitToDIEPair(main_unit)] = + src_child_type; } else { LLDB_LOGF(log, "warning: tried to unique lldb_private::Type from " @@ -3667,12 +3761,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.MainUnitToDIEPair(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 " @@ -3681,14 +3777,16 @@ } Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; + dst_die.GetDWARF() + ->GetDIEToType()[src_die.MainUnitToDIEPair(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.MainUnitToDIEPair(main_unit)] = src_child_type; } else { LLDB_LOGF(log, @@ -3722,12 +3820,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.MainUnitToDIEPair(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 " @@ -3736,14 +3836,17 @@ } Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; + dst_die.GetDWARF() + ->GetDIEToType()[src_die.MainUnitToDIEPair(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.MainUnitToDIEPair(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 @@ -55,7 +55,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) { @@ -90,7 +90,7 @@ // 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; + lldb::user_id_t GetID(DWARFUnit *main_unit) const; const char *GetName() 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 @@ -18,10 +18,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,9 +66,9 @@ return fail_value; } -lldb::user_id_t DWARFBaseDIE::GetID() const { +lldb::user_id_t DWARFBaseDIE::GetID(DWARFUnit *main_unit) const { if (IsValid()) - return GetDWARF()->GetUID(*this); + return GetDWARF()->GetUID(main_unit, *this); return LLDB_INVALID_UID; } 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,17 @@ DWARFDIE LookupAddress(const dw_addr_t address); + virtual DWARFUnit *GetMainDWARFUnit(DWARFUnit *main_unit) override; + + DWARFDIE DIE() { return {this, DIEPtr()}; } + + lldb_private::CompileUnit *GetCompUnit(); + + static DWARFCompileUnit *GetMainUnit(const lldb_private::SymbolContext &sc, + SymbolFileDWARF **dwarf_return); + static DWARFCompileUnit *GetMainUnit(lldb_private::CompileUnit &comp_unit, + SymbolFileDWARF **dwarf_return); + private: DWARFCompileUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid, const DWARFUnitHeader &header, @@ -34,6 +45,10 @@ DWARFCompileUnit(const DWARFCompileUnit &) = delete; const DWARFCompileUnit &operator=(const DWARFCompileUnit &) = delete; + static DWARFCompileUnit *GetMainUnit(lldb_private::Module &module, + lldb_private::CompileUnit *comp_unit, + SymbolFileDWARF **dwarf_return); + friend class DWARFUnit; }; 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 @@ -10,6 +10,7 @@ #include "DWARFDebugAranges.h" #include "SymbolFileDWARFDebugMap.h" +#include "lldb/Core/Module.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Utility/Stream.h" @@ -114,3 +115,45 @@ } 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; +} + +DWARFCompileUnit * +DWARFCompileUnit::GetMainUnit(Module &module, CompileUnit *comp_unit, + SymbolFileDWARF **dwarf_return) { + SymbolFileDWARF *dwarf = llvm::cast(module.GetSymbolFile()); + if (dwarf_return) + *dwarf_return = dwarf; + if (!comp_unit) { + lldbassert(dwarf_return); + return nullptr; + } + return dwarf->GetDWARFCompileUnit(comp_unit); +} + +DWARFCompileUnit * +DWARFCompileUnit::GetMainUnit(CompileUnit &comp_unit, + SymbolFileDWARF **dwarf_return) { + ModuleSP module_sp = comp_unit.CalculateSymbolContextModule(); + lldbassert(module_sp); + return GetMainUnit(*module_sp, &comp_unit, dwarf_return); +} + +DWARFCompileUnit * +DWARFCompileUnit::GetMainUnit(const SymbolContext &sc, + SymbolFileDWARF **dwarf_return) { + lldbassert(sc.module_sp); + return GetMainUnit(*sc.module_sp, sc.comp_unit, dwarf_return); +} 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 @@ -35,10 +35,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 +89,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 + MainUnitToDWARFDIEPair(DWARFUnit *main_unit) const; + std::pair + MainUnitToDIEPair(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 @@ -345,16 +345,19 @@ } } -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 +451,20 @@ } else return false; } + +DWARFUnit *DWARFDIE::GetMainDWARFUnit(DWARFUnit *main_unit) const { + lldbassert(IsValid()); + if (main_unit == nullptr) + main_unit = GetCU(); + return GetCU()->GetMainDWARFUnit(main_unit); +} + +std::pair +DWARFDIE::MainUnitToDWARFDIEPair(DWARFUnit *main_unit) const { + return std::make_pair(GetMainDWARFUnit(main_unit), *this); +} + +std::pair +DWARFDIE::MainUnitToDIEPair(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,13 @@ 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 +58,12 @@ llvm::Expected GetCompileUnitAranges(); + lldb::user_id_t GetUID(DWARFUnit *main_unit, DIERef ref) const { + return m_dwarf.GetUID(main_unit, ref); + } + + DWARFCompileUnit *GetDWARFCompileUnit(lldb_private::CompileUnit &comp_unit); + 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 @@ -12,6 +12,7 @@ #include #include "lldb/Host/PosixApi.h" +#include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" @@ -58,6 +59,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()); @@ -151,6 +154,12 @@ return GetUnitContainingDIEOffset(die_ref.section(), die_ref.die_offset()); } +DWARFUnit *DWARFDebugInfo::GetMainUnit(const DIERef &die_ref) { + // This function will be extended by a later DWZ patch. + DWARFUnit *main_unit = GetUnit(die_ref); + return main_unit; +} + DWARFUnit * DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section, dw_offset_t die_offset) { @@ -187,9 +196,30 @@ // // 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 } + +DWARFCompileUnit *DWARFDebugInfo::GetDWARFCompileUnit(CompileUnit &comp_unit) { + // The compile unit ID is the index of the DWARF unit. + DWARFUnit *dwarf_cu = GetUnitAtIndex(comp_unit.GetID()); + 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(dwarf_cu); +} 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 @@ -730,6 +730,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,49 @@ /// 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 &cu, - 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; + llvm::function_ref + callback) = 0; + virtual void GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + 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 + GetTypes(const DWARFDeclContext &context, + llvm::function_ref + callback) = 0; virtual void GetNamespaces(ConstString name, - llvm::function_ref callback) = 0; + 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; + llvm::function_ref + callback) = 0; virtual void GetFunctions(const RegularExpression ®ex, - llvm::function_ref callback) = 0; + llvm::function_ref + callback) = 0; virtual void Dump(Stream &s) = 0; @@ -68,32 +80,49 @@ /// 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 @@ -19,14 +19,16 @@ 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 +39,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 +60,47 @@ // 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.GetDIE(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 @@ -21,3 +21,7 @@ GetOffset(), GetLength(), GetVersion(), GetAbbrevOffset(), GetAddressByteSize(), GetNextUnitOffset()); } + +DWARFUnit *DWARFTypeUnit::GetMainDWARFUnit(DWARFUnit *main_unit) { + return &GetNonSkeletonUnit(); +} 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 @@ -357,7 +357,8 @@ 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. @@ -391,7 +392,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,44 @@ 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 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 {} + llvm::function_ref + callback) override {} void GetCompleteObjCClass( ConstString class_name, bool must_be_implementation, - llvm::function_ref callback) override; + llvm::function_ref callback) + override; void GetTypes(ConstString name, - llvm::function_ref callback) override; + llvm::function_ref + callback) override; void GetTypes(const DWARFDeclContext &context, - llvm::function_ref callback) override; - void GetNamespaces(ConstString name, - llvm::function_ref callback) override; + 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; + llvm::function_ref + callback) override; void GetFunctions(const RegularExpression ®ex, - llvm::function_ref callback) override; + llvm::function_ref + callback) override; void Dump(Stream &s) override; @@ -78,9 +89,10 @@ 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 @@ -60,7 +60,8 @@ 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 +70,9 @@ DWARFDIE die = dwarf.GetDIE(*ref); if (!die) return true; - return callback(die); + // FIXME: .debug_names have no DWZ support yet. + DWARFUnit *main_unit = die.GetMainDWARFUnit(nullptr); + return callback(main_unit, die); } void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error, @@ -84,7 +87,8 @@ } 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 +103,7 @@ 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 +127,9 @@ } 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 +148,15 @@ } } - 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: .debug_names have no DWZ support yet. DIEArray incomplete_types; for (const DebugNames::Entry &entry : @@ -177,12 +183,14 @@ if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) { // If we find the complete version we're done. - callback(die); + // FIXME: .debug_names have no DWZ support yet. + callback(nullptr /* main_unit */, die); return; } incomplete_types.push_back(*ref); } + // FIXME: .debug_names have no DWZ support yet. auto dierefcallback = DIERefCallback(callback, class_name.GetStringRef()); for (DIERef ref : incomplete_types) if (!dierefcallback(ref)) @@ -192,7 +200,8 @@ } 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 +215,7 @@ 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 +228,8 @@ } 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 +244,9 @@ 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: .debug_names have no DWZ support yet. std::set seen; for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { @@ -244,11 +255,17 @@ continue; if (llvm::Optional ref = ToDIERef(entry)) { - if (!ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx, - name_type_mask, [&](DWARFDIE die) { + // FIXME: .debug_names have no DWZ support yet. + 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: .debug_names have no DWZ support yet. + // lldbassert(main_unit_check == main_unit); if (!seen.insert(die.GetDIE()).second) return true; - return callback(die); + // FIXME: .debug_names have no DWZ support yet. + return callback(main_unit_check, die); })) return; } @@ -260,7 +277,7 @@ 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/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,44 @@ 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 &main_unit, + 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 &unit, - llvm::function_ref callback) override; - void GetObjCMethods(ConstString class_name, - llvm::function_ref callback) override; + GetObjCMethods(ConstString class_name, + llvm::function_ref + callback) override; void GetCompleteObjCClass( ConstString class_name, bool must_be_implementation, - llvm::function_ref callback) override; + llvm::function_ref callback) + override; void GetTypes(ConstString name, - llvm::function_ref callback) override; + llvm::function_ref + callback) override; void GetTypes(const DWARFDeclContext &context, - llvm::function_ref callback) override; - void GetNamespaces(ConstString name, - llvm::function_ref callback) override; + 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; + llvm::function_ref + callback) override; void GetFunctions(const RegularExpression ®ex, - llvm::function_ref callback) override; + llvm::function_ref + callback) override; void Dump(Stream &s) override; @@ -69,7 +81,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 @@ -122,23 +122,23 @@ 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, +void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, DWARFUnit *main_unit, const LanguageType cu_language, IndexSet &set) { for (const DWARFDebugInfoEntry &die : unit.dies()) { @@ -223,7 +223,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 +328,8 @@ } 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 +337,21 @@ 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 +359,22 @@ 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 +382,8 @@ } 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 +391,17 @@ 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 +409,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 +435,7 @@ 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/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,7 @@ 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 +240,9 @@ 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 +260,19 @@ 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); + DWARFDIE GetDIE(lldb::user_id_t uid, DWARFUnit **main_unit_return = nullptr); - lldb::user_id_t GetUID(const DWARFBaseDIE &die) { - return GetUID(die.GetDIERef()); - } + lldb::user_id_t GetUID(DWARFUnit *main_unit, const DWARFBaseDIE &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 +285,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 +307,36 @@ // 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); + llvm::Optional GetDWARFUnitIndex(uint32_t cu_idx); + protected: - typedef llvm::DenseMap + typedef llvm::DenseMap, + lldb_private::Type *> DIEToTypePtr; - typedef llvm::DenseMap + typedef llvm::DenseMap, + lldb::VariableSP> DIEToVariableSP; - typedef llvm::DenseMap, 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 +355,12 @@ lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu); - virtual DWARFCompileUnit * - GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit); + DWARFCompileUnit *GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit); 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 +376,11 @@ 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 +395,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 +416,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 +456,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,7 +481,6 @@ } void BuildCuTranslationTable(); - llvm::Optional GetDWARFUnitIndex(uint32_t cu_idx); struct DecodedUID { SymbolFileDWARF &dwarf; 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,12 @@ if (!comp_unit) return nullptr; - // 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) - dwarf_cu->SetUserData(comp_unit); + ModuleSP module_sp = comp_unit->CalculateSymbolContextModule(); + lldbassert(module_sp); + SymbolFileDWARF *dwarf = + llvm::cast(module_sp->GetSymbolFile()); - // It must be DWARFCompileUnit when it created a CompileUnit. - return llvm::cast_or_null(dwarf_cu); + return dwarf->DebugInfo().GetDWARFCompileUnit(*comp_unit); } DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() { @@ -704,6 +705,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 +764,10 @@ if (!die.IsValid()) return nullptr; - auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); + DWARFUnit *main_unit = GetDWARFCompileUnit(&comp_unit); + + 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"); @@ -841,7 +846,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; @@ -1135,7 +1140,8 @@ block = parent_block; } else { - BlockSP block_sp(new Block(die.GetID())); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); + BlockSP block_sp(new Block(die.GetID(dwarf_cu))); parent_block->AddChild(block_sp); block = block_sp.get(); } @@ -1261,14 +1267,45 @@ decl_ctx); } -user_id_t SymbolFileDWARF::GetUID(DIERef ref) { +user_id_t SymbolFileDWARF::GetUID(DWARFUnit *main_unit, + const DWARFBaseDIE &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 | - lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63; + 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 = GetDIE(retval, &main_unit_check); + lldbassert(dwarfdie_check2 == dwarfdie_check); +#endif + + return retval; } llvm::Optional @@ -1305,7 +1342,7 @@ } DWARFDIE -SymbolFileDWARF::GetDIE(lldb::user_id_t uid) { +SymbolFileDWARF::GetDIE(lldb::user_id_t uid, DWARFUnit **main_unit_return) { // This method can be called without going through the symbol vendor so we // need to lock the module. std::lock_guard guard(GetModuleMutex()); @@ -1313,7 +1350,7 @@ llvm::Optional decoded = DecodeUID(uid); if (decoded) - return decoded->dwarf.GetDIE(decoded->ref); + return decoded->dwarf.GetDIE(decoded->ref, main_unit_return); return DWARFDIE(); } @@ -1325,8 +1362,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 = GetDIE(type_uid, &main_unit)) + return GetDecl(main_unit, die); return CompilerDecl(); } @@ -1338,8 +1376,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 = GetDIE(type_uid, &main_unit)) + return GetDeclContext(main_unit, die); return CompilerDeclContext(); } @@ -1349,8 +1388,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 = GetDIE(type_uid, &main_unit)) + return GetContainingDeclContext(main_unit, die); return CompilerDeclContext(); } @@ -1359,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 type_die = GetDIE(type_uid)) - return type_die.ResolveType(); + DWARFUnit *main_unit; + if (DWARFDIE type_die = GetDIE(type_uid, &main_unit)) + return type_die.ResolveType(main_unit); else return nullptr; } @@ -1375,11 +1416,12 @@ 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 +1455,7 @@ } } } - return ResolveType(die); + return ResolveType(main_unit, die); } return nullptr; } @@ -1463,7 +1505,8 @@ return true; } - DWARFDIE dwarf_die = GetDIE(die_it->getSecond()); + DWARFUnit *main_unit; + DWARFDIE dwarf_die = GetDIE(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 +1514,30 @@ // to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done. GetForwardDeclClangTypeToDie().erase(die_it); - Type *type = GetDIEToType().lookup(dwarf_die.GetDIE()); + Type *type = GetDIEToType().lookup(dwarf_die.MainUnitToDIEPair(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(main_unit), 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 +1572,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 +1610,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 +1858,13 @@ 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 = GetDWARFCompileUnit(sc.comp_unit); + 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 +1877,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 +2160,44 @@ 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; - - auto *dwarf_cu = llvm::dyn_cast(die.GetCU()); - if (!dwarf_cu) - return true; - sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); + 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); - 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,15 +2229,16 @@ const uint32_t original_size = variables.GetSize(); SymbolContext sc; - m_index->GetGlobalVariables(regex, [&](DWARFDIE die) { + 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); @@ -2193,7 +2246,8 @@ }); } -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 +2276,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 +2304,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 +2313,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 +2357,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 +2397,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 +2459,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 +2521,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 +2530,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 +2566,17 @@ 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 +2594,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.MainUnitToDIEPair(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 +2617,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 +2736,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 +2762,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 +2774,7 @@ type_die.GetID(), type_cu->GetID()); if (die) - GetDIEToType()[die.GetDIE()] = resolved_type; + GetDIEToType()[die.MainUnitToDIEPair(main_unit)] = resolved_type; type_sp = resolved_type->shared_from_this(); return false; }); @@ -2843,12 +2908,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()))) + if (type_system && !type_system->SupportsLanguage(GetLanguage( + *type_die.GetMainDWARFUnit(main_unit)))) return true; bool try_resolving_type = false; @@ -2897,7 +2963,8 @@ 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 +2981,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 +2998,9 @@ if (!die) return {}; - auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); + DWARFUnit *main_unit = GetDWARFCompileUnit(sc.comp_unit); + 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 +3016,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 +3053,10 @@ if (parse_children && die.HasChildren()) { if (die.Tag() == DW_TAG_subprogram) { + DWARFUnit *main_unit = GetDWARFCompileUnit(sc.comp_unit); 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 +3100,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 +3129,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 = GetDWARFCompileUnit(sc.comp_unit); + if (!main_unit) return 0; + main_unit = &main_unit->GetNonSkeletonUnit(); uint32_t vars_added = 0; VariableListSP variables(sc.comp_unit->GetVariableList(false)); @@ -3069,7 +3142,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 +3163,12 @@ 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) return nullptr; - if (VariableSP var_sp = GetDIEToVariable()[die.GetDIE()]) + DWARFUnit *main_unit = GetDWARFCompileUnit(sc.comp_unit); + + if (VariableSP var_sp = GetDIEToVariable()[die.MainUnitToDIEPair(main_unit)]) return var_sp; // Already been parsed! const dw_tag_t tag = die.Tag(); @@ -3258,9 +3332,11 @@ // declaration context. if ((parent_tag == DW_TAG_compile_unit || parent_tag == DW_TAG_partial_unit) && - Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU()))) - mangled = - GetDWARFDeclContext(die).GetQualifiedNameAsConstString().GetCString(); + Language::LanguageIsCPlusPlus( + GetLanguage(*die.GetMainDWARFUnit(main_unit)))) + mangled = GetDWARFDeclContext(main_unit, die) + .GetQualifiedNameAsConstString() + .GetCString(); } if (tag == DW_TAG_formal_parameter) @@ -3392,8 +3468,8 @@ case DW_TAG_inlined_subroutine: case DW_TAG_lexical_block: if (sc.function) { - 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; } @@ -3407,7 +3483,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,9 +3492,9 @@ die.GetCU()->GetAddressByteSize()); var_sp = std::make_shared( - die.GetID(), name, mangled, type_sp, scope, symbol_context_scope, - scope_ranges, &decl, location, is_external, is_artificial, - location_is_const_value_data, is_static_member); + 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 { // Not ready to parse this variable yet. It might be a global or static // variable that is in a function scope and the function in the symbol @@ -3429,9 +3505,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.MainUnitToDIEPair(main_unit)] = var_sp; if (spec_die) - GetDIEToVariable()[spec_die.GetDIE()] = var_sp; + GetDIEToVariable()[spec_die.MainUnitToDIEPair(main_unit)] = var_sp; return var_sp; } @@ -3490,6 +3566,7 @@ return 0; VariableListSP variable_list_sp; + DWARFUnit *main_unit = GetDWARFCompileUnit(sc.comp_unit); size_t vars_added = 0; DWARFDIE die = orig_die; @@ -3497,7 +3574,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.MainUnitToDIEPair(main_unit)]; if (var_sp) { if (cc_variable_list) cc_variable_list->AddVariableIfUnique(var_sp); @@ -3520,8 +3597,9 @@ 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(main_unit), + sc_parent_die.GetTagAsCString(), orig_die.GetID(main_unit), + orig_die.GetTagAsCString()); } break; @@ -3533,7 +3611,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 +3623,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 +3641,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(main_unit), orig_die.GetTagAsCString()); break; } } @@ -3892,31 +3970,38 @@ 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())); + DWARFDeclContext dwarf_decl_ctx = 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/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,14 +31,17 @@ 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; } 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,7 @@ void SymbolFileDWARFDwo::GetObjCMethods( lldb_private::ConstString class_name, - llvm::function_ref callback) { + llvm::function_ref callback) { GetBaseSymbolFile().GetObjCMethods(class_name, callback); } @@ -123,8 +123,9 @@ } 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,25 +20,28 @@ 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, - const lldb_private::Declaration &decl, int32_t byte_size) - : m_type_sp(type_sp), m_die(die), m_declaration(decl), - m_byte_size(byte_size) {} + 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_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_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size) {} + : 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() {} 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 +50,7 @@ } lldb::TypeSP m_type_sp; + DWARFUnit *m_main_unit; DWARFDIE m_die; lldb_private::Declaration m_declaration; int32_t m_byte_size; @@ -64,8 +68,9 @@ m_collection.push_back(entry); } - bool Find(const DWARFDIE &die, const lldb_private::Declaration &decl, - const int32_t byte_size, UniqueDWARFASTType &entry) const; + bool Find(DWARFUnit *main_unit, const DWARFDIE &die, + const lldb_private::Declaration &decl, const int32_t byte_size, + UniqueDWARFASTType &entry) const; protected: typedef std::vector collection; @@ -83,13 +88,13 @@ m_collection[name.GetCString()].Append(entry); } - bool Find(lldb_private::ConstString name, const DWARFDIE &die, - const lldb_private::Declaration &decl, const int32_t byte_size, - UniqueDWARFASTType &entry) const { + 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/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]));