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

Adrian Prantl via lldb-commits lldb-commits at lists.llvm.org
Wed Apr 1 17:46:33 PDT 2020


Author: Adrian Prantl
Date: 2020-04-01T17:46:02-07:00
New Revision: 4354dfbdf5c8510a7ddff10ae67a28e16cf7cc79

URL: https://github.com/llvm/llvm-project/commit/4354dfbdf5c8510a7ddff10ae67a28e16cf7cc79
DIFF: https://github.com/llvm/llvm-project/commit/4354dfbdf5c8510a7ddff10ae67a28e16cf7cc79.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
sets 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.

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..e552f4389a1f 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,20 @@ 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 +1027,19 @@ 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..5cab0cac6ecc 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,27 @@ 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..87e5e7ab122b 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -123,8 +123,9 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
   if (is_templated)
     return clang::QualType(); // This is where we bail out.  Sorry!
 
-  CompilerType union_type(ast_ctx.CreateRecordType(
-      nullptr, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC));
+  CompilerType union_type(ast_ctx.CreateRecordType(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..01336e914438 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,13 @@ 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 +1599,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 +1616,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 +1630,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 +1644,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 +3088,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);
 
@@ -3153,8 +3159,8 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
                       Status error;
                       lldb::VariableSP var_sp;
                       auto valobj_sp = frame->GetValueForVariableExpressionPath(
-                          var_die.GetName(), eNoDynamicValues, 0, var_sp,
-                          error);
+                          var_die.GetName(), eNoDynamicValues, 0,
+                          var_sp, error);
                       if (valobj_sp) {
                         num_elements = valobj_sp->GetValueAsUnsigned(0);
                         break;
@@ -3282,7 +3288,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 +3305,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 +3325,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 +3384,31 @@ 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,7 @@ 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 +3509,7 @@ 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, OptionalClangModuleID(), 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..ff271178a7ff 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -78,6 +78,8 @@ 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 +89,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 +143,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..6c497bf72cd6 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,7 @@ 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 +815,7 @@ 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 +832,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 +880,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 +1013,7 @@ 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,7 +1081,7 @@ 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,
+        &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);
 
@@ -1102,8 +1103,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..5e2ca60db0b1 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,8 +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,
-                                             builtin_type, isScoped);
+      ast_enum = m_ast.CreateEnumerationType(
+          name.c_str(), decl_context, OptionalClangModuleID(), decl, builtin_type, isScoped);
 
       auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);
       assert(enum_decl);
@@ -550,7 +550,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 +901,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 +927,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,7 +941,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
             continue;
 
           clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
-              decl, nullptr, arg_type->GetForwardCompilerType(),
+              decl, OptionalClangModuleID(), nullptr, arg_type->GetForwardCompilerType(),
               clang::SC_None, true);
           if (param)
             params.push_back(param);
@@ -1057,7 +1057,7 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol(
                                                    : namespace_name.data();
       clang::NamespaceDecl *namespace_decl =
           m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str,
-                                              curr_context);
+                                              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 22f401fa4e95..712a2d21c2fd 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,7 +1216,53 @@ CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) {
 
 #pragma mark Structure, Unions, Classes
 
-CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx,
+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);
+}
+
+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,
@@ -1201,7 +1277,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 +1293,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 +1405,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 +1420,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 +1447,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 +1477,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 +1495,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 +1535,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 +1559,7 @@ TypeSystemClang::CreateClassTemplateSpecializationDecl(
   ast.getTypeDeclType(class_template_specialization_decl, nullptr);
   class_template_specialization_decl->setDeclName(
       class_template_decl->getDeclName());
+  SetOwningModule(class_template_specialization_decl, owning_module);
 
   class_template_specialization_decl->setSpecializationKind(
       TSK_ExplicitSpecialization);
@@ -1595,13 +1679,14 @@ bool TypeSystemClang::RecordHasFields(const RecordDecl *record_decl) {
 #pragma mark Objective-C Classes
 
 CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name,
-                                              DeclContext *decl_ctx,
+                                              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 +1694,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,17 +1732,19 @@ 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) {
     IdentifierInfo &identifier_info = ast.Idents.get(name);
     DeclarationName decl_name(&identifier_info);
-    clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
+    clang::DeclContext::lookup_result result =
+        decl_ctx->lookup(decl_name);
     for (NamedDecl *decl : result) {
       namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
       if (namespace_decl)
@@ -1699,17 +1787,22 @@ 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 +1826,7 @@ 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 +1836,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 +1844,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 +1863,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 +1872,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 +1984,11 @@ TypeSystemClang::GetDeclarationName(const char *name,
 }
 
 FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
-    DeclContext *decl_ctx, const char *name,
+    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 +2005,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,7 +2054,7 @@ TypeSystemClang::CreateFunctionType(const CompilerType &result_type,
 }
 
 ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
-    clang::DeclContext *decl_ctx, const char *name,
+    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);
@@ -1963,6 +2063,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 +2125,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 +2152,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 +2169,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 +4356,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 +4367,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 +4376,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 +4465,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()) {
@@ -6922,6 +7024,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
@@ -6963,6 +7066,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);
@@ -7024,6 +7128,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();
 
@@ -7054,7 +7159,8 @@ 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();
 
           indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers(
@@ -7120,6 +7226,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;
 
@@ -7255,6 +7362,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);
@@ -7429,6 +7537,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;
@@ -7520,6 +7629,7 @@ bool TypeSystemClang::AddObjCClassProperty(
     getter->setDefined(isDefined);
     getter->setDeclImplementation(impControl);
     getter->setRelatedResultType(HasRelatedResultType);
+    SetMemberOwningModule(getter, class_interface_decl);
 
     if (getter) {
       if (metadata)
@@ -7561,6 +7671,7 @@ bool TypeSystemClang::AddObjCClassProperty(
     setter->setDefined(isDefined);
     setter->setDeclImplementation(impControl);
     setter->setRelatedResultType(HasRelatedResultType);
+    SetMemberOwningModule(setter, class_interface_decl);
 
     if (setter) {
       if (metadata)
@@ -7689,6 +7800,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;
@@ -7919,6 +8031,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;
@@ -8813,14 +8926,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..7f44a29ecc4d 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,13 @@ 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 +347,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);
 
@@ -327,7 +356,7 @@ class TypeSystemClang : public TypeSystem {
       const TemplateParameterInfos &infos);
 
   clang::ClassTemplateDecl *
-  CreateClassTemplateDecl(clang::DeclContext *decl_ctx,
+  CreateClassTemplateDecl(clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
                           lldb::AccessType access_type, const char *class_name,
                           int kind, const TemplateParameterInfos &infos);
 
@@ -335,7 +364,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,7 +384,8 @@ class TypeSystemClang : public TypeSystem {
   static bool RecordHasFields(const clang::RecordDecl *record_decl);
 
   CompilerType CreateObjCClass(llvm::StringRef name,
-                               clang::DeclContext *decl_ctx, bool isForwardDecl,
+                               clang::DeclContext *decl_ctx,
+                               OptionalClangModuleID owning_module, bool isForwardDecl,
                                bool isInternal,
                                ClangASTMetadata *metadata = nullptr);
 
@@ -373,14 +403,13 @@ class TypeSystemClang : public TypeSystem {
 
   clang::NamespaceDecl *
   GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx,
-                                bool is_inline = false);
+                                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);
+  clang::FunctionDecl *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,
@@ -395,6 +424,7 @@ class TypeSystemClang : public TypeSystem {
   }
 
   clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx,
+                                                 OptionalClangModuleID owning_module,
                                                  const char *name,
                                                  const CompilerType &param_type,
                                                  int storage,
@@ -413,6 +443,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 +510,9 @@ 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 +675,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 +732,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 +992,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 +1032,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 +1056,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..76618d2687f8
--- /dev/null
+++ b/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;
+
+ 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..c4f943d24f9d
--- /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>;
+}

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..54e7e55ee60a
--- /dev/null
+++ b/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. 
+
+ 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<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

diff  --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
index a3345e815ee9..f0e514b6f673 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,38 @@ 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,7 +311,7 @@ TEST_F(TestTypeSystemClang, TestIsClangType) {
 
 TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {
   CompilerType record_type = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
       lldb::eLanguageTypeC_plus_plus, nullptr);
   QualType qt;
 
@@ -357,7 +383,7 @@ 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,
+      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct,
       lldb::eLanguageTypeC_plus_plus, nullptr);
   TypeSystemClang::StartTagDeclarationDefinition(empty_base);
   TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);
@@ -368,8 +394,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 +410,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 +433,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 +465,14 @@ 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 +481,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 +556,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 +587,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..1876121b1ce4 100644
--- a/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
+++ b/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
@@ -28,8 +28,8 @@ inline std::unique_ptr<TypeSystemClang> createAST() {
 
 inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) {
   return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(),
-                              lldb::AccessType::eAccessPublic, name, 0,
-                              lldb::LanguageType::eLanguageTypeC);
+                              OptionalClangModuleID(), lldb::AccessType::eAccessPublic, name,
+                              0, lldb::LanguageType::eLanguageTypeC);
 }
 
 /// Create a record with the given name and a field with the given type


        


More information about the lldb-commits mailing list