aprantl updated this revision to Diff 250971.
aprantl marked an inline comment as done.
aprantl added a comment.
Address review feedback from Raphael.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D75488/new/
https://reviews.llvm.org/D75488
Files:
lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
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
+// FIXME: : -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
@@ -75,7 +75,8 @@
uint32_t m_payload;
public:
TypePayloadClang() = default;
- explicit TypePayloadClang(bool is_complete_objc_class, ModuleID owning_module);
+ explicit TypePayloadClang(ModuleID owning_module,
+ bool is_complete_objc_class = false);
explicit TypePayloadClang(uint32_t opaque_payload) : m_payload(opaque_payload) {}
operator uint32_t() { return m_payload; }
@@ -314,8 +315,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
@@ -319,8 +319,8 @@
return *g_map_ptr;
}
-TypePayloadClang::TypePayloadClang(bool is_complete_objc_class,
- ModuleID owning_module)
+TypePayloadClang::TypePayloadClang(ModuleID owning_module,
+ bool is_complete_objc_class)
: m_payload(owning_module.id) {
SetIsCompleteObjCClass(is_complete_objc_class);
}
@@ -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
@@ -210,14 +210,15 @@
TypeSP type_sp(new Type(
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));
+ &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward,
+ TypePayloadClang(GetOwningModuleID(die))));
dwarf->GetTypeList().Insert(type_sp);
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type);
- if (tag_decl)
+ if (tag_decl) {
LinkDeclContextToDIE(tag_decl, die);
- else {
+ } else {
clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
if (defn_decl_ctx)
LinkDeclContextToDIE(defn_decl_ctx, die);
@@ -706,7 +707,7 @@
type_sp = std::make_shared<Type>(
die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl,
- clang_type, resolve_state);
+ clang_type, resolve_state, TypePayloadClang(GetOwningModuleID(die)));
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
return type_sp;
@@ -788,7 +789,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);
}
@@ -798,7 +800,8 @@
type_sp = std::make_shared<Type>(
die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
dwarf->GetUID(attrs.type.Reference()), Type::eEncodingIsUID, &attrs.decl,
- clang_type, Type::ResolveState::Forward);
+ clang_type, Type::ResolveState::Forward,
+ TypePayloadClang(GetOwningModuleID(die)));
if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
if (die.HasChildren()) {
@@ -1171,7 +1174,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 +1184,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 +1588,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 +1604,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 +1618,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);
}
}
@@ -1627,7 +1632,7 @@
die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
LLDB_INVALID_UID, Type::eEncodingIsUID, &attrs.decl, clang_type,
Type::ResolveState::Forward,
- TypePayloadClang(attrs.is_complete_objc_class));
+ TypePayloadClang(ModuleID(), attrs.is_complete_objc_class));
// Add our type to the unique type map so we don't end up creating many
// copies of the same type over and over in the ASTContext for our
@@ -3062,7 +3067,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 +3266,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 +3362,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 +3459,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]);
}
Index: lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -18,6 +18,7 @@
#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
+#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h"
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
@@ -1001,6 +1002,20 @@
importer.CompleteTagDecl(rd);
}
+/// Recreate a module with its parents in \p to_source and return its id.
+static ModuleID RemapModule(ModuleID from_id,
+ ClangExternalASTSourceCallbacks &from_source,
+ ClangExternalASTSourceCallbacks &to_source) {
+ if (!from_id.HasValue())
+ return {};
+ clang::Module *module = from_source.getModule(*from_id.get());
+ ModuleID parent = RemapModule(from_source.GetIDForModule(module->Parent),
+ from_source, to_source);
+ TypeSystemClang &to_ts = to_source.GetTypeSystem();
+ return to_ts.GetOrCreateClangModule(module->Name, parent, module->IsFramework,
+ module->IsExplicit);
+}
+
void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
clang::Decl *to) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1010,6 +1025,19 @@
if (m_decls_to_ignore.find(to) != m_decls_to_ignore.end())
return clang::ASTImporter::Imported(from, to);
+ // Transfer module ownership information.
+ auto *from_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
+ getFromContext().getExternalSource());
+ // Can also be a ClangASTSourceProxy.
+ auto *to_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
+ getToContext().getExternalSource());
+ if (from_source && to_source) {
+ ModuleID from_id(from->getOwningModuleID());
+ ModuleID to_id = RemapModule(from_id, *from_source, *to_source);
+ TypeSystemClang &to_ts = to_source->GetTypeSystem();
+ to_ts.SetOwningModule(to, to_id);
+ }
+
lldb::user_id_t user_id = LLDB_INVALID_UID;
ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
if (metadata)
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits