aprantl updated this revision to Diff 250941.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D75626/new/
https://reviews.llvm.org/D75626
Files:
lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/A.h
lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/B.h
lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/module.modulemap
lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
lldb/test/Shell/SymbolFile/DWARF/module-ownership.mm
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<int> t2;
+// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} imported in A struct Template
+
+Namespace::InNamespace<int> t3;
+// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} imported in A struct InNamespace
+
+Namespace::AlsoInNamespace<int> t4;
+// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} imported in A.B struct AlsoInNamespace
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/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/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<typename T> struct AlsoInNamespace { T field; };
+ extern template struct AlsoInNamespace<int>;
+}
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<typename T> struct Template { T field; };
+extern template struct Template<int>;
+
+namespace Namespace {
+template<typename T> struct InNamespace { T field; };
+extern template struct InNamespace<int>;
+}
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -314,8 +314,8 @@
static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl,
bool omit_empty_base_classes);
- /// Synthesize a clang::Module and return its ID or 0.
- unsigned GetOrCreateClangModule(llvm::StringRef name, unsigned parent,
+ /// Synthesize a clang::Module and return its ID or a default-constructed ID.
+ ModuleID GetOrCreateClangModule(llvm::StringRef name, ModuleID parent,
bool is_framework = false,
bool is_explicit = false);
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -1225,8 +1225,8 @@
decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
}
-unsigned TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name,
- unsigned parent,
+ModuleID TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name,
+ ModuleID parent,
bool is_framework,
bool is_explicit) {
// Get the external AST source which holds the modules.
@@ -1234,7 +1234,7 @@
getASTContext().getExternalSource());
assert(ast_source && "external ast source was lost");
if (!ast_source)
- return 0;
+ return {};
// Lazily initialize the module map.
if (!m_header_search_up) {
@@ -1250,7 +1250,7 @@
// Get or create the module context.
bool created;
clang::Module *module;
- auto parent_desc = ast_source->getSourceDescriptor(parent);
+ auto parent_desc = ast_source->getSourceDescriptor(parent.id);
std::tie(module, created) = m_module_map_up->findOrCreateModule(
name, parent_desc ? parent_desc->getModuleOrNull() : nullptr,
is_framework, is_explicit);
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,8 @@
DIEToDeclContextMap;
typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
DeclContextToDIEMap;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::ModuleID>
+ DIEToModuleMap;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
DIEToDeclMap;
typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
@@ -87,6 +89,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<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
/// @}
@@ -140,6 +143,7 @@
clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
DWARFDIE *decl_ctx_die);
+ lldb_private::ModuleID 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)
+ ModuleID owning_module = GetOwningModuleID(die);
+ if (tag_decl) {
+ TypeSystemClang::SetOwningModule(tag_decl, owning_module);
+ if (auto *rd = llvm::dyn_cast<clang::RecordDecl>(tag_decl))
+ for (clang::FieldDecl *fd : rd->fields())
+ TypeSystemClang::SetOwningModule(fd, owning_module);
+ if (auto *ed = llvm::dyn_cast<clang::EnumDecl>(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),
- ModuleID(), 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,
- ModuleID(), 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,13 @@
template_function_decl = m_ast.CreateFunctionDeclaration(
ignore_containing_context ? m_ast.GetTranslationUnitDecl()
: containing_decl_ctx,
- ModuleID(), attrs.name.GetCString(), clang_type, attrs.storage,
- attrs.is_inline);
+ GetOwningModuleID(die), attrs.name.GetCString(), clang_type,
+ attrs.storage, attrs.is_inline);
clang::FunctionTemplateDecl *func_template_decl =
m_ast.CreateFunctionTemplateDecl(
- containing_decl_ctx, ModuleID(), 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);
}
@@ -1583,7 +1605,7 @@
if (ParseTemplateParameterInfos(die, template_param_infos)) {
clang::ClassTemplateDecl *class_template_decl =
m_ast.ParseClassTemplateDecl(
- decl_ctx, ModuleID(), attrs.accessibility,
+ decl_ctx, GetOwningModuleID(die), attrs.accessibility,
attrs.name.GetCString(), tag_decl_kind, template_param_infos);
if (!class_template_decl) {
if (log) {
@@ -1599,8 +1621,8 @@
clang::ClassTemplateSpecializationDecl *class_specialization_decl =
m_ast.CreateClassTemplateSpecializationDecl(
- decl_ctx, ModuleID(), 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;
@@ -1613,9 +1635,9 @@
if (!clang_type_was_created) {
clang_type_was_created = true;
clang_type = m_ast.CreateRecordType(
- decl_ctx, ModuleID(), attrs.accessibility, attrs.name.GetCString(),
- tag_decl_kind, attrs.class_language, &metadata,
- attrs.exports_symbols);
+ decl_ctx, GetOwningModuleID(die), attrs.accessibility,
+ attrs.name.GetCString(), tag_decl_kind, attrs.class_language,
+ &metadata, attrs.exports_symbols);
}
}
@@ -3062,7 +3084,7 @@
clang::ParmVarDecl *param_var_decl =
m_ast.CreateParameterDeclaration(
- containing_decl_ctx, ModuleID(), name,
+ containing_decl_ctx, GetOwningModuleID(die), name,
type->GetForwardCompilerType(), storage);
assert(param_var_decl);
function_param_decls.push_back(param_var_decl);
@@ -3261,7 +3283,7 @@
TypeSystemClang::DeclContextGetAsDeclContext(
dwarf->GetDeclContextContainingUID(die.GetID()));
decl = m_ast.CreateVariableDeclaration(
- decl_context, ModuleID(), name,
+ decl_context, GetOwningModuleID(die), name,
ClangUtil::GetQualType(type->GetForwardCompilerType()));
}
break;
@@ -3357,6 +3379,31 @@
return nullptr;
}
+ModuleID DWARFASTParserClang::GetOwningModuleID(const DWARFDIE &die) {
+ if (!die.IsValid())
+ return {};
+
+ 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 {};
+
+ ModuleID id =
+ m_ast.GetOrCreateClangModule(name, GetOwningModuleID(module_die));
+ m_die_to_module.insert({module_die.GetDIE(), id});
+ return id;
+ }
+ }
+ return {};
+}
+
static bool IsSubroutine(const DWARFDIE &die) {
switch (die.Tag()) {
case DW_TAG_subprogram:
@@ -3429,7 +3476,7 @@
DWARFDIE decl_context_die;
clang::DeclContext *decl_context =
GetClangDeclContextContainingDIE(die, &decl_context_die);
- decl = m_ast.CreateBlockDeclaration(decl_context, ModuleID());
+ decl = m_ast.CreateBlockDeclaration(decl_context, GetOwningModuleID(die));
if (decl)
LinkDeclContextToDIE((clang::DeclContext *)decl, die);
Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
@@ -14,8 +14,6 @@
namespace lldb_private {
-class TypeSystemClang;
-
class ClangExternalASTSourceCallbacks : public clang::ExternalASTSource {
/// LLVM RTTI support.
static char ID;
@@ -51,8 +49,8 @@
llvm::Optional<clang::ASTSourceDescriptor>
getSourceDescriptor(unsigned ID) override;
clang::Module *getModule(unsigned ID) override;
- unsigned RegisterModule(clang::Module *module);
- unsigned GetIDForModule(clang::Module *module);
+ ModuleID RegisterModule(clang::Module *module);
+ ModuleID GetIDForModule(clang::Module *module);
/// \}
private:
TypeSystemClang &m_ast;
Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
@@ -46,11 +46,11 @@
}
}
-unsigned ClangExternalASTSourceCallbacks::RegisterModule(clang::Module *module) {
+ModuleID ClangExternalASTSourceCallbacks::RegisterModule(clang::Module *module) {
m_modules.push_back(module);
unsigned id = m_modules.size();
m_ids.insert({module, id});
- return id;
+ return ModuleID(id);
}
llvm::Optional<clang::ASTSourceDescriptor>
@@ -66,6 +66,6 @@
return nullptr;
}
-unsigned ClangExternalASTSourceCallbacks::GetIDForModule(clang::Module *module) {
- return m_ids[module];
+ModuleID ClangExternalASTSourceCallbacks::GetIDForModule(clang::Module *module) {
+ return ModuleID(m_ids[module]);
}
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits