[Lldb-commits] [lldb] 143d507 - Preserve the owning module information from DWARF in the synthesized AST

Adrian Prantl via lldb-commits lldb-commits at lists.llvm.org
Thu Apr 9 11:09:53 PDT 2020


Author: Adrian Prantl
Date: 2020-04-09T11:09:44-07:00
New Revision: 143d507c9ff90db93e547f0e1131e92db06e2675

URL: https://github.com/llvm/llvm-project/commit/143d507c9ff90db93e547f0e1131e92db06e2675
DIFF: https://github.com/llvm/llvm-project/commit/143d507c9ff90db93e547f0e1131e92db06e2675.diff

LOG: Preserve the owning module information from DWARF in the synthesized AST

Types that came from a Clang module are nested in DW_TAG_module tags
in DWARF. This patch recreates the Clang module hierarchy in LLDB and
1;95;0csets the owning module information accordingly. My primary motivation
is to facilitate looking up per-module APINotes for individual
declarations, but this likely also has other applications.

This reapplies the previously reverted commit, but without support for
ClassTemplateSpecializations, which I'm going to look into separately.

rdar://problem/59634380

Differential Revision: https://reviews.llvm.org/D75488

Added: 
    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/module-ownership.mm

Modified: 
    lldb/include/lldb/Symbol/CompilerType.h
    lldb/include/lldb/Symbol/TypeSystem.h
    lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
    lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
    lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
    lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
    lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
    lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
    lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
    lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
    lldb/source/Symbol/CompilerType.cpp
    lldb/source/Symbol/Type.cpp
    lldb/source/Symbol/TypeSystem.cpp
    lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
    lldb/unittests/Symbol/TestTypeSystemClang.cpp
    lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h
index 0d1b00a1b26c..b0a7953190f8 100644
--- a/lldb/include/lldb/Symbol/CompilerType.h
+++ b/lldb/include/lldb/Symbol/CompilerType.h
@@ -242,8 +242,10 @@ class CompilerType {
   /// Create a typedef to this type using "name" as the name of the typedef this
   /// type is valid and the type system supports typedefs, else return an
   /// invalid type.
+  /// \param payload   The typesystem-specific \p lldb::Type payload.
   CompilerType CreateTypedef(const char *name,
-                             const CompilerDeclContext &decl_ctx) const;
+                             const CompilerDeclContext &decl_ctx,
+                             uint32_t payload) const;
 
   /// If the current object represents a typedef type, get the underlying type
   CompilerType GetTypedefedType() const;

diff  --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index a84b9a1c441c..ba2bbfaf4650 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -259,9 +259,12 @@ class TypeSystem : public PluginInterface {
 
   virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type);
 
+  /// \param opaque_payload      The m_payload field of Type, which may
+  /// carry TypeSystem-specific extra information.
   virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
                                      const char *name,
-                                     const CompilerDeclContext &decl_ctx);
+                                     const CompilerDeclContext &decl_ctx,
+                                     uint32_t opaque_payload);
 
   // Exploring the type
 

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
index 4b3e237dc62c..2a21e5e0d7b9 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ b/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"
 
@@ -1003,6 +1004,21 @@ static void MaybeCompleteReturnType(ClangASTImporter &importer,
   importer.CompleteTagDecl(rd);
 }
 
+/// Recreate a module with its parents in \p to_source and return its id.
+static OptionalClangModuleID
+RemapModule(OptionalClangModuleID from_id,
+            ClangExternalASTSourceCallbacks &from_source,
+            ClangExternalASTSourceCallbacks &to_source) {
+  if (!from_id.HasValue())
+    return {};
+  clang::Module *module = from_source.getModule(from_id.GetValue());
+  OptionalClangModuleID 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));
@@ -1012,6 +1028,20 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
   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) {
+    OptionalClangModuleID from_id(from->getOwningModuleID());
+    OptionalClangModuleID 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)

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 9eca2d01c734..7d66cc0c29f4 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -993,7 +993,7 @@ void ClangExpressionDeclMap::LookupLocalVarNamespace(
 
   clang::NamespaceDecl *namespace_decl =
       m_clang_ast_context->GetUniqueNamespaceDeclaration(
-          g_lldb_local_vars_namespace_cstr, nullptr);
+          g_lldb_local_vars_namespace_cstr, nullptr, OptionalClangModuleID());
   if (!namespace_decl)
     return;
 

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
index 26dc4d65817e..943058fde5ad 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
@@ -13,6 +13,8 @@
 
 using namespace lldb_private;
 
+char ClangExternalASTSourceCallbacks::ID;
+
 void ClangExternalASTSourceCallbacks::CompleteType(clang::TagDecl *tag_decl) {
   m_ast.CompleteTagDecl(tag_decl);
 }
@@ -43,3 +45,29 @@ void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls(
       CompleteType(tag_decl);
   }
 }
+
+OptionalClangModuleID
+ClangExternalASTSourceCallbacks::RegisterModule(clang::Module *module) {
+  m_modules.push_back(module);
+  unsigned id = m_modules.size();
+  m_ids.insert({module, id});
+  return OptionalClangModuleID(id);
+}
+
+llvm::Optional<clang::ASTSourceDescriptor>
+ClangExternalASTSourceCallbacks::getSourceDescriptor(unsigned id) {
+  if (clang::Module *module = getModule(id))
+    return {*module};
+  return {};
+}
+
+clang::Module *ClangExternalASTSourceCallbacks::getModule(unsigned id) {
+  if (id && id <= m_modules.size())
+    return m_modules[id - 1];
+  return nullptr;
+}
+
+OptionalClangModuleID
+ClangExternalASTSourceCallbacks::GetIDForModule(clang::Module *module) {
+  return OptionalClangModuleID(m_ids[module]);
+}

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
index 4bbf5564ef94..fc6ba0d3327c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
@@ -10,14 +10,19 @@
 #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H
 
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
-#include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/Module.h"
 
 namespace lldb_private {
 
-class TypeSystemClang;
-
 class ClangExternalASTSourceCallbacks : public clang::ExternalASTSource {
+  /// LLVM RTTI support.
+  static char ID;
+
 public:
+  /// LLVM RTTI support.
+  bool isA(const void *ClassID) const override { return ClassID == &ID; }
+  static bool classof(const clang::ExternalASTSource *s) { return s->isA(&ID); }
+
   ClangExternalASTSourceCallbacks(TypeSystemClang &ast) : m_ast(ast) {}
 
   void FindExternalLexicalDecls(
@@ -37,8 +42,20 @@ class ClangExternalASTSourceCallbacks : public clang::ExternalASTSource {
       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
           &VirtualBaseOffsets) override;
 
+  TypeSystemClang &GetTypeSystem() const { return m_ast; }
+
+  /// Module-related methods.
+  /// \{
+  llvm::Optional<clang::ASTSourceDescriptor>
+  getSourceDescriptor(unsigned ID) override;
+  clang::Module *getModule(unsigned ID) override;
+  OptionalClangModuleID RegisterModule(clang::Module *module);
+  OptionalClangModuleID GetIDForModule(clang::Module *module);
+  /// \}
 private:
   TypeSystemClang &m_ast;
+  std::vector<clang::Module *> m_modules;
+  llvm::DenseMap<clang::Module *, unsigned> m_ids;
 };
 
 } // namespace lldb_private

diff  --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
index 2b228850987c..e76096ba7881 100644
--- a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -76,8 +76,9 @@ static CompilerType GetLLDBNSPairType(TargetSP target_sp) {
 
     if (!compiler_type) {
       compiler_type = target_ast_context->CreateRecordType(
-          nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(),
-          clang::TTK_Struct, lldb::eLanguageTypeC);
+          nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
+          g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct,
+          lldb::eLanguageTypeC);
 
       if (compiler_type) {
         TypeSystemClang::StartTagDeclarationDefinition(compiler_type);

diff  --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index 848431855b3b..ba76f68f3f54 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -124,7 +124,8 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
     return clang::QualType(); // This is where we bail out.  Sorry!
 
   CompilerType union_type(ast_ctx.CreateRecordType(
-      nullptr, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC));
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, name, kind,
+      lldb::eLanguageTypeC));
   if (union_type) {
     TypeSystemClang::StartTagDeclarationDefinition(union_type);
 

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 96500da4c516..62aba37c6fe7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -212,14 +212,15 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
   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(GetOwningClangModule(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);
@@ -708,7 +709,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
   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(GetOwningClangModule(die)));
 
   dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
   return type_sp;
@@ -790,7 +791,8 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
 
     clang_type = m_ast.CreateEnumerationType(
         attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr),
-        attrs.decl, enumerator_clang_type, attrs.is_scoped_enum);
+        GetOwningClangModule(die), attrs.decl, enumerator_clang_type,
+        attrs.is_scoped_enum);
   } else {
     enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type);
   }
@@ -800,7 +802,8 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
   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(GetOwningClangModule(die)));
 
   if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
     if (die.HasChildren()) {
@@ -1184,7 +1187,8 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
         function_decl = m_ast.CreateFunctionDeclaration(
             ignore_containing_context ? m_ast.GetTranslationUnitDecl()
                                       : containing_decl_ctx,
-            name, clang_type, attrs.storage, attrs.is_inline);
+            GetOwningClangModule(die), name, clang_type, attrs.storage,
+            attrs.is_inline);
 
         if (has_template_params) {
           TypeSystemClang::TemplateParameterInfos template_param_infos;
@@ -1192,12 +1196,12 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
           template_function_decl = m_ast.CreateFunctionDeclaration(
               ignore_containing_context ? m_ast.GetTranslationUnitDecl()
                                         : containing_decl_ctx,
-              name, clang_type, attrs.storage, attrs.is_inline);
-
+              GetOwningClangModule(die), attrs.name.GetCString(), clang_type,
+              attrs.storage, attrs.is_inline);
           clang::FunctionTemplateDecl *func_template_decl =
-              m_ast.CreateFunctionTemplateDecl(containing_decl_ctx,
-                                               template_function_decl, name,
-                                               template_param_infos);
+              m_ast.CreateFunctionTemplateDecl(
+                  containing_decl_ctx, GetOwningClangModule(die),
+                  template_function_decl, name, template_param_infos);
           m_ast.CreateFunctionTemplateSpecializationInfo(
               template_function_decl, func_template_decl, template_param_infos);
         }
@@ -1594,9 +1598,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
       TypeSystemClang::TemplateParameterInfos template_param_infos;
       if (ParseTemplateParameterInfos(die, template_param_infos)) {
         clang::ClassTemplateDecl *class_template_decl =
-            m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility,
-                                         attrs.name.GetCString(), tag_decl_kind,
-                                         template_param_infos);
+            m_ast.ParseClassTemplateDecl(
+                decl_ctx, GetOwningClangModule(die), attrs.accessibility,
+                attrs.name.GetCString(), tag_decl_kind, template_param_infos);
         if (!class_template_decl) {
           if (log) {
             dwarf->GetObjectFile()->GetModule()->LogMessage(
@@ -1611,8 +1615,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
 
         clang::ClassTemplateSpecializationDecl *class_specialization_decl =
             m_ast.CreateClassTemplateSpecializationDecl(
-                decl_ctx, class_template_decl, tag_decl_kind,
-                template_param_infos);
+                decl_ctx, GetOwningClangModule(die), class_template_decl,
+                tag_decl_kind, template_param_infos);
         clang_type = m_ast.CreateClassTemplateSpecializationType(
             class_specialization_decl);
         clang_type_was_created = true;
@@ -1625,8 +1629,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
     if (!clang_type_was_created) {
       clang_type_was_created = true;
       clang_type = m_ast.CreateRecordType(
-          decl_ctx, attrs.accessibility, attrs.name.GetCString(), tag_decl_kind,
-          attrs.class_language, &metadata, attrs.exports_symbols);
+          decl_ctx, GetOwningClangModule(die), attrs.accessibility,
+          attrs.name.GetCString(), tag_decl_kind, attrs.class_language,
+          &metadata, attrs.exports_symbols);
     }
   }
 
@@ -1638,7 +1643,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
       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(OptionalClangModuleID(), 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
@@ -3082,9 +3087,9 @@ size_t DWARFASTParserClang::ParseChildParameters(
             function_param_types.push_back(type->GetForwardCompilerType());
 
             clang::ParmVarDecl *param_var_decl =
-                m_ast.CreateParameterDeclaration(containing_decl_ctx, name,
-                                                 type->GetForwardCompilerType(),
-                                                 storage);
+                m_ast.CreateParameterDeclaration(
+                    containing_decl_ctx, GetOwningClangModule(die), name,
+                    type->GetForwardCompilerType(), storage);
             assert(param_var_decl);
             function_param_decls.push_back(param_var_decl);
 
@@ -3282,7 +3287,7 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
           TypeSystemClang::DeclContextGetAsDeclContext(
               dwarf->GetDeclContextContainingUID(die.GetID()));
       decl = m_ast.CreateVariableDeclaration(
-          decl_context, name,
+          decl_context, GetOwningClangModule(die), name,
           ClangUtil::GetQualType(type->GetForwardCompilerType()));
     }
     break;
@@ -3299,8 +3304,8 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
         if (clang::NamedDecl *clang_imported_decl =
                 llvm::dyn_cast<clang::NamedDecl>(
                     (clang::Decl *)imported_decl.GetOpaqueDecl()))
-          decl =
-              m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl);
+          decl = m_ast.CreateUsingDeclaration(
+              decl_context, OptionalClangModuleID(), clang_imported_decl);
       }
     }
     break;
@@ -3319,7 +3324,8 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
         if (clang::NamespaceDecl *ns_decl =
                 TypeSystemClang::DeclContextGetAsNamespaceDecl(
                     imported_decl_ctx))
-          decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
+          decl = m_ast.CreateUsingDirectiveDeclaration(
+              decl_context, OptionalClangModuleID(), ns_decl);
       }
     }
     break;
@@ -3377,6 +3383,32 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
   return nullptr;
 }
 
+OptionalClangModuleID
+DWARFASTParserClang::GetOwningClangModule(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 {};
+
+      OptionalClangModuleID id =
+          m_ast.GetOrCreateClangModule(name, GetOwningClangModule(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:
@@ -3449,7 +3481,8 @@ clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) {
       DWARFDIE decl_context_die;
       clang::DeclContext *decl_context =
           GetClangDeclContextContainingDIE(die, &decl_context_die);
-      decl = m_ast.CreateBlockDeclaration(decl_context);
+      decl =
+          m_ast.CreateBlockDeclaration(decl_context, GetOwningClangModule(die));
 
       if (decl)
         LinkDeclContextToDIE((clang::DeclContext *)decl, die);
@@ -3477,7 +3510,8 @@ DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) {
           die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0;
 
       namespace_decl = m_ast.GetUniqueNamespaceDeclaration(
-          namespace_name, containing_decl_ctx, is_inline);
+          namespace_name, containing_decl_ctx, GetOwningClangModule(die),
+          is_inline);
       Log *log =
           nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
       if (log) {

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 40d97ac2f11d..020d29d65eae 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -78,6 +78,9 @@ class DWARFASTParserClang : public DWARFASTParser {
       DIEToDeclContextMap;
   typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
       DeclContextToDIEMap;
+  typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
+                         lldb_private::OptionalClangModuleID>
+      DIEToModuleMap;
   typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
       DIEToDeclMap;
   typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
@@ -87,6 +90,7 @@ class DWARFASTParserClang : public DWARFASTParser {
   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 +144,7 @@ class DWARFASTParserClang : public DWARFASTParser {
 
   clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
                                                        DWARFDIE *decl_ctx_die);
+  lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &die);
 
   bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
                                   const DWARFDIE &dst_class_die,

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 1e9c24e98e41..b88f87527d8c 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -776,8 +776,9 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,
   metadata.SetUserID(toOpaqueUid(id));
   metadata.SetIsDynamicCXXType(false);
 
-  CompilerType ct = m_clang.CreateRecordType(
-      context, access, uname, ttk, lldb::eLanguageTypeC_plus_plus, &metadata);
+  CompilerType ct =
+      m_clang.CreateRecordType(context, OptionalClangModuleID(), access, uname,
+                               ttk, lldb::eLanguageTypeC_plus_plus, &metadata);
 
   lldbassert(ct.IsValid());
 
@@ -804,7 +805,8 @@ clang::NamespaceDecl *
 PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
                                         clang::DeclContext &context) {
   return m_clang.GetUniqueNamespaceDeclaration(
-      IsAnonymousNamespaceName(name) ? nullptr : name, &context);
+      IsAnonymousNamespaceName(name) ? nullptr : name, &context,
+      OptionalClangModuleID());
 }
 
 clang::BlockDecl *
@@ -814,7 +816,8 @@ PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) {
 
   clang::DeclContext *scope = GetParentDeclContext(block_id);
 
-  clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope);
+  clang::BlockDecl *block_decl =
+      m_clang.CreateBlockDeclaration(scope, OptionalClangModuleID());
   m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl});
 
   DeclStatus status;
@@ -831,7 +834,7 @@ clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym,
   clang::QualType qt = GetOrCreateType(var_info.type);
 
   clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration(
-      &scope, var_info.name.str().c_str(), qt);
+      &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt);
 
   m_uid_to_decl[toOpaqueUid(uid)] = var_decl;
   DeclStatus status;
@@ -879,7 +882,7 @@ PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) {
   std::string uname = std::string(DropNameScope(udt.Name));
 
   CompilerType ct = m_clang.CreateTypedefType(ToCompilerType(qt), uname.c_str(),
-                                              ToCompilerDeclContext(*scope));
+                                              ToCompilerDeclContext(*scope), 0);
   clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct);
   DeclStatus status;
   status.resolved = true;
@@ -1012,7 +1015,8 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
   proc_name.consume_front("::");
 
   clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
-      parent, proc_name.str().c_str(), func_ct, storage, false);
+      parent, OptionalClangModuleID(), proc_name.str().c_str(), func_ct,
+      storage, false);
 
   lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
   m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
@@ -1080,8 +1084,8 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
 
     CompilerType param_type_ct = m_clang.GetType(qt);
     clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
-        &function_decl, param_name.str().c_str(), param_type_ct,
-        clang::SC_None, true);
+        &function_decl, OptionalClangModuleID(), param_name.str().c_str(),
+        param_type_ct, clang::SC_None, true);
     lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
 
     m_uid_to_decl[toOpaqueUid(param_uid)] = param;
@@ -1102,8 +1106,8 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,
 
   Declaration declaration;
   CompilerType enum_ct = m_clang.CreateEnumerationType(
-      uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type),
-      er.isScoped());
+      uname.c_str(), decl_context, OptionalClangModuleID(), declaration,
+      ToCompilerType(underlying_type), er.isScoped());
 
   TypeSystemClang::StartTagDeclarationDefinition(enum_ct);
   TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);

diff  --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index a03878890d5c..112bec41af8b 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -409,9 +409,9 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
       metadata.SetUserID(type.getSymIndexId());
       metadata.SetIsDynamicCXXType(false);
 
-      clang_type =
-          m_ast.CreateRecordType(decl_context, access, name, tag_type_kind,
-                                 lldb::eLanguageTypeC_plus_plus, &metadata);
+      clang_type = m_ast.CreateRecordType(
+          decl_context, OptionalClangModuleID(), access, name, tag_type_kind,
+          lldb::eLanguageTypeC_plus_plus, &metadata);
       assert(clang_type.IsValid());
 
       auto record_decl =
@@ -497,7 +497,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
       // Class). Set it false for now.
       bool isScoped = false;
 
-      ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, decl,
+      ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context,
+                                             OptionalClangModuleID(), decl,
                                              builtin_type, isScoped);
 
       auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);
@@ -550,7 +551,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
       CompilerType target_ast_type = target_type->GetFullCompilerType();
 
       ast_typedef = m_ast.CreateTypedefType(
-          target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx));
+          target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0);
       if (!ast_typedef)
         return nullptr;
 
@@ -901,7 +902,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
         return nullptr;
 
       decl = m_ast.CreateVariableDeclaration(
-          decl_context, name.c_str(),
+          decl_context, OptionalClangModuleID(), name.c_str(),
           ClangUtil::GetQualType(type->GetLayoutCompilerType()));
     }
 
@@ -927,8 +928,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
                                     : clang::StorageClass::SC_None;
 
     auto decl = m_ast.CreateFunctionDeclaration(
-        decl_context, name.c_str(), type->GetForwardCompilerType(), storage,
-        func->hasInlineAttribute());
+        decl_context, OptionalClangModuleID(), name.c_str(),
+        type->GetForwardCompilerType(), storage, func->hasInlineAttribute());
 
     std::vector<clang::ParmVarDecl *> params;
     if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
@@ -941,8 +942,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
             continue;
 
           clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
-              decl, nullptr, arg_type->GetForwardCompilerType(),
-              clang::SC_None, true);
+              decl, OptionalClangModuleID(), nullptr,
+              arg_type->GetForwardCompilerType(), clang::SC_None, true);
           if (param)
             params.push_back(param);
         }
@@ -1056,8 +1057,8 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol(
           IsAnonymousNamespaceName(namespace_name) ? nullptr
                                                    : namespace_name.data();
       clang::NamespaceDecl *namespace_decl =
-          m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str,
-                                              curr_context);
+          m_ast.GetUniqueNamespaceDeclaration(
+              namespace_name_c_str, curr_context, OptionalClangModuleID());
 
       m_parent_to_namespaces[curr_context].insert(namespace_decl);
       m_namespaces.insert(namespace_decl);

diff  --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 50f53e5a8b50..33b1ed115e92 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -419,8 +419,9 @@ void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() {
       CompilerType uint16 =
           ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
       CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(
-          nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s",
-          clang::TTK_Struct, lldb::eLanguageTypeC);
+          nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
+          "__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct,
+          lldb::eLanguageTypeC);
 
       TypeSystemClang::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
       TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s,

diff  --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index ecb15201069d..8598e413edc6 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -34,6 +34,9 @@
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Frontend/FrontendOptions.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Lex/ModuleMap.h"
 #include "clang/Sema/Sema.h"
 
 #include "llvm/Support/Signals.h"
@@ -316,10 +319,33 @@ static ClangASTMap &GetASTMap() {
   return *g_map_ptr;
 }
 
-TypePayloadClang::TypePayloadClang(bool is_complete_objc_class) {
+TypePayloadClang::TypePayloadClang(OptionalClangModuleID owning_module,
+                                   bool is_complete_objc_class)
+    : m_payload(owning_module.GetValue()) {
   SetIsCompleteObjCClass(is_complete_objc_class);
 }
 
+void TypePayloadClang::SetOwningModule(OptionalClangModuleID id) {
+  assert(id.GetValue() < ObjCClassBit);
+  bool is_complete = IsCompleteObjCClass();
+  m_payload = id.GetValue();
+  SetIsCompleteObjCClass(is_complete);
+}
+
+static void SetMemberOwningModule(clang::Decl *member,
+                                  const clang::Decl *parent) {
+  if (!member || !parent)
+    return;
+
+  OptionalClangModuleID id(parent->getOwningModuleID());
+  if (!id.HasValue())
+    return;
+
+  member->setFromASTFile();
+  member->setOwningModuleID(id.GetValue());
+  member->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
+}
+
 char TypeSystemClang::ID;
 
 bool TypeSystemClang::IsOperator(llvm::StringRef name,
@@ -505,6 +531,10 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
   //
   // FIXME: This is affected by other options (-fno-inline).
   Opts.NoInlineDefine = !Opt;
+
+  // This is needed to allocate the extra space for the owning module
+  // on each decl.
+  Opts.ModulesLocalVisibility = 1;
 }
 
 TypeSystemClang::TypeSystemClang(llvm::StringRef name,
@@ -1186,12 +1216,60 @@ CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) {
 
 #pragma mark Structure, Unions, Classes
 
-CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx,
-                                               AccessType access_type,
-                                               llvm::StringRef name, int kind,
-                                               LanguageType language,
-                                               ClangASTMetadata *metadata,
-                                               bool exports_symbols) {
+void TypeSystemClang::SetOwningModule(clang::Decl *decl,
+                                      OptionalClangModuleID owning_module) {
+  if (!decl || !owning_module.HasValue())
+    return;
+
+  decl->setFromASTFile();
+  decl->setOwningModuleID(owning_module.GetValue());
+  decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
+  if (auto *decl_ctx = llvm::dyn_cast<clang::DeclContext>(decl)) {
+    decl_ctx->setHasExternalVisibleStorage();
+    if (auto *ns = llvm::dyn_cast<NamespaceDecl>(decl_ctx))
+      ns->getPrimaryContext()->setMustBuildLookupTable();
+  }
+}
+
+OptionalClangModuleID
+TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name,
+                                        OptionalClangModuleID parent,
+                                        bool is_framework, bool is_explicit) {
+  // Get the external AST source which holds the modules.
+  auto *ast_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
+      getASTContext().getExternalSource());
+  assert(ast_source && "external ast source was lost");
+  if (!ast_source)
+    return {};
+
+  // Lazily initialize the module map.
+  if (!m_header_search_up) {
+    auto HSOpts = std::make_shared<clang::HeaderSearchOptions>();
+    m_header_search_up = std::make_unique<clang::HeaderSearch>(
+        HSOpts, *m_source_manager_up, *m_diagnostics_engine_up,
+        *m_language_options_up, m_target_info_up.get());
+    m_module_map_up = std::make_unique<clang::ModuleMap>(
+        *m_source_manager_up, *m_diagnostics_engine_up, *m_language_options_up,
+        m_target_info_up.get(), *m_header_search_up);
+  }
+
+  // Get or create the module context.
+  bool created;
+  clang::Module *module;
+  auto parent_desc = ast_source->getSourceDescriptor(parent.GetValue());
+  std::tie(module, created) = m_module_map_up->findOrCreateModule(
+      name, parent_desc ? parent_desc->getModuleOrNull() : nullptr,
+      is_framework, is_explicit);
+  if (!created)
+    return ast_source->GetIDForModule(module);
+
+  return ast_source->RegisterModule(module);
+}
+
+CompilerType TypeSystemClang::CreateRecordType(
+    clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+    AccessType access_type, llvm::StringRef name, int kind,
+    LanguageType language, ClangASTMetadata *metadata, bool exports_symbols) {
   ASTContext &ast = getASTContext();
 
   if (decl_ctx == nullptr)
@@ -1201,7 +1279,8 @@ CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx,
       language == eLanguageTypeObjC_plus_plus) {
     bool isForwardDecl = true;
     bool isInternal = false;
-    return CreateObjCClass(name, decl_ctx, isForwardDecl, isInternal, metadata);
+    return CreateObjCClass(name, decl_ctx, owning_module, isForwardDecl,
+                           isInternal, metadata);
   }
 
   // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
@@ -1216,6 +1295,7 @@ CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx,
   decl->setDeclContext(decl_ctx);
   if (has_name)
     decl->setDeclName(&ast.Idents.get(name));
+  SetOwningModule(decl, owning_module);
 
   if (!has_name) {
     // In C++ a lambda is also represented as an unnamed class. This is
@@ -1327,13 +1407,13 @@ static TemplateParameterList *CreateTemplateParameterList(
 }
 
 clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
-    clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl,
-    const char *name, const TemplateParameterInfos &template_param_infos) {
+    clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+    clang::FunctionDecl *func_decl, const char *name,
+    const TemplateParameterInfos &template_param_infos) {
   //    /// Create a function template node.
   ASTContext &ast = getASTContext();
 
   llvm::SmallVector<NamedDecl *, 8> template_param_decls;
-
   TemplateParameterList *template_param_list = CreateTemplateParameterList(
       ast, template_param_infos, template_param_decls);
   FunctionTemplateDecl *func_tmpl_decl =
@@ -1342,6 +1422,7 @@ clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
   func_tmpl_decl->setLocation(func_decl->getLocation());
   func_tmpl_decl->setDeclName(func_decl->getDeclName());
   func_tmpl_decl->init(func_decl, template_param_list);
+  SetOwningModule(func_tmpl_decl, owning_module);
 
   for (size_t i = 0, template_param_decl_count = template_param_decls.size();
        i < template_param_decl_count; ++i) {
@@ -1368,8 +1449,9 @@ void TypeSystemClang::CreateFunctionTemplateSpecializationInfo(
 }
 
 ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
-    DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name,
-    int kind, const TemplateParameterInfos &template_param_infos) {
+    DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+    lldb::AccessType access_type, const char *class_name, int kind,
+    const TemplateParameterInfos &template_param_infos) {
   ASTContext &ast = getASTContext();
 
   ClassTemplateDecl *class_template_decl = nullptr;
@@ -1397,6 +1479,7 @@ ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
   // What decl context do we use here? TU? The actual decl context?
   template_cxx_decl->setDeclContext(decl_ctx);
   template_cxx_decl->setDeclName(decl_name);
+  SetOwningModule(template_cxx_decl, owning_module);
 
   for (size_t i = 0, template_param_decl_count = template_param_decls.size();
        i < template_param_decl_count; ++i) {
@@ -1414,6 +1497,7 @@ ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
   class_template_decl->setDeclName(decl_name);
   class_template_decl->init(template_cxx_decl, template_param_list);
   template_cxx_decl->setDescribedClassTemplate(class_template_decl);
+  SetOwningModule(class_template_decl, owning_module);
 
   if (class_template_decl) {
     if (access_type != eAccessNone)
@@ -1453,7 +1537,8 @@ TypeSystemClang::CreateTemplateTemplateParmDecl(const char *template_name) {
 
 ClassTemplateSpecializationDecl *
 TypeSystemClang::CreateClassTemplateSpecializationDecl(
-    DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
+    DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+    ClassTemplateDecl *class_template_decl, int kind,
     const TemplateParameterInfos &template_param_infos) {
   ASTContext &ast = getASTContext();
   llvm::SmallVector<clang::TemplateArgument, 2> args(
@@ -1476,6 +1561,16 @@ TypeSystemClang::CreateClassTemplateSpecializationDecl(
   ast.getTypeDeclType(class_template_specialization_decl, nullptr);
   class_template_specialization_decl->setDeclName(
       class_template_decl->getDeclName());
+  // FIXME: Turning this on breaks the libcxx data formatter tests.
+  // SetOwningModule marks the Decl as external, which prevents a
+  // LookupPtr from being built. Template instantiations can also not
+  // be found by ExternalASTSource::FindExternalVisibleDeclsByName(),
+  // nor can we lazily build a LookupPtr later, because template
+  // specializations are supposed to be hidden so
+  // makeDeclVisibleInContextWithFlags() is a noop, as well.
+  //
+  // SetOwningModule(class_template_specialization_decl, owning_module);
+  decl_ctx->addDecl(class_template_specialization_decl);
 
   class_template_specialization_decl->setSpecializationKind(
       TSK_ExplicitSpecialization);
@@ -1594,14 +1689,13 @@ bool TypeSystemClang::RecordHasFields(const RecordDecl *record_decl) {
 
 #pragma mark Objective-C Classes
 
-CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name,
-                                              DeclContext *decl_ctx,
-                                              bool isForwardDecl,
-                                              bool isInternal,
-                                              ClangASTMetadata *metadata) {
+CompilerType TypeSystemClang::CreateObjCClass(
+    llvm::StringRef name, clang::DeclContext *decl_ctx,
+    OptionalClangModuleID owning_module, bool isForwardDecl, bool isInternal,
+    ClangASTMetadata *metadata) {
   ASTContext &ast = getASTContext();
   assert(!name.empty());
-  if (decl_ctx == nullptr)
+  if (!decl_ctx)
     decl_ctx = ast.getTranslationUnitDecl();
 
   ObjCInterfaceDecl *decl = ObjCInterfaceDecl::CreateDeserialized(ast, 0);
@@ -1609,6 +1703,7 @@ CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name,
   decl->setDeclName(&ast.Idents.get(name));
   /*isForwardDecl,*/
   decl->setImplicit(isInternal);
+  SetOwningModule(decl, owning_module);
 
   if (decl && metadata)
     SetMetadata(decl, *metadata);
@@ -1646,11 +1741,12 @@ TypeSystemClang::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl,
 #pragma mark Namespace Declarations
 
 NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration(
-    const char *name, clang::DeclContext *decl_ctx, bool is_inline) {
+    const char *name, clang::DeclContext *decl_ctx,
+    OptionalClangModuleID owning_module, bool is_inline) {
   NamespaceDecl *namespace_decl = nullptr;
   ASTContext &ast = getASTContext();
   TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl();
-  if (decl_ctx == nullptr)
+  if (!decl_ctx)
     decl_ctx = translation_unit_decl;
 
   if (name) {
@@ -1699,17 +1795,23 @@ NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration(
       }
     }
   }
+  // Note: namespaces can span multiple modules, so perhaps this isn't a good
+  // idea.
+  SetOwningModule(namespace_decl, owning_module);
+
   VerifyDecl(namespace_decl);
   return namespace_decl;
 }
 
 clang::BlockDecl *
-TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx) {
+TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx,
+                                        OptionalClangModuleID owning_module) {
   if (ctx) {
     clang::BlockDecl *decl =
         clang::BlockDecl::CreateDeserialized(getASTContext(), 0);
     decl->setDeclContext(ctx);
     ctx->addDecl(decl);
+    SetOwningModule(decl, owning_module);
     return decl;
   }
   return nullptr;
@@ -1733,7 +1835,8 @@ clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left,
 }
 
 clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration(
-    clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) {
+    clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+    clang::NamespaceDecl *ns_decl) {
   if (decl_ctx && ns_decl) {
     auto *translation_unit = getASTContext().getTranslationUnitDecl();
     clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
@@ -1743,6 +1846,7 @@ clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration(
           FindLCABetweenDecls(decl_ctx, ns_decl,
                               translation_unit));
       decl_ctx->addDecl(using_decl);
+      SetOwningModule(using_decl, owning_module);
       return using_decl;
   }
   return nullptr;
@@ -1750,14 +1854,17 @@ clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration(
 
 clang::UsingDecl *
 TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
+                                        OptionalClangModuleID owning_module,
                                         clang::NamedDecl *target) {
-  if (current_decl_ctx != nullptr && target != nullptr) {
+  if (current_decl_ctx && target) {
     clang::UsingDecl *using_decl = clang::UsingDecl::Create(
         getASTContext(), current_decl_ctx, clang::SourceLocation(),
         clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
+    SetOwningModule(using_decl, owning_module);
     clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
         getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
         target);
+    SetOwningModule(shadow_decl, owning_module);
     using_decl->addShadowDecl(shadow_decl);
     current_decl_ctx->addDecl(using_decl);
     return using_decl;
@@ -1766,7 +1873,8 @@ TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
 }
 
 clang::VarDecl *TypeSystemClang::CreateVariableDeclaration(
-    clang::DeclContext *decl_context, const char *name, clang::QualType type) {
+    clang::DeclContext *decl_context, OptionalClangModuleID owning_module,
+    const char *name, clang::QualType type) {
   if (decl_context) {
     clang::VarDecl *var_decl =
         clang::VarDecl::CreateDeserialized(getASTContext(), 0);
@@ -1774,6 +1882,7 @@ clang::VarDecl *TypeSystemClang::CreateVariableDeclaration(
     if (name && name[0])
       var_decl->setDeclName(&getASTContext().Idents.getOwn(name));
     var_decl->setType(type);
+    SetOwningModule(var_decl, owning_module);
     var_decl->setAccess(clang::AS_public);
     decl_context->addDecl(var_decl);
     return var_decl;
@@ -1885,11 +1994,12 @@ TypeSystemClang::GetDeclarationName(const char *name,
 }
 
 FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
-    DeclContext *decl_ctx, const char *name,
-    const CompilerType &function_clang_type, int storage, bool is_inline) {
+    clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+    const char *name, const CompilerType &function_clang_type, int storage,
+    bool is_inline) {
   FunctionDecl *func_decl = nullptr;
   ASTContext &ast = getASTContext();
-  if (decl_ctx == nullptr)
+  if (!decl_ctx)
     decl_ctx = ast.getTranslationUnitDecl();
 
   const bool hasWrittenPrototype = true;
@@ -1906,6 +2016,7 @@ FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
   func_decl->setHasWrittenPrototype(hasWrittenPrototype);
   func_decl->setConstexprKind(isConstexprSpecified ? CSK_constexpr
                                                    : CSK_unspecified);
+  SetOwningModule(func_decl, owning_module);
   if (func_decl)
     decl_ctx->addDecl(func_decl);
 
@@ -1954,8 +2065,9 @@ TypeSystemClang::CreateFunctionType(const CompilerType &result_type,
 }
 
 ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
-    clang::DeclContext *decl_ctx, const char *name,
-    const CompilerType &param_type, int storage, bool add_decl) {
+    clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+    const char *name, const CompilerType &param_type, int storage,
+    bool add_decl) {
   ASTContext &ast = getASTContext();
   auto *decl = ParmVarDecl::CreateDeserialized(ast, 0);
   decl->setDeclContext(decl_ctx);
@@ -1963,6 +2075,7 @@ ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
     decl->setDeclName(&ast.Idents.get(name));
   decl->setType(ClangUtil::GetQualType(param_type));
   decl->setStorageClass(static_cast<clang::StorageClass>(storage));
+  SetOwningModule(decl, owning_module);
   if (add_decl)
     decl_ctx->addDecl(decl);
 
@@ -2024,8 +2137,9 @@ CompilerType TypeSystemClang::CreateStructForIdentifier(
     return type;
   }
 
-  type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(),
-                          clang::TTK_Struct, lldb::eLanguageTypeC);
+  type = CreateRecordType(nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
+                          type_name.GetCString(), clang::TTK_Struct,
+                          lldb::eLanguageTypeC);
   StartTagDeclarationDefinition(type);
   for (const auto &field : type_fields)
     AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic,
@@ -2050,11 +2164,10 @@ CompilerType TypeSystemClang::GetOrCreateStructForIdentifier(
 
 #pragma mark Enumeration Types
 
-CompilerType
-TypeSystemClang::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
-                                       const Declaration &decl,
-                                       const CompilerType &integer_clang_type,
-                                       bool is_scoped) {
+CompilerType TypeSystemClang::CreateEnumerationType(
+    const char *name, clang::DeclContext *decl_ctx,
+    OptionalClangModuleID owning_module, const Declaration &decl,
+    const CompilerType &integer_clang_type, bool is_scoped) {
   // TODO: Do something intelligent with the Declaration object passed in
   // like maybe filling in the SourceLocation with it...
   ASTContext &ast = getASTContext();
@@ -2068,6 +2181,7 @@ TypeSystemClang::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
   enum_decl->setScoped(is_scoped);
   enum_decl->setScopedUsingClassTag(is_scoped);
   enum_decl->setFixed(false);
+  SetOwningModule(enum_decl, owning_module);
   if (enum_decl) {
     if (decl_ctx)
       decl_ctx->addDecl(enum_decl);
@@ -4254,7 +4368,7 @@ TypeSystemClang::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
 
 CompilerType TypeSystemClang::CreateTypedefType(
     const CompilerType &type, const char *typedef_name,
-    const CompilerDeclContext &compiler_decl_ctx) {
+    const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) {
   if (type && typedef_name && typedef_name[0]) {
     TypeSystemClang *ast =
         llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
@@ -4265,7 +4379,7 @@ CompilerType TypeSystemClang::CreateTypedefType(
 
     clang::DeclContext *decl_ctx =
         TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx);
-    if (decl_ctx == nullptr)
+    if (!decl_ctx)
       decl_ctx = ast->getASTContext().getTranslationUnitDecl();
 
     clang::TypedefDecl *decl =
@@ -4274,6 +4388,7 @@ CompilerType TypeSystemClang::CreateTypedefType(
     decl->setDeclName(&clang_ast.Idents.get(typedef_name));
     decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(qual_type));
 
+    SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule());
     decl->setAccess(clang::AS_public); // TODO respect proper access specifier
 
     decl_ctx->addDecl(decl);
@@ -4362,24 +4477,23 @@ TypeSystemClang::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
   return CompilerType();
 }
 
-CompilerType
-TypeSystemClang::CreateTypedef(lldb::opaque_compiler_type_t type,
-                               const char *typedef_name,
-                               const CompilerDeclContext &compiler_decl_ctx) {
+CompilerType TypeSystemClang::CreateTypedef(
+    lldb::opaque_compiler_type_t type, const char *typedef_name,
+    const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) {
   if (type) {
     clang::ASTContext &clang_ast = getASTContext();
     clang::QualType qual_type(GetQualType(type));
 
     clang::DeclContext *decl_ctx =
         TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx);
-    if (decl_ctx == nullptr)
+    if (!decl_ctx)
       decl_ctx = getASTContext().getTranslationUnitDecl();
 
-    clang::TypedefDecl *decl =
-        clang::TypedefDecl::CreateDeserialized(clang_ast, 0);
-    decl->setDeclContext(decl_ctx);
-    decl->setDeclName(&clang_ast.Idents.get(typedef_name));
-    decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(qual_type));
+    clang::TypedefDecl *decl = clang::TypedefDecl::Create(
+        clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
+        &clang_ast.Idents.get(typedef_name),
+        clang_ast.getTrivialTypeSourceInfo(qual_type));
+    SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule());
 
     clang::TagDecl *tdecl = nullptr;
     if (!qual_type.isNull()) {
@@ -6923,6 +7037,7 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
     field->setType(ClangUtil::GetQualType(field_clang_type));
     if (bit_width)
       field->setBitWidth(bit_width);
+    SetMemberOwningModule(field, record_decl);
 
     if (name.empty()) {
       // Determine whether this field corresponds to an anonymous struct or
@@ -6964,6 +7079,7 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
         ivar->setBitWidth(bit_width);
       ivar->setSynthesize(is_synthesized);
       field = ivar;
+      SetMemberOwningModule(field, class_interface_decl);
 
       if (field) {
         class_interface_decl->addDecl(field);
@@ -7025,6 +7141,7 @@ void TypeSystemClang::BuildIndirectFields(const CompilerType &type) {
                   ast->getASTContext(), record_decl, clang::SourceLocation(),
                   nested_field_decl->getIdentifier(),
                   nested_field_decl->getType(), {chain, 2});
+          SetMemberOwningModule(indirect_field, record_decl);
 
           indirect_field->setImplicit();
 
@@ -7055,6 +7172,7 @@ void TypeSystemClang::BuildIndirectFields(const CompilerType &type) {
                   nested_indirect_field_decl->getIdentifier(),
                   nested_indirect_field_decl->getType(),
                   {chain, nested_chain_size + 1});
+          SetMemberOwningModule(indirect_field, record_decl);
 
           indirect_field->setImplicit();
 
@@ -7121,6 +7239,7 @@ clang::VarDecl *TypeSystemClang::AddVariableToRecordType(
   var_decl->setDeclName(ident);
   var_decl->setType(ClangUtil::GetQualType(var_type));
   var_decl->setStorageClass(clang::SC_Static);
+  SetMemberOwningModule(var_decl, record_decl);
   if (!var_decl)
     return nullptr;
 
@@ -7256,6 +7375,7 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
       cxx_method_decl->setConstexprKind(CSK_unspecified);
     }
   }
+  SetMemberOwningModule(cxx_method_decl, cxx_record_decl);
 
   clang::AccessSpecifier access_specifier =
       TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
@@ -7430,6 +7550,7 @@ bool TypeSystemClang::AddObjCClassProperty(
                              ? ivar_decl->getType()
                              : ClangUtil::GetQualType(property_clang_type),
                          prop_type_source);
+  SetMemberOwningModule(property_decl, class_interface_decl);
 
   if (!property_decl)
     return false;
@@ -7521,6 +7642,7 @@ bool TypeSystemClang::AddObjCClassProperty(
     getter->setDefined(isDefined);
     getter->setDeclImplementation(impControl);
     getter->setRelatedResultType(HasRelatedResultType);
+    SetMemberOwningModule(getter, class_interface_decl);
 
     if (getter) {
       if (metadata)
@@ -7562,6 +7684,7 @@ bool TypeSystemClang::AddObjCClassProperty(
     setter->setDefined(isDefined);
     setter->setDeclImplementation(impControl);
     setter->setRelatedResultType(HasRelatedResultType);
+    SetMemberOwningModule(setter, class_interface_decl);
 
     if (setter) {
       if (metadata)
@@ -7690,6 +7813,7 @@ clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType(
   objc_method_decl->setDefined(isDefined);
   objc_method_decl->setDeclImplementation(impControl);
   objc_method_decl->setRelatedResultType(HasRelatedResultType);
+  SetMemberOwningModule(objc_method_decl, class_interface_decl);
 
   if (objc_method_decl == nullptr)
     return nullptr;
@@ -7920,6 +8044,7 @@ clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
     enumerator_decl->setDeclName(&getASTContext().Idents.get(name));
   enumerator_decl->setType(clang::QualType(enutype, 0));
   enumerator_decl->setInitVal(value);
+  SetMemberOwningModule(enumerator_decl, enutype->getDecl());
 
   if (!enumerator_decl)
     return nullptr;
@@ -8814,14 +8939,14 @@ void TypeSystemClang::DumpTypeName(const CompilerType &type) {
 }
 
 clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl(
-    clang::DeclContext *decl_ctx, lldb::AccessType access_type,
-    const char *parent_name, int tag_decl_kind,
+    clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+    lldb::AccessType access_type, const char *parent_name, int tag_decl_kind,
     const TypeSystemClang::TemplateParameterInfos &template_param_infos) {
   if (template_param_infos.IsValid()) {
     std::string template_basename(parent_name);
     template_basename.erase(template_basename.find('<'));
 
-    return CreateClassTemplateDecl(decl_ctx, access_type,
+    return CreateClassTemplateDecl(decl_ctx, owning_module, access_type,
                                    template_basename.c_str(), tag_decl_kind,
                                    template_param_infos);
   }

diff  --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index f355681f2679..b326ee56cb8a 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -53,13 +53,30 @@ class ClangASTMetadata;
 class ClangASTSource;
 class Declaration;
 
+/// A Clang module ID.
+class OptionalClangModuleID {
+  unsigned m_id = 0;
+
+public:
+  OptionalClangModuleID() = default;
+  explicit OptionalClangModuleID(unsigned id) : m_id(id) {}
+  bool HasValue() const { return m_id != 0; }
+  unsigned GetValue() const { return m_id; }
+};
+
 /// The implementation of lldb::Type's m_payload field for TypeSystemClang.
 class TypePayloadClang {
-  /// Layout: bit 31 ... IsCompleteObjCClass.
+  /// The Layout is as follows:
+  /// \verbatim
+  /// bit 0..30 ... Owning Module ID.
+  /// bit 31 ...... IsCompleteObjCClass.
+  /// \endverbatim
   Type::Payload m_payload = 0;
+
 public:
   TypePayloadClang() = default;
-  explicit TypePayloadClang(bool is_complete_objc_class);
+  explicit TypePayloadClang(OptionalClangModuleID owning_module,
+                            bool is_complete_objc_class = false);
   explicit TypePayloadClang(uint32_t opaque_payload) : m_payload(opaque_payload) {}
   operator Type::Payload() { return m_payload; }
 
@@ -69,6 +86,11 @@ class TypePayloadClang {
     m_payload = is_complete_objc_class ? Flags(m_payload).Set(ObjCClassBit)
                                        : Flags(m_payload).Clear(ObjCClassBit);
   }
+  OptionalClangModuleID GetOwningModule() {
+    return OptionalClangModuleID(Flags(m_payload).Clear(ObjCClassBit));
+  }
+  void SetOwningModule(OptionalClangModuleID id);
+  /// \}
 };
   
 /// A TypeSystem implementation based on Clang.
@@ -293,7 +315,14 @@ class TypeSystemClang : public TypeSystem {
   static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl,
                                     bool omit_empty_base_classes);
 
+  /// Synthesize a clang::Module and return its ID or a default-constructed ID.
+  OptionalClangModuleID GetOrCreateClangModule(llvm::StringRef name,
+                                               OptionalClangModuleID parent,
+                                               bool is_framework = false,
+                                               bool is_explicit = false);
+
   CompilerType CreateRecordType(clang::DeclContext *decl_ctx,
+                                OptionalClangModuleID owning_module,
                                 lldb::AccessType access_type,
                                 llvm::StringRef name, int kind,
                                 lldb::LanguageType language,
@@ -319,6 +348,7 @@ class TypeSystemClang : public TypeSystem {
 
   clang::FunctionTemplateDecl *
   CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx,
+                             OptionalClangModuleID owning_module,
                              clang::FunctionDecl *func_decl, const char *name,
                              const TemplateParameterInfos &infos);
 
@@ -328,6 +358,7 @@ class TypeSystemClang : public TypeSystem {
 
   clang::ClassTemplateDecl *
   CreateClassTemplateDecl(clang::DeclContext *decl_ctx,
+                          OptionalClangModuleID owning_module,
                           lldb::AccessType access_type, const char *class_name,
                           int kind, const TemplateParameterInfos &infos);
 
@@ -335,7 +366,7 @@ class TypeSystemClang : public TypeSystem {
   CreateTemplateTemplateParmDecl(const char *template_name);
 
   clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl(
-      clang::DeclContext *decl_ctx,
+      clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
       clang::ClassTemplateDecl *class_template_decl, int kind,
       const TemplateParameterInfos &infos);
 
@@ -355,8 +386,9 @@ class TypeSystemClang : public TypeSystem {
   static bool RecordHasFields(const clang::RecordDecl *record_decl);
 
   CompilerType CreateObjCClass(llvm::StringRef name,
-                               clang::DeclContext *decl_ctx, bool isForwardDecl,
-                               bool isInternal,
+                               clang::DeclContext *decl_ctx,
+                               OptionalClangModuleID owning_module,
+                               bool isForwardDecl, bool isInternal,
                                ClangASTMetadata *metadata = nullptr);
 
   bool SetTagTypeKind(clang::QualType type, int kind) const;
@@ -373,14 +405,16 @@ class TypeSystemClang : public TypeSystem {
 
   clang::NamespaceDecl *
   GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx,
+                                OptionalClangModuleID owning_module,
                                 bool is_inline = false);
 
   // Function Types
 
   clang::FunctionDecl *
-  CreateFunctionDeclaration(clang::DeclContext *decl_ctx, const char *name,
-                            const CompilerType &function_Type, int storage,
-                            bool is_inline);
+  CreateFunctionDeclaration(clang::DeclContext *decl_ctx,
+                            OptionalClangModuleID owning_module,
+                            const char *name, const CompilerType &function_Type,
+                            int storage, bool is_inline);
 
   CompilerType CreateFunctionType(const CompilerType &result_type,
                                   const CompilerType *args, unsigned num_args,
@@ -394,11 +428,11 @@ class TypeSystemClang : public TypeSystem {
                               type_quals, clang::CC_C);
   }
 
-  clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx,
-                                                 const char *name,
-                                                 const CompilerType &param_type,
-                                                 int storage,
-                                                 bool add_decl=false);
+  clang::ParmVarDecl *
+  CreateParameterDeclaration(clang::DeclContext *decl_ctx,
+                             OptionalClangModuleID owning_module,
+                             const char *name, const CompilerType &param_type,
+                             int storage, bool add_decl = false);
 
   void SetFunctionParameters(clang::FunctionDecl *function_decl,
                              clang::ParmVarDecl **params, unsigned num_params);
@@ -413,6 +447,7 @@ class TypeSystemClang : public TypeSystem {
   // Enumeration Types
   CompilerType CreateEnumerationType(const char *name,
                                      clang::DeclContext *decl_ctx,
+                                     OptionalClangModuleID owning_module,
                                      const Declaration &decl,
                                      const CompilerType &integer_qual_type,
                                      bool is_scoped);
@@ -479,6 +514,10 @@ class TypeSystemClang : public TypeSystem {
   /// TypeSystemClang.
   CompilerDeclContext CreateDeclContext(clang::DeclContext *ctx);
 
+  /// Set the owning module for \p decl.
+  static void SetOwningModule(clang::Decl *decl,
+                              OptionalClangModuleID owning_module);
+
   std::vector<CompilerDecl>
   DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
                             const bool ignore_using_decls) override;
@@ -641,11 +680,13 @@ class TypeSystemClang : public TypeSystem {
 
   // Creating related types
 
-  // Using the current type, create a new typedef to that type using
-  // "typedef_name" as the name and "decl_ctx" as the decl context.
+  /// Using the current type, create a new typedef to that type using
+  /// "typedef_name" as the name and "decl_ctx" as the decl context.
+  /// \param payload is an opaque TypePayloadClang.
   static CompilerType
   CreateTypedefType(const CompilerType &type, const char *typedef_name,
-                    const CompilerDeclContext &compiler_decl_ctx);
+                    const CompilerDeclContext &compiler_decl_ctx,
+                    uint32_t opaque_payload);
 
   CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type,
                                    uint64_t *stride) override;
@@ -696,7 +737,8 @@ class TypeSystemClang : public TypeSystem {
 
   CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
                              const char *name,
-                             const CompilerDeclContext &decl_ctx) override;
+                             const CompilerDeclContext &decl_ctx,
+                             uint32_t opaque_payload) override;
 
   // If the current object represents a typedef type, get the underlying type
   CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override;
@@ -955,20 +997,24 @@ class TypeSystemClang : public TypeSystem {
   GetAsObjCInterfaceDecl(const CompilerType &type);
 
   clang::ClassTemplateDecl *ParseClassTemplateDecl(
-      clang::DeclContext *decl_ctx, lldb::AccessType access_type,
-      const char *parent_name, int tag_decl_kind,
+      clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+      lldb::AccessType access_type, const char *parent_name, int tag_decl_kind,
       const TypeSystemClang::TemplateParameterInfos &template_param_infos);
 
-  clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx);
+  clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx,
+                                           OptionalClangModuleID owning_module);
 
   clang::UsingDirectiveDecl *
   CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx,
+                                  OptionalClangModuleID owning_module,
                                   clang::NamespaceDecl *ns_decl);
 
   clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
+                                           OptionalClangModuleID owning_module,
                                            clang::NamedDecl *target);
 
   clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context,
+                                            OptionalClangModuleID owning_module,
                                             const char *name,
                                             clang::QualType type);
 
@@ -991,6 +1037,13 @@ class TypeSystemClang : public TypeSystem {
   clang::DeclarationName
   GetDeclarationName(const char *name, const CompilerType &function_clang_type);
 
+  clang::LangOptions *GetLangOpts() const {
+    return m_language_options_up.get();
+  }
+  clang::SourceManager *GetSourceMgr() const {
+    return m_source_manager_up.get();
+  }
+
 private:
   const clang::ClassTemplateSpecializationDecl *
   GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type);
@@ -1008,6 +1061,8 @@ class TypeSystemClang : public TypeSystem {
   std::unique_ptr<clang::IdentifierTable> m_identifier_table_up;
   std::unique_ptr<clang::SelectorTable> m_selector_table_up;
   std::unique_ptr<clang::Builtin::Context> m_builtins_up;
+  std::unique_ptr<clang::HeaderSearch> m_header_search_up;
+  std::unique_ptr<clang::ModuleMap> m_module_map_up;
   std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_up;
   std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up;
   std::unique_ptr<clang::MangleContext> m_mangle_ctx_up;

diff  --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp
index 6c150988a012..f24d9939e6cb 100644
--- a/lldb/source/Symbol/CompilerType.cpp
+++ b/lldb/source/Symbol/CompilerType.cpp
@@ -439,11 +439,11 @@ CompilerType CompilerType::AddRestrictModifier() const {
     return CompilerType();
 }
 
-CompilerType
-CompilerType::CreateTypedef(const char *name,
-                            const CompilerDeclContext &decl_ctx) const {
+CompilerType CompilerType::CreateTypedef(const char *name,
+                                         const CompilerDeclContext &decl_ctx,
+                                         uint32_t payload) const {
   if (IsValid())
-    return m_type_system->CreateTypedef(m_type, name, decl_ctx);
+    return m_type_system->CreateTypedef(m_type, name, decl_ctx, payload);
   else
     return CompilerType();
 }

diff  --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 804f7e02d3c9..058d4c714634 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -505,7 +505,7 @@ bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {
       case eEncodingIsTypedefUID:
         m_compiler_type = encoding_type->GetForwardCompilerType().CreateTypedef(
             m_name.AsCString("__lldb_invalid_typedef_name"),
-            GetSymbolFile()->GetDeclContextContainingUID(GetID()));
+            GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload);
         m_name.Clear();
         break;
 
@@ -563,7 +563,7 @@ bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {
         case eEncodingIsTypedefUID:
           m_compiler_type = void_compiler_type.CreateTypedef(
               m_name.AsCString("__lldb_invalid_typedef_name"),
-              GetSymbolFile()->GetDeclContextContainingUID(GetID()));
+              GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload);
           break;
 
         case eEncodingIsPointerUID:

diff  --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp
index fd5b9613f717..5e57813c28bd 100644
--- a/lldb/source/Symbol/TypeSystem.cpp
+++ b/lldb/source/Symbol/TypeSystem.cpp
@@ -113,7 +113,8 @@ TypeSystem::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
 
 CompilerType TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type,
                                        const char *name,
-                                       const CompilerDeclContext &decl_ctx) {
+                                       const CompilerDeclContext &decl_ctx,
+                                       uint32_t opaque_payload) {
   return CompilerType();
 }
 

diff  --git a/lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/A.h b/lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/A.h
new file mode 100644
index 000000000000..4b223cafdcba
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/A.h
@@ -0,0 +1,29 @@
+#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;
+
+ at interface SomeClass {
+}
+ at 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>;
+}

diff  --git a/lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/B.h b/lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/B.h
new file mode 100644
index 000000000000..23d8347a2322
--- /dev/null
+++ b/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>;
+} // namespace Namespace

diff  --git a/lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/module.modulemap b/lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/module.modulemap
new file mode 100644
index 000000000000..b9940a8f53bf
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/module.modulemap
@@ -0,0 +1,6 @@
+module A {
+  header "A.h"
+  module B {
+    header "B.h"
+  }
+}

diff  --git a/lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg b/lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
index 8c4600c6922b..84376e61665b 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
+++ b/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']

diff  --git a/lldb/test/Shell/SymbolFile/DWARF/module-ownership.mm b/lldb/test/Shell/SymbolFile/DWARF/module-ownership.mm
new file mode 100644
index 000000000000..6a876d1ea578
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/module-ownership.mm
@@ -0,0 +1,42 @@
+// 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.
+
+ at 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 specializations are not yet supported, so they lack the ownership info:
+Template<int> t2;
+// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} struct Template
+
+Namespace::InNamespace<int> t3;
+// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} struct InNamespace
+
+Namespace::AlsoInNamespace<int> t4;
+// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} struct AlsoInNamespace

diff  --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
index a3345e815ee9..c67168ba5f56 100644
--- a/lldb/unittests/Symbol/TestTypeSystemClang.cpp
+++ b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
@@ -14,6 +14,7 @@
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Symbol/Declaration.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "gtest/gtest.h"
 
@@ -257,9 +258,10 @@ TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) {
       CompilerType basic_compiler_type = ast.GetBasicType(basic_type);
       EXPECT_TRUE(basic_compiler_type.IsValid());
 
-      CompilerType enum_type =
-          ast.CreateEnumerationType("my_enum", ast.GetTranslationUnitDecl(),
-                                    Declaration(), basic_compiler_type, scoped);
+      CompilerType enum_type = ast.CreateEnumerationType(
+          "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(),
+          Declaration(), basic_compiler_type, scoped);
+
       CompilerType t = ast.GetEnumerationIntegerType(enum_type);
       // Check that the type we put in at the start is found again.
       EXPECT_EQ(basic_compiler_type.GetTypeName(), t.GetTypeName());
@@ -267,14 +269,39 @@ TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) {
   }
 }
 
+TEST_F(TestTypeSystemClang, TestOwningModule) {
+  TypeSystemClang ast("module_ast", HostInfo::GetTargetTriple());
+  CompilerType basic_compiler_type = ast.GetBasicType(BasicType::eBasicTypeInt);
+  CompilerType enum_type = ast.CreateEnumerationType(
+      "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(100),
+      Declaration(), basic_compiler_type, false);
+  auto *ed = TypeSystemClang::GetAsEnumDecl(enum_type);
+  EXPECT_FALSE(!ed);
+  EXPECT_EQ(ed->getOwningModuleID(), 100u);
+
+  CompilerType record_type = ast.CreateRecordType(
+      nullptr, OptionalClangModuleID(200), lldb::eAccessPublic, "FooRecord",
+      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
+  auto *rd = TypeSystemClang::GetAsRecordDecl(record_type);
+  EXPECT_FALSE(!rd);
+  EXPECT_EQ(rd->getOwningModuleID(), 200u);
+
+  CompilerType class_type =
+      ast.CreateObjCClass("objc_class", ast.GetTranslationUnitDecl(),
+                          OptionalClangModuleID(300), false, false);
+  auto *cd = TypeSystemClang::GetAsObjCInterfaceDecl(class_type);
+  EXPECT_FALSE(!cd);
+  EXPECT_EQ(cd->getOwningModuleID(), 300u);
+}
+
 TEST_F(TestTypeSystemClang, TestIsClangType) {
   clang::ASTContext &context = m_ast->getASTContext();
   lldb::opaque_compiler_type_t bool_ctype =
       TypeSystemClang::GetOpaqueCompilerType(&context, lldb::eBasicTypeBool);
   CompilerType bool_type(m_ast.get(), bool_ctype);
   CompilerType record_type = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
-      lldb::eLanguageTypeC_plus_plus, nullptr);
+      nullptr, OptionalClangModuleID(100), lldb::eAccessPublic, "FooRecord",
+      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
   // Clang builtin type and record type should pass
   EXPECT_TRUE(ClangUtil::IsClangType(bool_type));
   EXPECT_TRUE(ClangUtil::IsClangType(record_type));
@@ -285,8 +312,8 @@ TEST_F(TestTypeSystemClang, TestIsClangType) {
 
 TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {
   CompilerType record_type = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
-      lldb::eLanguageTypeC_plus_plus, nullptr);
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord",
+      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
   QualType qt;
 
   qt = ClangUtil::GetQualType(record_type);
@@ -357,8 +384,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
 
   // Test that a record with no fields returns false
   CompilerType empty_base = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct,
-      lldb::eLanguageTypeC_plus_plus, nullptr);
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase",
+      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
   TypeSystemClang::StartTagDeclarationDefinition(empty_base);
   TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);
 
@@ -368,8 +395,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
 
   // Test that a record with direct fields returns true
   CompilerType non_empty_base = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "NonEmptyBase", clang::TTK_Struct,
-      lldb::eLanguageTypeC_plus_plus, nullptr);
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "NonEmptyBase",
+      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
   TypeSystemClang::StartTagDeclarationDefinition(non_empty_base);
   FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType(
       non_empty_base, "MyField", int_type, eAccessPublic, 0);
@@ -384,8 +411,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
 
   // Test that a record with no direct fields, but fields in a base returns true
   CompilerType empty_derived = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "EmptyDerived", clang::TTK_Struct,
-      lldb::eLanguageTypeC_plus_plus, nullptr);
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived",
+      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
   TypeSystemClang::StartTagDeclarationDefinition(empty_derived);
   std::unique_ptr<clang::CXXBaseSpecifier> non_empty_base_spec =
       m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
@@ -407,8 +434,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
   // Test that a record with no direct fields, but fields in a virtual base
   // returns true
   CompilerType empty_derived2 = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "EmptyDerived2", clang::TTK_Struct,
-      lldb::eLanguageTypeC_plus_plus, nullptr);
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived2",
+      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
   TypeSystemClang::StartTagDeclarationDefinition(empty_derived2);
   std::unique_ptr<CXXBaseSpecifier> non_empty_vbase_spec =
       m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
@@ -439,13 +466,15 @@ TEST_F(TestTypeSystemClang, TemplateArguments) {
 
   // template<typename T, int I> struct foo;
   ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
-      m_ast->GetTranslationUnitDecl(), eAccessPublic, "foo", TTK_Struct, infos);
+      m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,
+      "foo", TTK_Struct, infos);
   ASSERT_NE(decl, nullptr);
 
   // foo<int, 47>
   ClassTemplateSpecializationDecl *spec_decl =
       m_ast->CreateClassTemplateSpecializationDecl(
-          m_ast->GetTranslationUnitDecl(), decl, TTK_Struct, infos);
+          m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl,
+          TTK_Struct, infos);
   ASSERT_NE(spec_decl, nullptr);
   CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl);
   ASSERT_TRUE(type);
@@ -454,7 +483,8 @@ TEST_F(TestTypeSystemClang, TemplateArguments) {
 
   // typedef foo<int, 47> foo_def;
   CompilerType typedef_type = m_ast->CreateTypedefType(
-      type, "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()));
+      type, "foo_def",
+      m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0);
 
   CompilerType auto_type(
       m_ast.get(),
@@ -528,13 +558,14 @@ TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) {
   // Prepare the declarations/types we need for the template.
   CompilerType clang_type =
       m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
-  FunctionDecl *func =
-      m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false);
+  FunctionDecl *func = m_ast->CreateFunctionDeclaration(
+      TU, OptionalClangModuleID(), "foo", clang_type, 0, false);
   TypeSystemClang::TemplateParameterInfos empty_params;
 
   // Create the actual function template.
   clang::FunctionTemplateDecl *func_template =
-      m_ast->CreateFunctionTemplateDecl(TU, func, "foo", empty_params);
+      m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func,
+                                        "foo", empty_params);
 
   EXPECT_EQ(TU, func_template->getDeclContext());
   EXPECT_EQ("foo", func_template->getName());
@@ -558,13 +589,14 @@ TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) {
   // We create the FunctionDecl for the template in the TU DeclContext because:
   // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can).
   // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine.
-  FunctionDecl *func =
-      m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false);
+  FunctionDecl *func = m_ast->CreateFunctionDeclaration(
+      TU, OptionalClangModuleID(), "foo", clang_type, 0, false);
   TypeSystemClang::TemplateParameterInfos empty_params;
 
   // Create the actual function template.
   clang::FunctionTemplateDecl *func_template =
-      m_ast->CreateFunctionTemplateDecl(record, func, "foo", empty_params);
+      m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func,
+                                        "foo", empty_params);
 
   EXPECT_EQ(record, func_template->getDeclContext());
   EXPECT_EQ("foo", func_template->getName());

diff  --git a/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h b/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
index c6954af12679..6524f093ab95 100644
--- a/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
+++ b/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
@@ -28,6 +28,7 @@ inline std::unique_ptr<TypeSystemClang> createAST() {
 
 inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) {
   return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(),
+                              OptionalClangModuleID(),
                               lldb::AccessType::eAccessPublic, name, 0,
                               lldb::LanguageType::eLanguageTypeC);
 }


        


More information about the lldb-commits mailing list