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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to