Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -78,6 +78,7 @@ DIEToDeclContextMap; typedef std::multimap DeclContextToDIEMap; + typedef llvm::DenseMap DIEToModuleMap; typedef llvm::DenseMap DIEToDeclMap; typedef llvm::DenseMap DeclToDIEMap; @@ -87,6 +88,7 @@ DeclToDIEMap m_decl_to_die; DIEToDeclContextMap m_die_to_decl_ctx; DeclContextToDIEMap m_decl_ctx_to_die; + DIEToModuleMap m_die_to_module; std::unique_ptr m_clang_ast_importer_up; /// @} @@ -140,6 +142,7 @@ clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die, DWARFDIE *decl_ctx_die); + unsigned GetOwningModuleID(const DWARFDIE &die); bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die, Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -211,13 +211,30 @@ die.GetID(), dwarf, pcm_type_sp->GetName(), pcm_type_sp->GetByteSize(), nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid, &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward)); + TypePayloadClang(type_sp->GetPayload()) + .SetOwningModuleID(GetOwningModuleID(die)); dwarf->GetTypeList().Insert(type_sp); dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type); - if (tag_decl) + unsigned owning_module = GetOwningModuleID(die); + if (tag_decl) { + TypeSystemClang::SetOwningModule(tag_decl, owning_module); + if (auto *rd = llvm::dyn_cast(tag_decl)) + for (clang::FieldDecl *fd : rd->fields()) + TypeSystemClang::SetOwningModule(fd, owning_module); + if (auto *ed = llvm::dyn_cast(tag_decl)) + for (clang::EnumConstantDecl *ecd : ed->enumerators()) + TypeSystemClang::SetOwningModule(ecd, owning_module); LinkDeclContextToDIE(tag_decl, die); - else { + } else { + if (auto *oid = TypeSystemClang::GetAsObjCInterfaceDecl(type)) { + TypeSystemClang::SetOwningModule(oid, owning_module); + for (clang::ObjCMethodDecl *omd : oid->methods()) + TypeSystemClang::SetOwningModule(omd, owning_module); + for (clang::ObjCPropertyDecl *opd : oid->properties()) + TypeSystemClang::SetOwningModule(opd, owning_module); + } clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die); if (defn_decl_ctx) LinkDeclContextToDIE(defn_decl_ctx, die); @@ -707,6 +724,7 @@ die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl, clang_type, resolve_state); + TypePayloadClang(type_sp->GetPayload()).SetOwningModuleID(GetOwningModuleID(die)); dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); return type_sp; @@ -788,7 +806,8 @@ clang_type = m_ast.CreateEnumerationType( attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr), - 0, attrs.decl, enumerator_clang_type, attrs.is_scoped_enum); + GetOwningModuleID(die), attrs.decl, enumerator_clang_type, + attrs.is_scoped_enum); } else { enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type); } @@ -799,6 +818,7 @@ die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, dwarf->GetUID(attrs.type.Reference()), Type::eEncodingIsUID, &attrs.decl, clang_type, Type::ResolveState::Forward); + TypePayloadClang(type_sp->GetPayload()).SetOwningModuleID(GetOwningModuleID(die)); if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { if (die.HasChildren()) { @@ -1171,7 +1191,8 @@ function_decl = m_ast.CreateFunctionDeclaration( ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, - 0, attrs.name.GetCString(), clang_type, attrs.storage, + GetOwningModuleID(die), + attrs.name.GetCString(), clang_type, attrs.storage, attrs.is_inline); if (has_template_params) { @@ -1180,12 +1201,14 @@ template_function_decl = m_ast.CreateFunctionDeclaration( ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, - 0, attrs.name.GetCString(), clang_type, attrs.storage, + GetOwningModuleID(die), + attrs.name.GetCString(), clang_type, attrs.storage, attrs.is_inline); clang::FunctionTemplateDecl *func_template_decl = m_ast.CreateFunctionTemplateDecl( - containing_decl_ctx, 0, template_function_decl, - attrs.name.GetCString(), template_param_infos); + containing_decl_ctx, GetOwningModuleID(die), + template_function_decl, attrs.name.GetCString(), + template_param_infos); m_ast.CreateFunctionTemplateSpecializationInfo( function_decl, func_template_decl, template_param_infos); } @@ -1582,9 +1605,9 @@ TypeSystemClang::TemplateParameterInfos template_param_infos; if (ParseTemplateParameterInfos(die, template_param_infos)) { clang::ClassTemplateDecl *class_template_decl = - m_ast.ParseClassTemplateDecl(decl_ctx, 0, attrs.accessibility, - attrs.name.GetCString(), tag_decl_kind, - template_param_infos); + m_ast.ParseClassTemplateDecl( + decl_ctx, GetOwningModuleID(die), attrs.accessibility, + attrs.name.GetCString(), tag_decl_kind, template_param_infos); if (!class_template_decl) { if (log) { dwarf->GetObjectFile()->GetModule()->LogMessage( @@ -1599,8 +1622,8 @@ clang::ClassTemplateSpecializationDecl *class_specialization_decl = m_ast.CreateClassTemplateSpecializationDecl( - decl_ctx, 0, class_template_decl, tag_decl_kind, - template_param_infos); + decl_ctx, GetOwningModuleID(die), class_template_decl, + tag_decl_kind, template_param_infos); clang_type = m_ast.CreateClassTemplateSpecializationType( class_specialization_decl); clang_type_was_created = true; @@ -1612,10 +1635,10 @@ if (!clang_type_was_created) { clang_type_was_created = true; - clang_type = m_ast.CreateRecordType(decl_ctx, 0, attrs.accessibility, - attrs.name.GetCString(), - tag_decl_kind, attrs.class_language, - &metadata, attrs.exports_symbols); + clang_type = m_ast.CreateRecordType( + decl_ctx, GetOwningModuleID(die), attrs.accessibility, + attrs.name.GetCString(), tag_decl_kind, attrs.class_language, + &metadata, attrs.exports_symbols); } } @@ -3063,9 +3086,9 @@ function_param_types.push_back(type->GetForwardCompilerType()); clang::ParmVarDecl *param_var_decl = - m_ast.CreateParameterDeclaration(containing_decl_ctx, 0, name, - type->GetForwardCompilerType(), - storage); + m_ast.CreateParameterDeclaration( + containing_decl_ctx, GetOwningModuleID(die), name, + type->GetForwardCompilerType(), storage); assert(param_var_decl); function_param_decls.push_back(param_var_decl); @@ -3263,7 +3286,7 @@ TypeSystemClang::DeclContextGetAsDeclContext( dwarf->GetDeclContextContainingUID(die.GetID())); decl = m_ast.CreateVariableDeclaration( - decl_context, 0, name, + decl_context, GetOwningModuleID(die), name, ClangUtil::GetQualType(type->GetForwardCompilerType())); } break; @@ -3280,8 +3303,8 @@ if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast( (clang::Decl *)imported_decl.GetOpaqueDecl())) - decl = - m_ast.CreateUsingDeclaration(decl_context, 0, clang_imported_decl); + decl = m_ast.CreateUsingDeclaration( + decl_context, GetOwningModuleID(die), clang_imported_decl); } } break; @@ -3300,7 +3323,8 @@ if (clang::NamespaceDecl *ns_decl = TypeSystemClang::DeclContextGetAsNamespaceDecl( imported_decl_ctx)) - decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, 0, ns_decl); + decl = m_ast.CreateUsingDirectiveDeclaration( + decl_context, GetOwningModuleID(die), ns_decl); } } break; @@ -3358,6 +3382,31 @@ return nullptr; } +unsigned DWARFASTParserClang::GetOwningModuleID(const DWARFDIE &die) { + if (!die.IsValid()) + return 0; + + for (DWARFDIE parent = die.GetParent(); parent.IsValid(); + parent = parent.GetParent()) { + 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()); + if (it != m_die_to_module.end()) + return it->second; + const char *name = module_die.GetAttributeValueAsString(DW_AT_name, 0); + if (!name) + return 0; + + unsigned id = + m_ast.GetOrCreateClangModule(name, GetOwningModuleID(module_die)); + m_die_to_module.insert({module_die.GetDIE(), id}); + return id; + } + } + return 0; +} + static bool IsSubroutine(const DWARFDIE &die) { switch (die.Tag()) { case DW_TAG_subprogram: @@ -3430,7 +3479,7 @@ DWARFDIE decl_context_die; clang::DeclContext *decl_context = GetClangDeclContextContainingDIE(die, &decl_context_die); - decl = m_ast.CreateBlockDeclaration(decl_context, 0); + decl = m_ast.CreateBlockDeclaration(decl_context, GetOwningModuleID(die)); if (decl) LinkDeclContextToDIE((clang::DeclContext *)decl, die); Index: lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/A.h =================================================================== --- /dev/null +++ lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/A.h @@ -0,0 +1,30 @@ +#include "B.h" // -*- ObjC -*- + +typedef int Typedef; + +struct TopLevelStruct { + int a; +}; + +typedef struct Struct_s { + int a; +} Struct; + +struct Nested { + StructB fromb; +}; + +typedef enum Enum_e { + a = 0 +} Enum; + +@interface SomeClass {} +@end + +template struct Template { T field; }; +extern template struct Template; + +namespace Namespace { +template struct InNamespace { T field; }; +extern template struct InNamespace; +} Index: lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/B.h =================================================================== --- /dev/null +++ lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/B.h @@ -0,0 +1,8 @@ +typedef struct { + int b; +} StructB; + +namespace Namespace { +template struct AlsoInNamespace { T field; }; + extern template struct AlsoInNamespace; +} Index: lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/module.modulemap =================================================================== --- /dev/null +++ lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/module.modulemap @@ -0,0 +1,6 @@ +module A { + header "A.h" + module B { + header "B.h" + } +} Index: lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg =================================================================== --- lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg +++ lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg @@ -1 +1 @@ -config.suffixes = ['.cpp', '.m', '.s', '.test', '.ll'] +config.suffixes = ['.cpp', '.m', '.mm', '.s', '.test', '.ll'] Index: lldb/test/Shell/SymbolFile/DWARF/module-ownership.mm =================================================================== --- /dev/null +++ lldb/test/Shell/SymbolFile/DWARF/module-ownership.mm @@ -0,0 +1,41 @@ +// RUN: %clang --target=x86_64-apple-macosx -g -gmodules \ +// RUN: -fmodules -fmodules-cache-path=%t.cache \ +// RUN: -c -o %t.o %s -I%S/Inputs +// RUN: lldb-test symbols -dump-clang-ast %t.o | FileCheck %s +// Verify that the owning module information from DWARF is preserved in the AST. + +@import A; + +Typedef t1; +// CHECK-DAG: TypedefDecl {{.*}} imported in A Typedef + +TopLevelStruct s1; +// CHECK-DAG: CXXRecordDecl {{.*}} imported in A struct TopLevelStruct +// CHECK-DAG: -FieldDecl {{.*}} in A a 'int' + +Struct s2; +// CHECK-DAG: CXXRecordDecl {{.*}} imported in A struct + +StructB s3; +// CHECK-DAG: CXXRecordDecl {{.*}} imported in A.B struct +// CHECK-DAG: -FieldDecl {{.*}} in A.B b 'int' + +Nested s4; +// CHECK-DAG: CXXRecordDecl {{.*}} imported in A struct Nested +// CHECK-DAG: -FieldDecl {{.*}} in A fromb 'StructB' + +Enum e1; +// CHECK-DAG: EnumDecl {{.*}} imported in A Enum_e +// CHECK-DAG: -EnumConstantDecl {{.*}} imported in A a + +SomeClass *obj1; +// CHECK-DAG: ObjCInterfaceDecl {{.*}} imported in A SomeClass + +Template t2; +// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} imported in A struct Template + +Namespace::InNamespace t3; +// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} imported in A struct InNamespace + +Namespace::AlsoInNamespace t4; +// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} imported in A.B struct AlsoInNamespace