aprantl updated this revision to Diff 247992.
aprantl retitled this revision from "RFC: Preserve the owning module 
information from DWARF in the synthesized AST" to "Preserve the owning module 
information from DWARF in the synthesized AST".
aprantl added a comment.

Now with a more comprehensive testcase and support for deferred completion via 
DWARFASTParserClang::ParseTypeFromClangModule().

This is good to review in earnest now!


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75488/new/

https://reviews.llvm.org/D75488

Files:
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/ExternalASTSource.h
  clang/lib/AST/ExternalASTSource.cpp
  clang/lib/Serialization/ASTReader.cpp
  lldb/include/lldb/Symbol/CompilerType.h
  lldb/include/lldb/Symbol/Type.h
  lldb/include/lldb/Symbol/TypeSystem.h
  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/LanguageRuntime/ObjC/ObjCLanguageRuntime.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/Inputs/ModuleOwnership/A.h
  lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/B.h
  lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/module.modulemap
  lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
  lldb/test/Shell/SymbolFile/DWARF/module-ownership.mm
  lldb/unittests/Symbol/TestTypeSystemClang.cpp
  lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h

Index: lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
===================================================================
--- lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
+++ lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
@@ -27,7 +27,7 @@
 }
 
 inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) {
-  return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(),
+  return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(), 0,
                               lldb::AccessType::eAccessPublic, name, 0,
                               lldb::LanguageType::eLanguageTypeC);
 }
Index: lldb/unittests/Symbol/TestTypeSystemClang.cpp
===================================================================
--- lldb/unittests/Symbol/TestTypeSystemClang.cpp
+++ lldb/unittests/Symbol/TestTypeSystemClang.cpp
@@ -258,7 +258,7 @@
       EXPECT_TRUE(basic_compiler_type.IsValid());
 
       CompilerType enum_type =
-          ast.CreateEnumerationType("my_enum", ast.GetTranslationUnitDecl(),
+          ast.CreateEnumerationType("my_enum", ast.GetTranslationUnitDecl(), 0,
                                     Declaration(), basic_compiler_type, scoped);
       CompilerType t = ast.GetEnumerationIntegerType(enum_type);
       // Check that the type we put in at the start is found again.
@@ -273,7 +273,7 @@
       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,
+      nullptr, 0, 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));
@@ -285,7 +285,7 @@
 
 TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {
   CompilerType record_type = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
+      nullptr, 0, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
       lldb::eLanguageTypeC_plus_plus, nullptr);
   QualType qt;
 
@@ -357,7 +357,7 @@
 
   // Test that a record with no fields returns false
   CompilerType empty_base = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct,
+      nullptr, 0, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct,
       lldb::eLanguageTypeC_plus_plus, nullptr);
   TypeSystemClang::StartTagDeclarationDefinition(empty_base);
   TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);
@@ -368,7 +368,7 @@
 
   // Test that a record with direct fields returns true
   CompilerType non_empty_base = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "NonEmptyBase", clang::TTK_Struct,
+      nullptr, 0, 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(
@@ -384,7 +384,7 @@
 
   // 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,
+      nullptr, 0, lldb::eAccessPublic, "EmptyDerived", clang::TTK_Struct,
       lldb::eLanguageTypeC_plus_plus, nullptr);
   TypeSystemClang::StartTagDeclarationDefinition(empty_derived);
   std::unique_ptr<clang::CXXBaseSpecifier> non_empty_base_spec =
@@ -407,7 +407,7 @@
   // 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,
+      nullptr, 0, lldb::eAccessPublic, "EmptyDerived2", clang::TTK_Struct,
       lldb::eLanguageTypeC_plus_plus, nullptr);
   TypeSystemClang::StartTagDeclarationDefinition(empty_derived2);
   std::unique_ptr<CXXBaseSpecifier> non_empty_vbase_spec =
@@ -439,13 +439,14 @@
 
   // template<typename T, int I> struct foo;
   ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
-      m_ast->GetTranslationUnitDecl(), eAccessPublic, "foo", TTK_Struct, infos);
+      m_ast->GetTranslationUnitDecl(), 0, 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(), 0, decl, TTK_Struct, infos);
   ASSERT_NE(spec_decl, nullptr);
   CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl);
   ASSERT_TRUE(type);
@@ -454,7 +455,8 @@
 
   // 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(),
@@ -529,12 +531,12 @@
   CompilerType clang_type =
       m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
   FunctionDecl *func =
-      m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false);
+      m_ast->CreateFunctionDeclaration(TU, 0, "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, 0, func, "foo", empty_params);
 
   EXPECT_EQ(TU, func_template->getDeclContext());
   EXPECT_EQ("foo", func_template->getName());
@@ -559,12 +561,12 @@
   // 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);
+    m_ast->CreateFunctionDeclaration(TU, 0, "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, 0, func, "foo", empty_params);
 
   EXPECT_EQ(record, func_template->getDeclContext());
   EXPECT_EQ("foo", func_template->getName());
Index: lldb/test/Shell/SymbolFile/DWARF/module-ownership.mm
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/module-ownership.mm
@@ -0,0 +1,17 @@
+// RUN: %clang_host -g -gmodules -fmodules -fmodules-cache-path=%t.cache \
+// RUN:    -c -o %t.o %s -I%S/Inputs
+// RUN: lldb-test symbols -dump-clang-ast %t.o | FileCheck %s
+// Verify that the owning module information from DWARF is preserved in the AST. 
+
+@import A;
+
+// CHECK: CXXRecordDecl {{.*}} imported in A struct TopLevelStruct
+TopLevelStruct s1;
+// CHECK: CXXRecordDecl {{.*}} imported in A struct
+Struct s2;
+// CHECK: CXXRecordDecl {{.*}} imported in A.B struct
+StructB s3;
+// CHECK: EnumDecl {{.*}} imported in A {{.*}} Enum_e
+Enum e1;
+// CHECK: ObjCInterfaceDecl {{.*}} imported in A {{.*}} SomeClass
+SomeClass *obj1;
Index: lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
+++ lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg
@@ -1 +1 @@
-config.suffixes = ['.cpp', '.m', '.s', '.test', '.ll']
+config.suffixes = ['.cpp', '.m', '.mm', '.s', '.test', '.ll']
Index: lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/module.modulemap
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/module.modulemap
@@ -0,0 +1,6 @@
+module A {
+  header "A.h"
+  module B {
+    header "B.h"
+  }
+}
Index: lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/B.h
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/B.h
@@ -0,0 +1,3 @@
+typedef struct {
+  int b;
+} StructB;
Index: lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/A.h
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/Inputs/ModuleOwnership/A.h
@@ -0,0 +1,17 @@
+#include "B.h"                                                 // -*- ObjC -*-
+
+
+struct TopLevelStruct {
+  int a;
+};
+
+typedef struct Struct_s {
+  int a;
+} Struct;
+
+typedef enum Enum_e {
+  a = 0
+} Enum;
+
+@interface SomeClass {}
+@end
Index: lldb/source/Symbol/TypeSystem.cpp
===================================================================
--- lldb/source/Symbol/TypeSystem.cpp
+++ lldb/source/Symbol/TypeSystem.cpp
@@ -109,7 +109,8 @@
 
 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();
 }
 
Index: lldb/source/Symbol/Type.cpp
===================================================================
--- lldb/source/Symbol/Type.cpp
+++ lldb/source/Symbol/Type.cpp
@@ -148,10 +148,8 @@
       m_symbol_file(symbol_file), m_context(context), m_encoding_type(nullptr),
       m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type),
       m_decl(decl), m_compiler_type(compiler_type),
-      m_compiler_type_resolve_state(
-          compiler_type ? compiler_type_resolve_state
-                        : ResolveState::Unresolved),
-      m_is_complete_objc_class(false) {
+      m_compiler_type_resolve_state(compiler_type ? compiler_type_resolve_state
+                                                  : ResolveState::Unresolved) {
   if (byte_size) {
     m_byte_size = *byte_size;
     m_byte_size_has_value = true;
@@ -506,7 +504,7 @@
       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;
 
@@ -564,7 +562,7 @@
         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:
Index: lldb/source/Symbol/CompilerType.cpp
===================================================================
--- lldb/source/Symbol/CompilerType.cpp
+++ lldb/source/Symbol/CompilerType.cpp
@@ -439,11 +439,11 @@
     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();
 }
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -33,6 +33,7 @@
 #include "lldb/Symbol/TypeSystem.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Flags.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Logging.h"
 #include "lldb/lldb-enumerations.h"
@@ -40,12 +41,41 @@
 class DWARFASTParserClang;
 class PDBASTParser;
 
+namespace clang {
+  class HeaderSearch;
+  class ModuleMap;
+}
+
 namespace lldb_private {
 
 class ClangASTMetadata;
 class ClangASTSource;
 class Declaration;
 
+/// The implementation of lldb::Type's m_payload field for TypeSystemClang.
+class TypePayloadClang {
+  uint32_t &m_payload;
+public:
+  TypePayloadClang(uint32_t &opaque_payload) : m_payload(opaque_payload) {}
+  /// Clang-specific functions. As more of these get added we may want
+  /// to factor this into typesystem-specific subclasses.
+  /// \{
+  static constexpr unsigned ObjCClassBit = 1 << 31;
+  bool IsCompleteObjCClass() { return Flags(m_payload).Test(ObjCClassBit); }
+  void SetIsCompleteObjCClass(bool is_complete_objc_class) {
+    m_payload = is_complete_objc_class ? Flags(m_payload).Set(ObjCClassBit)
+                                       : Flags(m_payload).Clear(ObjCClassBit);
+  }
+  unsigned GetOwningModuleID() { return Flags(m_payload).Clear(ObjCClassBit); }
+  void SetOwningModuleID(unsigned id) {
+    assert(id < ObjCClassBit);
+    bool is_complete = IsCompleteObjCClass();
+    m_payload = id;
+    SetIsCompleteObjCClass(is_complete);
+  }
+  /// \}
+};
+  
 /// A TypeSystem implementation based on Clang.
 ///
 /// This class uses a single clang::ASTContext as the backend for storing
@@ -268,7 +298,13 @@
   static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl,
                                     bool omit_empty_base_classes);
 
+  /// Synthesize a clang::Module and return its ID or 0.
+  unsigned GetOrCreateClangModule(llvm::StringRef name, unsigned parent,
+                                  bool is_framework = false,
+                                  bool is_explicit = false);
+
   CompilerType CreateRecordType(clang::DeclContext *decl_ctx,
+                                unsigned owning_module,
                                 lldb::AccessType access_type,
                                 llvm::StringRef name, int kind,
                                 lldb::LanguageType language,
@@ -294,6 +330,7 @@
 
   clang::FunctionTemplateDecl *
   CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx,
+                             unsigned owning_module,
                              clang::FunctionDecl *func_decl, const char *name,
                              const TemplateParameterInfos &infos);
 
@@ -302,7 +339,7 @@
       const TemplateParameterInfos &infos);
 
   clang::ClassTemplateDecl *
-  CreateClassTemplateDecl(clang::DeclContext *decl_ctx,
+  CreateClassTemplateDecl(clang::DeclContext *decl_ctx, unsigned owning_module,
                           lldb::AccessType access_type, const char *class_name,
                           int kind, const TemplateParameterInfos &infos);
 
@@ -310,7 +347,7 @@
   CreateTemplateTemplateParmDecl(const char *template_name);
 
   clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl(
-      clang::DeclContext *decl_ctx,
+      clang::DeclContext *decl_ctx, unsigned owning_module,
       clang::ClassTemplateDecl *class_template_decl, int kind,
       const TemplateParameterInfos &infos);
 
@@ -330,7 +367,8 @@
   static bool RecordHasFields(const clang::RecordDecl *record_decl);
 
   CompilerType CreateObjCClass(llvm::StringRef name,
-                               clang::DeclContext *decl_ctx, bool isForwardDecl,
+                               clang::DeclContext *decl_ctx,
+                               unsigned owning_module, bool isForwardDecl,
                                bool isInternal,
                                ClangASTMetadata *metadata = nullptr);
 
@@ -348,14 +386,13 @@
 
   clang::NamespaceDecl *
   GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx,
-                                bool is_inline = false);
+                                unsigned 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, unsigned 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,
@@ -370,6 +407,7 @@
   }
 
   clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx,
+                                                 unsigned owning_module,
                                                  const char *name,
                                                  const CompilerType &param_type,
                                                  int storage,
@@ -388,6 +426,7 @@
   // Enumeration Types
   CompilerType CreateEnumerationType(const char *name,
                                      clang::DeclContext *decl_ctx,
+                                     unsigned owning_module,
                                      const Declaration &decl,
                                      const CompilerType &integer_qual_type,
                                      bool is_scoped);
@@ -454,6 +493,9 @@
   /// TypeSystemClang.
   CompilerDeclContext CreateDeclContext(clang::DeclContext *ctx);
 
+  /// Set the owning module for \p decl.
+  static void SetOwningModule(clang::Decl *decl, unsigned owning_module);
+
   std::vector<CompilerDecl>
   DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
                             const bool ignore_using_decls) override;
@@ -612,11 +654,13 @@
 
   // 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;
@@ -667,7 +711,8 @@
 
   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;
@@ -926,20 +971,24 @@
   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, unsigned 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,
+                                           unsigned owning_module);
 
   clang::UsingDirectiveDecl *
   CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx,
+                                  unsigned owning_module,
                                   clang::NamespaceDecl *ns_decl);
 
   clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
+                                           unsigned owning_module,
                                            clang::NamedDecl *target);
 
   clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context,
+                                            unsigned owning_module,
                                             const char *name,
                                             clang::QualType type);
 
@@ -962,6 +1011,13 @@
   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);
@@ -979,6 +1035,8 @@
   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;
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ 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"
@@ -501,6 +504,10 @@
   //
   // 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,
@@ -1182,7 +1189,53 @@
 
 #pragma mark Structure, Unions, Classes
 
-CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx,
+unsigned TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name,
+                                                 unsigned 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 0;
+
+  // 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);
+  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);
+
+  module->Name = name.str();
+  return ast_source->registerModule(module);
+}
+
+void TypeSystemClang::SetOwningModule(clang::Decl *decl, unsigned owning_module) {
+  if (!decl || !owning_module)
+    return;
+
+  decl->setFromASTFile();
+  decl->setOwningModuleID(owning_module);
+  decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
+}
+
+CompilerType TypeSystemClang::CreateRecordType(clang::DeclContext *decl_ctx,
+                                               unsigned owning_module,
                                                AccessType access_type,
                                                llvm::StringRef name, int kind,
                                                LanguageType language,
@@ -1197,7 +1250,8 @@
       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
@@ -1207,10 +1261,10 @@
   // complete definition just in case.
 
   bool has_name = !name.empty();
-
   CXXRecordDecl *decl = CXXRecordDecl::Create(
-      ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), SourceLocation(),
-      has_name ? &ast.Idents.get(name) : nullptr);
+      ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
+      SourceLocation(), has_name ? &ast.Idents.get(name) : nullptr);
+  SetOwningModule(decl, owning_module);
 
   if (!has_name) {
     // In C++ a lambda is also represented as an unnamed class. This is
@@ -1322,18 +1376,19 @@
 }
 
 clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
-    clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl,
-    const char *name, const TemplateParameterInfos &template_param_infos) {
+    clang::DeclContext *decl_ctx, unsigned 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 = FunctionTemplateDecl::Create(
       ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(),
       template_param_list, func_decl);
+  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) {
@@ -1360,8 +1415,9 @@
 }
 
 ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
-    DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name,
-    int kind, const TemplateParameterInfos &template_param_infos) {
+    DeclContext *decl_ctx, unsigned 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;
@@ -1386,9 +1442,10 @@
 
   CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create(
       ast, (TagDecl::TagKind)kind,
-      decl_ctx, // What decl context do we use here? TU? The actual decl
-                // context?
+      decl_ctx, // What decl context do we use here? TU? The actual
+                            // decl context?
       SourceLocation(), SourceLocation(), &identifier_info);
+  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) {
@@ -1402,10 +1459,11 @@
 
   class_template_decl = ClassTemplateDecl::Create(
       ast,
-      decl_ctx, // What decl context do we use here? TU? The actual decl
-                // context?
+      decl_ctx, // What decl context do we use here? TU? The actual
+                            // decl context?
       SourceLocation(), decl_name, template_param_list, template_cxx_decl);
   template_cxx_decl->setDescribedClassTemplate(class_template_decl);
+  SetOwningModule(class_template_decl, owning_module);
 
   if (class_template_decl) {
     if (access_type != eAccessNone)
@@ -1448,7 +1506,8 @@
 
 ClassTemplateSpecializationDecl *
 TypeSystemClang::CreateClassTemplateSpecializationDecl(
-    DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
+    DeclContext *decl_ctx, unsigned owning_module,
+    ClassTemplateDecl *class_template_decl, int kind,
     const TemplateParameterInfos &template_param_infos) {
   ASTContext &ast = getASTContext();
   llvm::SmallVector<clang::TemplateArgument, 2> args(
@@ -1464,6 +1523,7 @@
       ClassTemplateSpecializationDecl::Create(
           ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
           SourceLocation(), class_template_decl, args, nullptr);
+  SetOwningModule(class_template_decl, owning_module);
 
   class_template_specialization_decl->setSpecializationKind(
       TSK_ExplicitSpecialization);
@@ -1583,13 +1643,14 @@
 #pragma mark Objective-C Classes
 
 CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name,
-                                              DeclContext *decl_ctx,
+                                              clang::DeclContext *decl_ctx,
+                                              unsigned 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::Create(
@@ -1597,6 +1658,7 @@
       SourceLocation(),
       /*isForwardDecl,*/
       isInternal);
+  SetOwningModule(decl, owning_module);
 
   if (decl && metadata)
     SetMetadata(decl, *metadata);
@@ -1634,17 +1696,19 @@
 #pragma mark Namespace Declarations
 
 NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration(
-    const char *name, DeclContext *decl_ctx, bool is_inline) {
+    const char *name, clang::DeclContext *decl_ctx, unsigned 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)
@@ -1687,16 +1751,21 @@
       }
     }
   }
+  // 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) {
-  if (ctx != nullptr) {
-    clang::BlockDecl *decl =
-        clang::BlockDecl::Create(getASTContext(), ctx, clang::SourceLocation());
+TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx,
+                                        unsigned owning_module) {
+  if (ctx) {
+    clang::BlockDecl *decl = clang::BlockDecl::Create(
+        getASTContext(), ctx, clang::SourceLocation());
     ctx->addDecl(decl);
+    SetOwningModule(decl, owning_module);
     return decl;
   }
   return nullptr;
@@ -1720,30 +1789,37 @@
 }
 
 clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration(
-    clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) {
-  if (decl_ctx != nullptr && ns_decl != nullptr) {
+    clang::DeclContext *decl_ctx, unsigned owning_module,
+    clang::NamespaceDecl *ns_decl) {
+  if (decl_ctx && ns_decl) {
     auto *translation_unit = getASTContext().getTranslationUnitDecl();
-    clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
-        getASTContext(), decl_ctx, clang::SourceLocation(),
-        clang::SourceLocation(), clang::NestedNameSpecifierLoc(),
-        clang::SourceLocation(), ns_decl,
-        FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit));
-    decl_ctx->addDecl(using_decl);
-    return using_decl;
+      clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
+          getASTContext(), decl_ctx, clang::SourceLocation(),
+          clang::SourceLocation(), clang::NestedNameSpecifierLoc(),
+          clang::SourceLocation(), ns_decl,
+          FindLCABetweenDecls(decl_ctx, ns_decl,
+                              translation_unit));
+      decl_ctx->addDecl(using_decl);
+      SetOwningModule(using_decl, owning_module);
+
+      return using_decl;
   }
   return nullptr;
 }
 
 clang::UsingDecl *
 TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
+                                        unsigned 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;
@@ -1752,13 +1828,16 @@
 }
 
 clang::VarDecl *TypeSystemClang::CreateVariableDeclaration(
-    clang::DeclContext *decl_context, const char *name, clang::QualType type) {
-  if (decl_context != nullptr) {
+    clang::DeclContext *decl_context, unsigned owning_module, const char *name,
+    clang::QualType type) {
+  if (decl_context) {
     clang::VarDecl *var_decl = clang::VarDecl::Create(
         getASTContext(), decl_context, clang::SourceLocation(),
         clang::SourceLocation(),
         name && name[0] ? &getASTContext().Idents.getOwn(name) : nullptr, type,
         nullptr, clang::SC_None);
+    SetOwningModule(var_decl, owning_module);
+
     var_decl->setAccess(clang::AS_public);
     decl_context->addDecl(var_decl);
     return var_decl;
@@ -1870,11 +1949,11 @@
 }
 
 FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
-    DeclContext *decl_ctx, const char *name,
+    clang::DeclContext *decl_ctx, unsigned 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;
@@ -1887,6 +1966,7 @@
       ClangUtil::GetQualType(function_clang_type), nullptr,
       (clang::StorageClass)storage, is_inline, hasWrittenPrototype,
       isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
+  SetOwningModule(func_decl, owning_module);
   if (func_decl)
     decl_ctx->addDecl(func_decl);
 
@@ -1935,7 +2015,7 @@
 }
 
 ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
-    clang::DeclContext *decl_ctx, const char *name,
+    clang::DeclContext *decl_ctx, unsigned owning_module, const char *name,
     const CompilerType &param_type, int storage, bool add_decl) {
   ASTContext &ast = getASTContext();
   auto *decl =
@@ -1943,6 +2023,8 @@
                           name && name[0] ? &ast.Idents.get(name) : nullptr,
                           ClangUtil::GetQualType(param_type), nullptr,
                           (clang::StorageClass)storage, nullptr);
+  SetOwningModule(decl, owning_module);
+ 
   if (add_decl)
     decl_ctx->addDecl(decl);
 
@@ -2004,8 +2086,9 @@
     return type;
   }
 
-  type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(),
-                          clang::TTK_Struct, lldb::eLanguageTypeC);
+  type =
+      CreateRecordType(nullptr, 0, 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,
@@ -2030,25 +2113,23 @@
 
 #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, unsigned 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();
 
   // TODO: ask about these...
   //    const bool IsFixed = false;
-
   EnumDecl *enum_decl = EnumDecl::Create(
       ast, decl_ctx, SourceLocation(), SourceLocation(),
       name && name[0] ? &ast.Idents.get(name) : nullptr, nullptr,
       is_scoped, // IsScoped
       is_scoped, // IsScopedUsingClassTag
       false);    // IsFixed
-
+  SetOwningModule(enum_decl, owning_module);
   if (enum_decl) {
     if (decl_ctx)
       decl_ctx->addDecl(enum_decl);
@@ -4229,7 +4310,7 @@
 
 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());
@@ -4240,14 +4321,15 @@
 
     clang::DeclContext *decl_ctx =
         TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx);
-    if (decl_ctx == nullptr)
+    if (!decl_ctx)
       decl_ctx = ast->getASTContext().getTranslationUnitDecl();
 
     clang::TypedefDecl *decl = clang::TypedefDecl::Create(
-        clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
-        &clang_ast.Idents.get(typedef_name),
+        clang_ast, decl_ctx, clang::SourceLocation(),
+        clang::SourceLocation(), &clang_ast.Idents.get(typedef_name),
         clang_ast.getTrivialTypeSourceInfo(qual_type));
 
+    SetOwningModule(decl, TypePayloadClang(payload).GetOwningModuleID());
     decl->setAccess(clang::AS_public); // TODO respect proper access specifier
 
     decl_ctx->addDecl(decl);
@@ -4336,23 +4418,23 @@
   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::Create(
         clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
         &clang_ast.Idents.get(typedef_name),
         clang_ast.getTrivialTypeSourceInfo(qual_type));
+    SetOwningModule(decl, TypePayloadClang(payload).GetOwningModuleID());
 
     clang::TagDecl *tdecl = nullptr;
     if (!qual_type.isNull()) {
@@ -6875,6 +6957,15 @@
   return nullptr;
 }
 
+static void SetMemberOwningModule(clang::Decl *member,
+                                  const clang::Decl *parent) {
+  if (member && parent)
+    if (unsigned id = parent->getOwningModuleID()) {
+      member->setFromASTFile();
+      member->setOwningModuleID(id);
+    }
+}
+
 clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
     const CompilerType &type, llvm::StringRef name,
     const CompilerType &field_clang_type, AccessType access,
@@ -6912,6 +7003,7 @@
         bit_width,                                // BitWidth
         false,                                    // Mutable
         clang::ICIS_NoInit);                      // HasInit
+    SetMemberOwningModule(field, record_decl);
 
     if (name.empty()) {
       // Determine whether this field corresponds to an anonymous struct or
@@ -6952,6 +7044,7 @@
           nullptr,                                  // TypeSourceInfo *
           ConvertAccessTypeToObjCIvarAccessControl(access), bit_width,
           is_synthesized);
+      SetMemberOwningModule(field, class_interface_decl);
 
       if (field) {
         class_interface_decl->addDecl(field);
@@ -7013,6 +7106,7 @@
                   ast->getASTContext(), record_decl, clang::SourceLocation(),
                   nested_field_decl->getIdentifier(),
                   nested_field_decl->getType(), {chain, 2});
+          SetMemberOwningModule(indirect_field, record_decl);
 
           indirect_field->setImplicit();
 
@@ -7043,7 +7137,8 @@
                   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(
@@ -7113,6 +7208,7 @@
       ClangUtil::GetQualType(var_type), // Variable clang::QualType
       nullptr,                          // TypeSourceInfo *
       clang::SC_Static);                // StorageClass
+  SetMemberOwningModule(var_decl, record_decl);
   if (!var_decl)
     return nullptr;
 
@@ -7238,6 +7334,7 @@
           SC, is_inline, CSK_unspecified, clang::SourceLocation());
     }
   }
+  SetMemberOwningModule(cxx_method_decl, cxx_record_decl);
 
   clang::AccessSpecifier access_specifier =
       TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
@@ -7413,6 +7510,7 @@
       ivar_decl ? ivar_decl->getType()
                 : ClangUtil::GetQualType(property_clang_type),
       prop_type_source);
+  SetMemberOwningModule(property_decl, class_interface_decl);
 
   if (!property_decl)
     return false;
@@ -7498,6 +7596,7 @@
         class_interface_decl, isInstance, isVariadic, isPropertyAccessor,
         isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl,
         HasRelatedResultType);
+    SetMemberOwningModule(getter, class_interface_decl);
 
     if (getter) {
       if (metadata)
@@ -7532,6 +7631,7 @@
         result_type, nullptr, class_interface_decl, isInstance, isVariadic,
         isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared,
         isDefined, impControl, HasRelatedResultType);
+        SetMemberOwningModule(setter, class_interface_decl);
 
     if (setter) {
       if (metadata)
@@ -7657,6 +7757,7 @@
       lldb_ast->GetDeclContextForType(ClangUtil::GetQualType(type)), isInstance,
       isVariadic, isPropertyAccessor, isSynthesizedAccessorStub,
       isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType);
+  SetMemberOwningModule(objc_method_decl, class_interface_decl);
 
   if (objc_method_decl == nullptr)
     return nullptr;
@@ -7884,6 +7985,7 @@
       getASTContext(), enutype->getDecl(), clang::SourceLocation(),
       name ? &getASTContext().Idents.get(name) : nullptr, // Identifier
       clang::QualType(enutype, 0), nullptr, value);
+  SetMemberOwningModule(enumerator_decl, enutype->getDecl());
 
   if (!enumerator_decl)
     return nullptr;
@@ -8778,14 +8880,14 @@
 }
 
 clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl(
-    clang::DeclContext *decl_ctx, lldb::AccessType access_type,
-    const char *parent_name, int tag_decl_kind,
+    clang::DeclContext *decl_ctx, unsigned 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);
   }
Index: lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
===================================================================
--- lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -419,7 +419,7 @@
       CompilerType uint16 =
           ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
       CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(
-          nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s",
+          nullptr, 0, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s",
           clang::TTK_Struct, lldb::eLanguageTypeC);
 
       TypeSystemClang::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
Index: lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -410,7 +410,7 @@
       metadata.SetIsDynamicCXXType(false);
 
       clang_type =
-          m_ast.CreateRecordType(decl_context, access, name, tag_type_kind,
+          m_ast.CreateRecordType(decl_context, 0, access, name, tag_type_kind,
                                  lldb::eLanguageTypeC_plus_plus, &metadata);
       assert(clang_type.IsValid());
 
@@ -497,8 +497,8 @@
       // 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, 0,
+                                             decl, builtin_type, isScoped);
 
       auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);
       assert(enum_decl);
@@ -550,7 +550,7 @@
       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 @@
         return nullptr;
 
       decl = m_ast.CreateVariableDeclaration(
-          decl_context, name.c_str(),
+          decl_context, 0, name.c_str(),
           ClangUtil::GetQualType(type->GetLayoutCompilerType()));
     }
 
@@ -927,7 +927,7 @@
                                     : clang::StorageClass::SC_None;
 
     auto decl = m_ast.CreateFunctionDeclaration(
-        decl_context, name.c_str(), type->GetForwardCompilerType(), storage,
+        decl_context, 0, name.c_str(), type->GetForwardCompilerType(), storage,
         func->hasInlineAttribute());
 
     std::vector<clang::ParmVarDecl *> params;
@@ -941,7 +941,7 @@
             continue;
 
           clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
-              decl, nullptr, arg_type->GetForwardCompilerType(),
+              decl, 0, nullptr, arg_type->GetForwardCompilerType(),
               clang::SC_None, true);
           if (param)
             params.push_back(param);
@@ -1057,7 +1057,7 @@
                                                    : namespace_name.data();
       clang::NamespaceDecl *namespace_decl =
           m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str,
-                                              curr_context);
+                                              curr_context, 0);
 
       m_parent_to_namespaces[curr_context].insert(namespace_decl);
       m_namespaces.insert(namespace_decl);
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -776,8 +776,9 @@
   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, 0, access, uname, ttk,
+                               lldb::eLanguageTypeC_plus_plus, &metadata);
 
   lldbassert(ct.IsValid());
 
@@ -804,7 +805,7 @@
 PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
                                         clang::DeclContext &context) {
   return m_clang.GetUniqueNamespaceDeclaration(
-      IsAnonymousNamespaceName(name) ? nullptr : name, &context);
+      IsAnonymousNamespaceName(name) ? nullptr : name, &context, 0);
 }
 
 clang::BlockDecl *
@@ -814,7 +815,7 @@
 
   clang::DeclContext *scope = GetParentDeclContext(block_id);
 
-  clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope);
+  clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope, 0);
   m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl});
 
   DeclStatus status;
@@ -831,7 +832,7 @@
   clang::QualType qt = GetOrCreateType(var_info.type);
 
   clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration(
-      &scope, var_info.name.str().c_str(), qt);
+      &scope, 0, var_info.name.str().c_str(), qt);
 
   m_uid_to_decl[toOpaqueUid(uid)] = var_decl;
   DeclStatus status;
@@ -879,7 +880,7 @@
   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 @@
   proc_name.consume_front("::");
 
   clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
-      parent, proc_name.str().c_str(), func_ct, storage, false);
+      parent, 0, 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 @@
 
     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, 0, 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 @@
 
   Declaration declaration;
   CompilerType enum_ct = m_clang.CreateEnumerationType(
-      uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type),
-      er.isScoped());
+      uname.c_str(), decl_context, 0, declaration,
+      ToCompilerType(underlying_type), er.isScoped());
 
   TypeSystemClang::StartTagDeclarationDefinition(enum_ct);
   TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -78,6 +78,7 @@
       DIEToDeclContextMap;
   typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
       DeclContextToDIEMap;
+  typedef llvm::DenseMap<const DWARFDebugInfoEntry *, unsigned> DIEToModuleMap;
   typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
       DIEToDeclMap;
   typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
@@ -87,6 +88,7 @@
   DeclToDIEMap m_decl_to_die;
   DIEToDeclContextMap m_die_to_decl_ctx;
   DeclContextToDIEMap m_decl_ctx_to_die;
+  DIEToModuleMap m_die_to_module;
   std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
   /// @}
 
@@ -140,6 +142,7 @@
 
   clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
                                                        DWARFDIE *decl_ctx_die);
+  unsigned GetOwningModuleID(const DWARFDIE &die);
 
   bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
                                   const DWARFDIE &dst_class_die,
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -211,13 +211,18 @@
       die.GetID(), dwarf, pcm_type_sp->GetName(), pcm_type_sp->GetByteSize(),
       nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid,
       &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward));
+  TypePayloadClang(type_sp->GetPayload())
+      .SetOwningModuleID(GetOwningModuleID(die));
 
   dwarf->GetTypeList().Insert(type_sp);
   dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
   clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type);
+  TypeSystemClang::SetOwningModule(tag_decl, GetOwningModuleID(die));
   if (tag_decl)
     LinkDeclContextToDIE(tag_decl, die);
   else {
+    if (auto *oid = TypeSystemClang::GetAsObjCInterfaceDecl(type))
+      TypeSystemClang::SetOwningModule(oid, GetOwningModuleID(die));
     clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
     if (defn_decl_ctx)
       LinkDeclContextToDIE(defn_decl_ctx, die);
@@ -707,6 +712,7 @@
       die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
       dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl,
       clang_type, resolve_state);
+  TypePayloadClang(type_sp->GetPayload()).SetOwningModuleID(GetOwningModuleID(die));
 
   dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
   return type_sp;
@@ -788,7 +794,8 @@
 
     clang_type = m_ast.CreateEnumerationType(
         attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr),
-        attrs.decl, enumerator_clang_type, attrs.is_scoped_enum);
+        GetOwningModuleID(die), attrs.decl, enumerator_clang_type,
+        attrs.is_scoped_enum);
   } else {
     enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type);
   }
@@ -799,6 +806,7 @@
       die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
       dwarf->GetUID(attrs.type.Reference()), Type::eEncodingIsUID, &attrs.decl,
       clang_type, Type::ResolveState::Forward);
+  TypePayloadClang(type_sp->GetPayload()).SetOwningModuleID(GetOwningModuleID(die));
 
   if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
     if (die.HasChildren()) {
@@ -1171,6 +1179,7 @@
         function_decl = m_ast.CreateFunctionDeclaration(
             ignore_containing_context ? m_ast.GetTranslationUnitDecl()
                                       : containing_decl_ctx,
+            GetOwningModuleID(die),
             attrs.name.GetCString(), clang_type, attrs.storage,
             attrs.is_inline);
 
@@ -1180,12 +1189,14 @@
           template_function_decl = m_ast.CreateFunctionDeclaration(
               ignore_containing_context ? m_ast.GetTranslationUnitDecl()
                                         : containing_decl_ctx,
+              GetOwningModuleID(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,
-                  attrs.name.GetCString(), template_param_infos);
+                  containing_decl_ctx, GetOwningModuleID(die),
+                  template_function_decl, attrs.name.GetCString(),
+                  template_param_infos);
           m_ast.CreateFunctionTemplateSpecializationInfo(
               function_decl, func_template_decl, template_param_infos);
         }
@@ -1582,9 +1593,9 @@
       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, GetOwningModuleID(die), attrs.accessibility,
+                attrs.name.GetCString(), tag_decl_kind, template_param_infos);
         if (!class_template_decl) {
           if (log) {
             dwarf->GetObjectFile()->GetModule()->LogMessage(
@@ -1599,8 +1610,8 @@
 
         clang::ClassTemplateSpecializationDecl *class_specialization_decl =
             m_ast.CreateClassTemplateSpecializationDecl(
-                decl_ctx, class_template_decl, tag_decl_kind,
-                template_param_infos);
+                decl_ctx, GetOwningModuleID(die), class_template_decl,
+                tag_decl_kind, template_param_infos);
         clang_type = m_ast.CreateClassTemplateSpecializationType(
             class_specialization_decl);
         clang_type_was_created = true;
@@ -1613,8 +1624,9 @@
     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, GetOwningModuleID(die), attrs.accessibility,
+          attrs.name.GetCString(), tag_decl_kind, attrs.class_language,
+          &metadata, attrs.exports_symbols);
     }
   }
 
@@ -1627,7 +1639,8 @@
                                    Type::eEncodingIsUID, &attrs.decl,
                                    clang_type, Type::ResolveState::Forward);
 
-  type_sp->SetIsCompleteObjCClass(attrs.is_complete_objc_class);
+  TypePayloadClang(type_sp->GetPayload())
+      .SetIsCompleteObjCClass(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
@@ -3061,9 +3074,9 @@
             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, GetOwningModuleID(die), name,
+                    type->GetForwardCompilerType(), storage);
             assert(param_var_decl);
             function_param_decls.push_back(param_var_decl);
 
@@ -3261,7 +3274,7 @@
           TypeSystemClang::DeclContextGetAsDeclContext(
               dwarf->GetDeclContextContainingUID(die.GetID()));
       decl = m_ast.CreateVariableDeclaration(
-          decl_context, name,
+          decl_context, GetOwningModuleID(die), name,
           ClangUtil::GetQualType(type->GetForwardCompilerType()));
     }
     break;
@@ -3278,8 +3291,8 @@
         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, GetOwningModuleID(die), clang_imported_decl);
       }
     }
     break;
@@ -3298,7 +3311,8 @@
         if (clang::NamespaceDecl *ns_decl =
                 TypeSystemClang::DeclContextGetAsNamespaceDecl(
                     imported_decl_ctx))
-          decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
+          decl = m_ast.CreateUsingDirectiveDeclaration(
+              decl_context, GetOwningModuleID(die), ns_decl);
       }
     }
     break;
@@ -3356,6 +3370,31 @@
   return nullptr;
 }
 
+unsigned DWARFASTParserClang::GetOwningModuleID(const DWARFDIE &die) {
+  if (!die.IsValid())
+    return 0;
+
+  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 0;
+
+      unsigned id =
+          m_ast.GetOrCreateClangModule(name, GetOwningModuleID(module_die));
+      m_die_to_module.insert({module_die.GetDIE(), id});
+      return id;
+    }
+  }
+  return 0;
+}
+
 static bool IsSubroutine(const DWARFDIE &die) {
   switch (die.Tag()) {
   case DW_TAG_subprogram:
@@ -3428,7 +3467,7 @@
       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, GetOwningModuleID(die));
 
       if (decl)
         LinkDeclContextToDIE((clang::DeclContext *)decl, die);
Index: lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
===================================================================
--- lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
+++ lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
@@ -129,7 +129,7 @@
 
       if (TypeSystemClang::IsObjCObjectOrInterfaceType(
               type_sp->GetForwardCompilerType())) {
-        if (type_sp->IsCompleteObjCClass()) {
+        if (TypePayloadClang(type_sp->GetPayload()).IsCompleteObjCClass()) {
           m_complete_class_cache[name] = type_sp;
           return type_sp;
         }
Index: lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
===================================================================
--- lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -124,7 +124,7 @@
     return clang::QualType(); // This is where we bail out.  Sorry!
 
   CompilerType union_type(ast_ctx.CreateRecordType(
-      nullptr, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC));
+      nullptr, 0, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC));
   if (union_type) {
     TypeSystemClang::StartTagDeclarationDefinition(union_type);
 
Index: lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
===================================================================
--- lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -76,7 +76,7 @@
 
     if (!compiler_type) {
       compiler_type = target_ast_context->CreateRecordType(
-          nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(),
+          nullptr, 0, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(),
           clang::TTK_Struct, lldb::eLanguageTypeC);
 
       if (compiler_type) {
Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
@@ -17,7 +17,14 @@
 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 +44,17 @@
       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
           &VirtualBaseOffsets) override;
 
+  unsigned registerModule(clang::Module *module);
+  unsigned getIDForModule(clang::Module *module);
+  TypeSystemClang &GetTypeSystem() const { return m_ast; }
+
+  llvm::Optional<clang::ExternalASTSource::ASTSourceDescriptor>
+  getSourceDescriptor(unsigned ID) override;
+  clang::Module *getModule(unsigned ID) override;
 private:
   TypeSystemClang &m_ast;
+  std::vector<clang::Module *> m_modules;
+  llvm::DenseMap<clang::Module *, unsigned> m_ids;
 };
 
 } // namespace lldb_private
Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
+++ 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 @@
       CompleteType(tag_decl);
   }
 }
+
+unsigned ClangExternalASTSourceCallbacks::registerModule(clang::Module *module) {
+  m_modules.push_back(module);
+  unsigned id = m_modules.size();
+  m_ids.insert({module, id});
+  return id;
+}
+
+llvm::Optional<clang::ExternalASTSource::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;
+}
+
+unsigned ClangExternalASTSourceCallbacks::getIDForModule(clang::Module *module) {
+  return m_ids[module];
+}
Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -993,7 +993,7 @@
 
   clang::NamespaceDecl *namespace_decl =
       m_clang_ast_context->GetUniqueNamespaceDeclaration(
-          g_lldb_local_vars_namespace_cstr, nullptr);
+          g_lldb_local_vars_namespace_cstr, nullptr, 0);
   if (!namespace_decl)
     return;
 
Index: lldb/include/lldb/Symbol/TypeSystem.h
===================================================================
--- lldb/include/lldb/Symbol/TypeSystem.h
+++ lldb/include/lldb/Symbol/TypeSystem.h
@@ -254,9 +254,12 @@
 
   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
 
Index: lldb/include/lldb/Symbol/Type.h
===================================================================
--- lldb/include/lldb/Symbol/Type.h
+++ lldb/include/lldb/Symbol/Type.h
@@ -195,12 +195,7 @@
   void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; }
 
   uint32_t GetEncodingMask();
-
-  bool IsCompleteObjCClass() { return m_is_complete_objc_class; }
-
-  void SetIsCompleteObjCClass(bool is_complete_objc_class) {
-    m_is_complete_objc_class = is_complete_objc_class;
-  }
+  uint32_t &GetPayload() { return m_payload; }
 
 protected:
   ConstString m_name;
@@ -215,7 +210,8 @@
   Declaration m_decl;
   CompilerType m_compiler_type;
   ResolveState m_compiler_type_resolve_state;
-  bool m_is_complete_objc_class;
+  /// Language-specific flags.
+  uint32_t m_payload = 0;
 
   Type *GetEncodingType();
 
Index: lldb/include/lldb/Symbol/CompilerType.h
===================================================================
--- lldb/include/lldb/Symbol/CompilerType.h
+++ lldb/include/lldb/Symbol/CompilerType.h
@@ -233,9 +233,10 @@
 
   // 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.
+  // invalid type. The payload argument is the typesystem-specific 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;
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -8493,7 +8493,7 @@
 
 llvm::Optional<ExternalASTSource::ASTSourceDescriptor>
 ASTReader::getSourceDescriptor(unsigned ID) {
-  if (const Module *M = getSubmodule(ID))
+  if (Module *M = getSubmodule(ID))
     return ExternalASTSource::ASTSourceDescriptor(*M);
 
   // If there is only a single PCH, return it instead.
Index: clang/lib/AST/ExternalASTSource.cpp
===================================================================
--- clang/lib/AST/ExternalASTSource.cpp
+++ clang/lib/AST/ExternalASTSource.cpp
@@ -39,7 +39,7 @@
   return EK_ReplyHazy;
 }
 
-ExternalASTSource::ASTSourceDescriptor::ASTSourceDescriptor(const Module &M)
+ExternalASTSource::ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
   : Signature(M.Signature), ClangModule(&M) {
   if (M.Directory)
     Path = M.Directory->getName();
Index: clang/include/clang/AST/ExternalASTSource.h
===================================================================
--- clang/include/clang/AST/ExternalASTSource.h
+++ clang/include/clang/AST/ExternalASTSource.h
@@ -173,7 +173,7 @@
     StringRef Path;
     StringRef ASTFile;
     ASTFileSignature Signature;
-    const Module *ClangModule = nullptr;
+    Module *ClangModule = nullptr;
 
   public:
     ASTSourceDescriptor() = default;
@@ -181,13 +181,13 @@
                         ASTFileSignature Signature)
         : PCHModuleName(std::move(Name)), Path(std::move(Path)),
           ASTFile(std::move(ASTFile)), Signature(Signature) {}
-    ASTSourceDescriptor(const Module &M);
+    ASTSourceDescriptor(Module &M);
 
     std::string getModuleName() const;
     StringRef getPath() const { return Path; }
     StringRef getASTFile() const { return ASTFile; }
     ASTFileSignature getSignature() const { return Signature; }
-    const Module *getModuleOrNull() const { return ClangModule; }
+    Module *getModuleOrNull() const { return ClangModule; }
   };
 
   /// Return a descriptor for the corresponding module, if one exists.
Index: clang/include/clang/AST/DeclBase.h
===================================================================
--- clang/include/clang/AST/DeclBase.h
+++ clang/include/clang/AST/DeclBase.h
@@ -626,13 +626,15 @@
     setModuleOwnershipKind(ModuleOwnershipKind::ModulePrivate);
   }
 
+public:
+  void setFromASTFile() { FromASTFile = true; }
+  
   /// Set the owning module ID.
   void setOwningModuleID(unsigned ID) {
     assert(isFromASTFile() && "Only works on a deserialized declaration");
     *((unsigned*)this - 2) = ID;
   }
 
-public:
   /// Determine the availability of the given declaration.
   ///
   /// This routine will determine the most restrictive availability of
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to