aprantl created this revision.
aprantl added reviewers: teemperor, shafik, labath.

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.

The fact that Clang modules are orthogonal to DeclContexts made the 
implementation in LLDB challenging. In the end I extended 
`lldb_private::CompilerDeclContext` to hold a pair of `clang::DeclContext *` 
and `clang::Module *` and made sure to use CompilerDeclContext everywhere in 
TypeSystemClang. To save memory for all non-Clang typesystems, the extra data 
for the owning module ID is hidden in the CompilerDeclContext's opaque pointer: 
If it isn't a raw clang::DeclContext pointer, it is an index into an array of 
Module ID + DeclContexts.


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/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/SymbolFile/PDB/SymbolFilePDB.cpp
  lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
  lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
  lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
  lldb/test/Shell/SymbolFile/DWARF/owning-module.test
  lldb/unittests/Symbol/TestTypeSystemClang.cpp
  lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.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,8 @@
 }
 
 inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) {
-  return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(),
+  return ast.CreateRecordType(ast.GetAsCompilerDeclContext(
+                                  ast.getASTContext().getTranslationUnitDecl()),
                               lldb::AccessType::eAccessPublic, name, 0,
                               lldb::LanguageType::eLanguageTypeC);
 }
Index: lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
===================================================================
--- lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -23,10 +23,10 @@
   using DWARFASTParserClang::DWARFASTParserClang;
   using DWARFASTParserClang::LinkDeclContextToDIE;
 
-  std::vector<const clang::DeclContext *> GetDeclContextToDIEMapKeys() {
-    std::vector<const clang::DeclContext *> keys;
+  std::vector<CompilerDeclContext> GetDeclContextToDIEMapKeys() {
+    std::vector<CompilerDeclContext> keys;
     for (const auto &it : m_decl_ctx_to_die)
-      keys.push_back(it.first);
+      keys.push_back({&m_ast, it.first});
     return keys;
   }
 };
@@ -103,13 +103,14 @@
   std::vector<DWARFDIE> dies = {
       DWARFDIE(unit, die_child0), DWARFDIE(unit, die_child1),
       DWARFDIE(unit, die_child2), DWARFDIE(unit, die_child3)};
-  std::vector<clang::DeclContext *> decl_ctxs = {
-      (clang::DeclContext *)1LL, (clang::DeclContext *)2LL,
-      (clang::DeclContext *)2LL, (clang::DeclContext *)3LL};
+  std::vector<CompilerDeclContext> decl_ctxs = {
+      {&ast_ctx, (clang::DeclContext *)1LL},
+      {&ast_ctx, (clang::DeclContext *)2LL},
+      {&ast_ctx, (clang::DeclContext *)2LL},
+      {&ast_ctx, (clang::DeclContext *)3LL}};
   for (int i = 0; i < 4; ++i)
     ast_parser.LinkDeclContextToDIE(decl_ctxs[i], dies[i]);
-  ast_parser.EnsureAllDIEsInDeclContextHaveBeenParsed(
-      CompilerDeclContext(nullptr, decl_ctxs[1]));
+  ast_parser.EnsureAllDIEsInDeclContextHaveBeenParsed(decl_ctxs[1]);
 
   EXPECT_THAT(ast_parser.GetDeclContextToDIEMapKeys(),
               testing::UnorderedElementsAre(decl_ctxs[0], decl_ctxs[3]));
Index: lldb/unittests/Symbol/TestTypeSystemClang.cpp
===================================================================
--- lldb/unittests/Symbol/TestTypeSystemClang.cpp
+++ lldb/unittests/Symbol/TestTypeSystemClang.cpp
@@ -257,9 +257,10 @@
       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",
+          m_ast->GetAsCompilerDeclContext(ast.GetTranslationUnitDecl()),
+          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());
@@ -273,7 +274,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,
+      {}, 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 +286,7 @@
 
 TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {
   CompilerType record_type = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
+      {}, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
       lldb::eLanguageTypeC_plus_plus, nullptr);
   QualType qt;
 
@@ -357,7 +358,7 @@
 
   // Test that a record with no fields returns false
   CompilerType empty_base = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct,
+      {}, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct,
       lldb::eLanguageTypeC_plus_plus, nullptr);
   TypeSystemClang::StartTagDeclarationDefinition(empty_base);
   TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);
@@ -368,7 +369,7 @@
 
   // Test that a record with direct fields returns true
   CompilerType non_empty_base = m_ast->CreateRecordType(
-      nullptr, lldb::eAccessPublic, "NonEmptyBase", clang::TTK_Struct,
+      {}, 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 +385,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,
+      {}, 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 +408,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,
+      {}, 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 +440,15 @@
 
   // template<typename T, int I> struct foo;
   ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
-      m_ast->GetTranslationUnitDecl(), eAccessPublic, "foo", TTK_Struct, infos);
+      m_ast->GetAsCompilerDeclContext(m_ast->GetTranslationUnitDecl()),
+      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->GetAsCompilerDeclContext(m_ast->GetTranslationUnitDecl()),
+          decl, TTK_Struct, infos);
   ASSERT_NE(spec_decl, nullptr);
   CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl);
   ASSERT_TRUE(type);
@@ -454,7 +457,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->GetAsCompilerDeclContext(m_ast->GetTranslationUnitDecl()));
 
   CompilerType auto_type(
       m_ast.get(),
@@ -528,13 +532,14 @@
   // 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(
+      m_ast->GetAsCompilerDeclContext(TU), "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(m_ast->GetAsCompilerDeclContext(TU),
+                                        func, "foo", empty_params);
 
   EXPECT_EQ(TU, func_template->getDeclContext());
   EXPECT_EQ("foo", func_template->getName());
@@ -559,12 +564,13 @@
   // 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(m_ast->GetAsCompilerDeclContext(TU), "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(m_ast->GetAsCompilerDeclContext(record),
+                                        func, "foo", empty_params);
 
   EXPECT_EQ(record, func_template->getDeclContext());
   EXPECT_EQ("foo", func_template->getName());
Index: lldb/test/Shell/SymbolFile/DWARF/owning-module.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/owning-module.test
@@ -0,0 +1,6 @@
+// RUN: llc  %S/compilercontext.ll -filetype=obj -o %t.o
+// RUN: %clang_host -g -c -o %t.o %s
+// RUN: lldb-test symbols -dump-clang-ast %t.o | FileCheck %s
+// Verify that the owning module information from DWARF is preserved in the AST. 
+// CHECK: CXXRecordDecl {{.*}} imported in CModule.SubModule struct FromSubmodule definition
+
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -25,6 +25,7 @@
 #include "clang/AST/TemplateBase.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/PointerEmbeddedInt.h"
 #include "llvm/ADT/SmallVector.h"
 
 #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
@@ -40,6 +41,11 @@
 class DWARFASTParserClang;
 class PDBASTParser;
 
+namespace clang {
+  class HeaderSearch;
+  class ModuleMap;
+}
+
 namespace lldb_private {
 
 class ClangASTMetadata;
@@ -268,7 +274,12 @@
   static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl,
                                     bool omit_empty_base_classes);
 
-  CompilerType CreateRecordType(clang::DeclContext *decl_ctx,
+  /// 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(CompilerDeclContext decl_ctx,
                                 lldb::AccessType access_type,
                                 llvm::StringRef name, int kind,
                                 lldb::LanguageType language,
@@ -293,7 +304,7 @@
   };
 
   clang::FunctionTemplateDecl *
-  CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx,
+  CreateFunctionTemplateDecl(CompilerDeclContext decl_ctx,
                              clang::FunctionDecl *func_decl, const char *name,
                              const TemplateParameterInfos &infos);
 
@@ -302,7 +313,7 @@
       const TemplateParameterInfos &infos);
 
   clang::ClassTemplateDecl *
-  CreateClassTemplateDecl(clang::DeclContext *decl_ctx,
+  CreateClassTemplateDecl(CompilerDeclContext decl_ctx,
                           lldb::AccessType access_type, const char *class_name,
                           int kind, const TemplateParameterInfos &infos);
 
@@ -310,7 +321,7 @@
   CreateTemplateTemplateParmDecl(const char *template_name);
 
   clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl(
-      clang::DeclContext *decl_ctx,
+      CompilerDeclContext decl_ctx,
       clang::ClassTemplateDecl *class_template_decl, int kind,
       const TemplateParameterInfos &infos);
 
@@ -330,7 +341,7 @@
   static bool RecordHasFields(const clang::RecordDecl *record_decl);
 
   CompilerType CreateObjCClass(llvm::StringRef name,
-                               clang::DeclContext *decl_ctx, bool isForwardDecl,
+                               CompilerDeclContext decl_ctx, bool isForwardDecl,
                                bool isInternal,
                                ClangASTMetadata *metadata = nullptr);
 
@@ -347,13 +358,13 @@
   // Namespace Declarations
 
   clang::NamespaceDecl *
-  GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx,
+  GetUniqueNamespaceDeclaration(const char *name, CompilerDeclContext decl_ctx,
                                 bool is_inline = false);
 
   // Function Types
 
   clang::FunctionDecl *
-  CreateFunctionDeclaration(clang::DeclContext *decl_ctx, const char *name,
+  CreateFunctionDeclaration(CompilerDeclContext decl_ctx, const char *name,
                             const CompilerType &function_Type, int storage,
                             bool is_inline);
 
@@ -369,7 +380,7 @@
                               type_quals, clang::CC_C);
   }
 
-  clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx,
+  clang::ParmVarDecl *CreateParameterDeclaration(CompilerDeclContext decl_ctx,
                                                  const char *name,
                                                  const CompilerType &param_type,
                                                  int storage,
@@ -387,7 +398,7 @@
 
   // Enumeration Types
   CompilerType CreateEnumerationType(const char *name,
-                                     clang::DeclContext *decl_ctx,
+                                     CompilerDeclContext decl_ctx,
                                      const Declaration &decl,
                                      const CompilerType &integer_qual_type,
                                      bool is_scoped);
@@ -448,12 +459,6 @@
 
   // CompilerDeclContext override functions
 
-  /// Creates a CompilerDeclContext from the given DeclContext
-  /// with the current TypeSystemClang instance as its typesystem.
-  /// The DeclContext has to come from the ASTContext of this
-  /// TypeSystemClang.
-  CompilerDeclContext CreateDeclContext(clang::DeclContext *ctx);
-
   std::vector<CompilerDecl>
   DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
                             const bool ignore_using_decls) override;
@@ -926,20 +931,20 @@
   GetAsObjCInterfaceDecl(const CompilerType &type);
 
   clang::ClassTemplateDecl *ParseClassTemplateDecl(
-      clang::DeclContext *decl_ctx, lldb::AccessType access_type,
+      CompilerDeclContext decl_ctx, 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(CompilerDeclContext ctx);
 
   clang::UsingDirectiveDecl *
-  CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx,
+  CreateUsingDirectiveDeclaration(CompilerDeclContext decl_ctx,
                                   clang::NamespaceDecl *ns_decl);
 
-  clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
+  clang::UsingDecl *CreateUsingDeclaration(CompilerDeclContext current_decl_ctx,
                                            clang::NamedDecl *target);
 
-  clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context,
+  clang::VarDecl *CreateVariableDeclaration(CompilerDeclContext decl_context,
                                             const char *name,
                                             clang::QualType type);
 
@@ -962,6 +967,52 @@
   clang::DeclarationName
   GetDeclarationName(const char *name, const CompilerType &function_clang_type);
 
+  // BEGIN SWIFT
+  clang::LangOptions *GetLangOpts() const {
+    return m_language_options_up.get();
+  }
+  clang::SourceManager *GetSourceMgr() const {
+    return m_source_manager_up.get();
+  }
+  // END SWIFT
+
+  /// To save memory in the general case, Clang DeclContexts are tagged
+  /// pointers that are either a straight (clang::DeclContext *) or
+  /// an index into m_decl_contexts which holds ModuleDeclContext structs.
+  struct ModuleDeclContext {
+    clang::DeclContext *decl_context = nullptr;
+    unsigned owning_module = 0;
+
+    ModuleDeclContext(clang::DeclContext *dc, unsigned m)
+        : decl_context(dc), owning_module(m) {}
+    operator bool() const { return decl_context; }
+
+    using IndexType =
+        llvm::PointerEmbeddedInt<unsigned,
+                                 sizeof(unsigned) * CHAR_BIT - 8>;
+    using WrappedPointer = llvm::PointerUnion<clang::DeclContext *, IndexType>;
+  };
+
+  ModuleDeclContext
+  GetModuleDeclContextFromCompilerDeclContext(CompilerDeclContext ctx);
+
+  /// Extract the clang::DeclContext from a CompilerDeclContext.
+  clang::DeclContext *GetClangDeclContext(CompilerDeclContext ctx);
+
+  /// Convert into a CompilerDeclContext without attaching module
+  /// information. This should only be used when we are sure that the
+  /// module information isn't needed. It's also used in the PDB
+  /// parser where module info isn't serialized at all.
+  CompilerDeclContext
+  GetAsCompilerDeclContext(const clang::DeclContext *decl_context);
+
+  /// Creates a CompilerDeclContext from the given DeclContext
+  /// with the current TypeSystemClang instance as its typesystem.
+  /// The DeclContext has to come from the ASTContext of this
+  /// TypeSystemClang.
+  CompilerDeclContext CreateDeclContext(clang::DeclContext *decl_context,
+                                        unsigned owning_module);
+
 private:
   const clang::ClassTemplateSpecializationDecl *
   GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type);
@@ -979,6 +1030,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;
@@ -989,6 +1042,7 @@
   /// Useful for logging and debugging.
   std::string m_display_name;
 
+  std::vector<ModuleDeclContext> m_decl_contexts;
   typedef llvm::DenseMap<const clang::Decl *, ClangASTMetadata> DeclMetadataMap;
   /// Maps Decls to their associated ClangASTMetadata.
   DeclMetadataMap m_decl_metadata;
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"
@@ -1157,12 +1160,6 @@
   return CompilerType();
 }
 
-CompilerDeclContext TypeSystemClang::CreateDeclContext(DeclContext *ctx) {
-  // Check that the DeclContext actually belongs to this ASTContext.
-  assert(&ctx->getParentASTContext() == &getASTContext());
-  return CompilerDeclContext(this, ctx);
-}
-
 CompilerType TypeSystemClang::GetTypeForDecl(clang::NamedDecl *decl) {
   if (clang::ObjCInterfaceDecl *interface_decl =
       llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
@@ -1182,7 +1179,52 @@
 
 #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;
+
+  // 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);
+}
+
+static void SetOwningModule(clang::Decl *decl,
+                            TypeSystemClang::ModuleDeclContext decl_ctx) {
+  if (decl && decl_ctx.owning_module) {
+    decl->setFromASTFile();
+    decl->setOwningModuleID(decl_ctx.owning_module);
+    decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
+  }
+}
+
+CompilerType TypeSystemClang::CreateRecordType(CompilerDeclContext decl_ctx,
                                                AccessType access_type,
                                                llvm::StringRef name, int kind,
                                                LanguageType language,
@@ -1190,8 +1232,8 @@
                                                bool exports_symbols) {
   ASTContext &ast = getASTContext();
 
-  if (decl_ctx == nullptr)
-    decl_ctx = ast.getTranslationUnitDecl();
+  if (!decl_ctx)
+    decl_ctx = GetAsCompilerDeclContext(ast.getTranslationUnitDecl());
 
   if (language == eLanguageTypeObjC ||
       language == eLanguageTypeObjC_plus_plus) {
@@ -1207,10 +1249,11 @@
   // complete definition just in case.
 
   bool has_name = !name.empty();
-
+  auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx);
   CXXRecordDecl *decl = CXXRecordDecl::Create(
-      ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), SourceLocation(),
-      has_name ? &ast.Idents.get(name) : nullptr);
+      ast, (TagDecl::TagKind)kind, mod_ctx.decl_context, SourceLocation(),
+      SourceLocation(), has_name ? &ast.Idents.get(name) : nullptr);
+  SetOwningModule(decl, mod_ctx);
 
   if (!has_name) {
     // In C++ a lambda is also represented as an unnamed class. This is
@@ -1237,7 +1280,7 @@
     // Anonymous classes is a GNU/MSVC extension that clang supports. It
     // requires the anonymous class be embedded within a class. So the new
     // heuristic verifies this condition.
-    if (isa<CXXRecordDecl>(decl_ctx) && exports_symbols)
+    if (isa<CXXRecordDecl>(mod_ctx.decl_context) && exports_symbols)
       decl->setAnonymousStructOrUnion(true);
   }
 
@@ -1249,7 +1292,7 @@
       decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type));
 
     if (decl_ctx)
-      decl_ctx->addDecl(decl);
+      mod_ctx.decl_context->addDecl(decl);
 
     return GetType(ast.getTagDeclType(decl));
   }
@@ -1322,18 +1365,19 @@
 }
 
 clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
-    clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl,
+    CompilerDeclContext decl_ctx, 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;
-
+  auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx);
   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);
+      ast, mod_ctx.decl_context, func_decl->getLocation(),
+      func_decl->getDeclName(), template_param_list, func_decl);
+  SetOwningModule(func_tmpl_decl, mod_ctx);
 
   for (size_t i = 0, template_param_decl_count = template_param_decls.size();
        i < template_param_decl_count; ++i) {
@@ -1343,7 +1387,7 @@
   // Function templates inside a record need to have an access specifier.
   // It doesn't matter what access specifier we give the template as LLDB
   // anyway allows accessing everything inside a record.
-  if (decl_ctx->isRecord())
+  if (GetClangDeclContext(decl_ctx)->isRecord())
     func_tmpl_decl->setAccess(clang::AccessSpecifier::AS_public);
 
   return func_tmpl_decl;
@@ -1360,18 +1404,19 @@
 }
 
 ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
-    DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name,
+    CompilerDeclContext decl_ctx, lldb::AccessType access_type, const char *class_name,
     int kind, const TemplateParameterInfos &template_param_infos) {
   ASTContext &ast = getASTContext();
 
   ClassTemplateDecl *class_template_decl = nullptr;
-  if (decl_ctx == nullptr)
-    decl_ctx = ast.getTranslationUnitDecl();
+  if (!decl_ctx)
+    decl_ctx = CreateDeclContext(ast.getTranslationUnitDecl(), 0);
 
   IdentifierInfo &identifier_info = ast.Idents.get(class_name);
   DeclarationName decl_name(&identifier_info);
 
-  clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
+  clang::DeclContext::lookup_result result =
+      GetClangDeclContext(decl_ctx)->lookup(decl_name);
 
   for (NamedDecl *decl : result) {
     class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
@@ -1384,11 +1429,13 @@
   TemplateParameterList *template_param_list = CreateTemplateParameterList(
       ast, template_param_infos, template_param_decls);
 
+  auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx);
   CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create(
       ast, (TagDecl::TagKind)kind,
-      decl_ctx, // What decl context do we use here? TU? The actual decl
-                // context?
+      mod_ctx.decl_context, // What decl context do we use here? TU? The actual
+                            // decl context?
       SourceLocation(), SourceLocation(), &identifier_info);
+  SetOwningModule(template_cxx_decl, mod_ctx);
 
   for (size_t i = 0, template_param_decl_count = template_param_decls.size();
        i < template_param_decl_count; ++i) {
@@ -1402,10 +1449,11 @@
 
   class_template_decl = ClassTemplateDecl::Create(
       ast,
-      decl_ctx, // What decl context do we use here? TU? The actual decl
-                // context?
+      mod_ctx.decl_context, // 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, mod_ctx);
 
   if (class_template_decl) {
     if (access_type != eAccessNone)
@@ -1415,7 +1463,7 @@
     // if (TagDecl *ctx_tag_decl = dyn_cast<TagDecl>(decl_ctx))
     //    CompleteTagDeclarationDefinition(GetTypeForDecl(ctx_tag_decl));
 
-    decl_ctx->addDecl(class_template_decl);
+    mod_ctx.decl_context->addDecl(class_template_decl);
 
     VerifyDecl(class_template_decl);
   }
@@ -1448,8 +1496,8 @@
 
 ClassTemplateSpecializationDecl *
 TypeSystemClang::CreateClassTemplateSpecializationDecl(
-    DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
-    const TemplateParameterInfos &template_param_infos) {
+    CompilerDeclContext decl_ctx, ClassTemplateDecl *class_template_decl,
+    int kind, const TemplateParameterInfos &template_param_infos) {
   ASTContext &ast = getASTContext();
   llvm::SmallVector<clang::TemplateArgument, 2> args(
       template_param_infos.args.size() +
@@ -1460,10 +1508,12 @@
     args[args.size() - 1] = TemplateArgument::CreatePackCopy(
         ast, template_param_infos.packed_args->args);
   }
+  auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx);
   ClassTemplateSpecializationDecl *class_template_specialization_decl =
       ClassTemplateSpecializationDecl::Create(
-          ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
+          ast, (TagDecl::TagKind)kind, mod_ctx.decl_context, SourceLocation(),
           SourceLocation(), class_template_decl, args, nullptr);
+  SetOwningModule(class_template_decl, mod_ctx);
 
   class_template_specialization_decl->setSpecializationKind(
       TSK_ExplicitSpecialization);
@@ -1583,20 +1633,22 @@
 #pragma mark Objective-C Classes
 
 CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name,
-                                              DeclContext *decl_ctx,
+                                              CompilerDeclContext decl_ctx,
                                               bool isForwardDecl,
                                               bool isInternal,
                                               ClangASTMetadata *metadata) {
   ASTContext &ast = getASTContext();
   assert(!name.empty());
-  if (decl_ctx == nullptr)
-    decl_ctx = ast.getTranslationUnitDecl();
+  if (!decl_ctx)
+    decl_ctx = CreateDeclContext(ast.getTranslationUnitDecl(), 0);
 
+  auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx);
   ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create(
-      ast, decl_ctx, SourceLocation(), &ast.Idents.get(name), nullptr, nullptr,
+      ast, mod_ctx.decl_context, SourceLocation(), &ast.Idents.get(name), nullptr, nullptr,
       SourceLocation(),
       /*isForwardDecl,*/
       isInternal);
+  SetOwningModule(decl, mod_ctx);
 
   if (decl && metadata)
     SetMetadata(decl, *metadata);
@@ -1634,17 +1686,20 @@
 #pragma mark Namespace Declarations
 
 NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration(
-    const char *name, DeclContext *decl_ctx, bool is_inline) {
+    const char *name, CompilerDeclContext decl_ctx, bool is_inline) {
   NamespaceDecl *namespace_decl = nullptr;
   ASTContext &ast = getASTContext();
   TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl();
-  if (decl_ctx == nullptr)
-    decl_ctx = translation_unit_decl;
+  if (!decl_ctx)
+    decl_ctx = CreateDeclContext(translation_unit_decl, 0);
+
+  auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx);
 
   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 =
+        GetClangDeclContext(decl_ctx)->lookup(decl_name);
     for (NamedDecl *decl : result) {
       namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
       if (namespace_decl)
@@ -1652,30 +1707,31 @@
     }
 
     namespace_decl =
-        NamespaceDecl::Create(ast, decl_ctx, is_inline, SourceLocation(),
+        NamespaceDecl::Create(ast, mod_ctx.decl_context, is_inline, SourceLocation(),
                               SourceLocation(), &identifier_info, nullptr);
 
-    decl_ctx->addDecl(namespace_decl);
+    mod_ctx.decl_context->addDecl(namespace_decl);
   } else {
-    if (decl_ctx == translation_unit_decl) {
+    if (GetClangDeclContext(decl_ctx) == translation_unit_decl) {
       namespace_decl = translation_unit_decl->getAnonymousNamespace();
       if (namespace_decl)
         return namespace_decl;
 
       namespace_decl =
-          NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(),
+          NamespaceDecl::Create(ast, mod_ctx.decl_context, false, SourceLocation(),
                                 SourceLocation(), nullptr, nullptr);
       translation_unit_decl->setAnonymousNamespace(namespace_decl);
       translation_unit_decl->addDecl(namespace_decl);
       assert(namespace_decl == translation_unit_decl->getAnonymousNamespace());
     } else {
-      NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
+      NamespaceDecl *parent_namespace_decl =
+          cast<NamespaceDecl>(GetClangDeclContext(decl_ctx));
       if (parent_namespace_decl) {
         namespace_decl = parent_namespace_decl->getAnonymousNamespace();
         if (namespace_decl)
           return namespace_decl;
         namespace_decl =
-            NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(),
+            NamespaceDecl::Create(ast, mod_ctx.decl_context, false, SourceLocation(),
                                   SourceLocation(), nullptr, nullptr);
         parent_namespace_decl->setAnonymousNamespace(namespace_decl);
         parent_namespace_decl->addDecl(namespace_decl);
@@ -1687,16 +1743,21 @@
       }
     }
   }
+  // Note: namespaces can span multiple modules, so perhaps this isn't a good idea.
+  SetOwningModule(namespace_decl, mod_ctx);
+
   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());
-    ctx->addDecl(decl);
+TypeSystemClang::CreateBlockDeclaration(CompilerDeclContext ctx) {
+  if (ctx) {
+    auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(ctx);
+    clang::BlockDecl *decl = clang::BlockDecl::Create(
+        getASTContext(), mod_ctx.decl_context, clang::SourceLocation());
+    GetClangDeclContext(ctx)->addDecl(decl);
+    SetOwningModule(decl, mod_ctx);
     return decl;
   }
   return nullptr;
@@ -1720,47 +1781,61 @@
 }
 
 clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration(
-    clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) {
-  if (decl_ctx != nullptr && ns_decl != nullptr) {
+    CompilerDeclContext decl_ctx, 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;
+      auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx);
+      clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
+          getASTContext(), mod_ctx.decl_context, clang::SourceLocation(),
+          clang::SourceLocation(), clang::NestedNameSpecifierLoc(),
+          clang::SourceLocation(), ns_decl,
+          FindLCABetweenDecls(GetClangDeclContext(decl_ctx), ns_decl,
+                              translation_unit));
+      mod_ctx.decl_context->addDecl(using_decl);
+      SetOwningModule(using_decl, mod_ctx);
+
+      return using_decl;
   }
   return nullptr;
 }
 
 clang::UsingDecl *
-TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
+TypeSystemClang::CreateUsingDeclaration(CompilerDeclContext current_decl_ctx,
                                         clang::NamedDecl *target) {
-  if (current_decl_ctx != nullptr && target != nullptr) {
+  if (current_decl_ctx && target) {
+    auto mod_ctx =
+        GetModuleDeclContextFromCompilerDeclContext(current_decl_ctx);
     clang::UsingDecl *using_decl = clang::UsingDecl::Create(
-        getASTContext(), current_decl_ctx, clang::SourceLocation(),
+        getASTContext(), mod_ctx.decl_context, clang::SourceLocation(),
         clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
     clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
-        getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
+        getASTContext(), mod_ctx.decl_context, clang::SourceLocation(), using_decl,
         target);
+    SetOwningModule(using_decl, mod_ctx);
+    SetOwningModule(shadow_decl, mod_ctx);
     using_decl->addShadowDecl(shadow_decl);
-    current_decl_ctx->addDecl(using_decl);
+    GetClangDeclContext(current_decl_ctx)->addDecl(using_decl);
     return using_decl;
   }
   return nullptr;
 }
 
 clang::VarDecl *TypeSystemClang::CreateVariableDeclaration(
-    clang::DeclContext *decl_context, const char *name, clang::QualType type) {
-  if (decl_context != nullptr) {
+    CompilerDeclContext decl_context, const char *name, clang::QualType type) {
+  if (decl_context) {
+    auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_context);
     clang::VarDecl *var_decl = clang::VarDecl::Create(
-        getASTContext(), decl_context, clang::SourceLocation(),
+        getASTContext(), mod_ctx.decl_context, clang::SourceLocation(),
         clang::SourceLocation(),
         name && name[0] ? &getASTContext().Idents.getOwn(name) : nullptr, type,
         nullptr, clang::SC_None);
+    if (mod_ctx.owning_module) {
+      var_decl->setFromASTFile();
+      var_decl->setOwningModuleID(mod_ctx.owning_module);
+    }
+
     var_decl->setAccess(clang::AS_public);
-    decl_context->addDecl(var_decl);
+    GetClangDeclContext(decl_context)->addDecl(var_decl);
     return var_decl;
   }
   return nullptr;
@@ -1870,25 +1945,28 @@
 }
 
 FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
-    DeclContext *decl_ctx, const char *name,
+    CompilerDeclContext decl_ctx, const char *name,
     const CompilerType &function_clang_type, int storage, bool is_inline) {
   FunctionDecl *func_decl = nullptr;
   ASTContext &ast = getASTContext();
-  if (decl_ctx == nullptr)
-    decl_ctx = ast.getTranslationUnitDecl();
+  if (!decl_ctx)
+    decl_ctx = CreateDeclContext(ast.getTranslationUnitDecl(), 0);
 
   const bool hasWrittenPrototype = true;
   const bool isConstexprSpecified = false;
 
   clang::DeclarationName declarationName =
       GetDeclarationName(name, function_clang_type);
+  auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx);
   func_decl = FunctionDecl::Create(
-      ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName,
+      ast, mod_ctx.decl_context, SourceLocation(), SourceLocation(), declarationName,
       ClangUtil::GetQualType(function_clang_type), nullptr,
       (clang::StorageClass)storage, is_inline, hasWrittenPrototype,
       isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
-  if (func_decl)
-    decl_ctx->addDecl(func_decl);
+  if (func_decl) {
+    mod_ctx.decl_context->addDecl(func_decl);
+    SetOwningModule(func_decl, mod_ctx);
+  }
 
   VerifyDecl(func_decl);
 
@@ -1935,16 +2013,19 @@
 }
 
 ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
-    clang::DeclContext *decl_ctx, const char *name,
+    CompilerDeclContext decl_ctx, const char *name,
     const CompilerType &param_type, int storage, bool add_decl) {
   ASTContext &ast = getASTContext();
+  auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx);
   auto *decl =
-      ParmVarDecl::Create(ast, decl_ctx, SourceLocation(), SourceLocation(),
+      ParmVarDecl::Create(ast, mod_ctx.decl_context, SourceLocation(), SourceLocation(),
                           name && name[0] ? &ast.Idents.get(name) : nullptr,
                           ClangUtil::GetQualType(param_type), nullptr,
                           (clang::StorageClass)storage, nullptr);
+  SetOwningModule(decl, mod_ctx);
+ 
   if (add_decl)
-    decl_ctx->addDecl(decl);
+    mod_ctx.decl_context->addDecl(decl);
 
   return decl;
 }
@@ -2004,7 +2085,7 @@
     return type;
   }
 
-  type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(),
+  type = CreateRecordType({}, lldb::eAccessPublic, type_name.GetCString(),
                           clang::TTK_Struct, lldb::eLanguageTypeC);
   StartTagDeclarationDefinition(type);
   for (const auto &field : type_fields)
@@ -2030,28 +2111,27 @@
 
 #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, CompilerDeclContext decl_ctx, 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;
-
+  auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx);
   EnumDecl *enum_decl = EnumDecl::Create(
-      ast, decl_ctx, SourceLocation(), SourceLocation(),
+      ast, mod_ctx.decl_context, SourceLocation(), SourceLocation(),
       name && name[0] ? &ast.Idents.get(name) : nullptr, nullptr,
       is_scoped, // IsScoped
       is_scoped, // IsScopedUsingClassTag
       false);    // IsFixed
 
   if (enum_decl) {
+    SetOwningModule(enum_decl, mod_ctx);
     if (decl_ctx)
-      decl_ctx->addDecl(enum_decl);
+      mod_ctx.decl_context->addDecl(enum_decl);
 
     // TODO: check if we should be setting the promotion type too?
     enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
@@ -4238,19 +4318,20 @@
     clang::ASTContext &clang_ast = ast->getASTContext();
     clang::QualType qual_type(ClangUtil::GetQualType(type));
 
-    clang::DeclContext *decl_ctx =
-        TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx);
-    if (decl_ctx == nullptr)
-      decl_ctx = ast->getASTContext().getTranslationUnitDecl();
+    auto mod_ctx =
+        ast->GetModuleDeclContextFromCompilerDeclContext(compiler_decl_ctx);
+    if (!mod_ctx)
+      mod_ctx = {ast->getASTContext().getTranslationUnitDecl(), 0};
 
     clang::TypedefDecl *decl = clang::TypedefDecl::Create(
-        clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
-        &clang_ast.Idents.get(typedef_name),
+        clang_ast, mod_ctx.decl_context, clang::SourceLocation(),
+        clang::SourceLocation(), &clang_ast.Idents.get(typedef_name),
         clang_ast.getTrivialTypeSourceInfo(qual_type));
 
+    SetOwningModule(decl, mod_ctx);
     decl->setAccess(clang::AS_public); // TODO respect proper access specifier
 
-    decl_ctx->addDecl(decl);
+    ast->GetClangDeclContext(compiler_decl_ctx)->addDecl(decl);
 
     // Get a uniqued clang::QualType for the typedef decl type
     return ast->GetType(clang_ast.getTypedefType(decl));
@@ -4344,22 +4425,26 @@
     clang::ASTContext &clang_ast = getASTContext();
     clang::QualType qual_type(GetQualType(type));
 
-    clang::DeclContext *decl_ctx =
         TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx);
-    if (decl_ctx == nullptr)
-      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));
-
-    clang::TagDecl *tdecl = nullptr;
-    if (!qual_type.isNull()) {
-      if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
-        tdecl = rt->getDecl();
-      if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
-        tdecl = et->getDecl();
+        auto mod_ctx =
+            GetModuleDeclContextFromCompilerDeclContext(compiler_decl_ctx);
+        clang::DeclContext *decl_ctx = mod_ctx.decl_context;
+        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, mod_ctx);
+
+        clang::TagDecl *tdecl = nullptr;
+        if (!qual_type.isNull()) {
+          if (const clang::RecordType *rt =
+                  qual_type->getAs<clang::RecordType>())
+            tdecl = rt->getDecl();
+          if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
+            tdecl = et->getDecl();
     }
 
     // Check whether this declaration is an anonymous struct, union, or enum,
@@ -6875,6 +6960,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 +7006,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 +7047,7 @@
           nullptr,                                  // TypeSourceInfo *
           ConvertAccessTypeToObjCIvarAccessControl(access), bit_width,
           is_synthesized);
+      SetMemberOwningModule(field, class_interface_decl);
 
       if (field) {
         class_interface_decl->addDecl(field);
@@ -7013,6 +7109,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 +7140,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 +7211,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 +7337,7 @@
           SC, is_inline, CSK_unspecified, clang::SourceLocation());
     }
   }
+  SetMemberOwningModule(cxx_method_decl, cxx_record_decl);
 
   clang::AccessSpecifier access_specifier =
       TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
@@ -7413,6 +7513,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 +7599,7 @@
         class_interface_decl, isInstance, isVariadic, isPropertyAccessor,
         isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl,
         HasRelatedResultType);
+    SetMemberOwningModule(getter, class_interface_decl);
 
     if (getter) {
       if (metadata)
@@ -7532,6 +7634,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 +7760,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 +7988,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,7 +8883,7 @@
 }
 
 clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl(
-    clang::DeclContext *decl_ctx, lldb::AccessType access_type,
+    CompilerDeclContext decl_ctx, lldb::AccessType access_type,
     const char *parent_name, int tag_decl_kind,
     const TypeSystemClang::TemplateParameterInfos &template_param_infos) {
   if (template_param_infos.IsValid()) {
@@ -8882,8 +8987,9 @@
 }
 
 CompilerDeclContext TypeSystemClang::DeclGetDeclContext(void *opaque_decl) {
+  // FIXME: This drops the module information.
   if (opaque_decl)
-    return CreateDeclContext(((clang::Decl *)opaque_decl)->getDeclContext());
+    return GetAsCompilerDeclContext(((clang::Decl *)opaque_decl)->getDeclContext());
   return CompilerDeclContext();
 }
 
@@ -8947,8 +9053,7 @@
            it++) {
         if (!searched.insert(it->second).second)
           continue;
-        symbol_file->ParseDeclsForContext(
-            CreateDeclContext(it->second));
+        symbol_file->ParseDeclsForContext(GetAsCompilerDeclContext(it->second));
 
         for (clang::Decl *child : it->second->decls()) {
           if (clang::UsingDirectiveDecl *ud =
@@ -9062,8 +9167,7 @@
           continue;
 
         searched.insert(it->second);
-        symbol_file->ParseDeclsForContext(
-            CreateDeclContext(it->second));
+        symbol_file->ParseDeclsForContext(GetAsCompilerDeclContext(it->second));
 
         for (clang::Decl *child : it->second->decls()) {
           if (clang::UsingDirectiveDecl *ud =
@@ -9194,40 +9298,33 @@
 clang::DeclContext *
 TypeSystemClang::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) {
   if (IsClangDeclContext(dc))
-    return (clang::DeclContext *)dc.GetOpaqueDeclContext();
+    return llvm::cast<TypeSystemClang>(dc.GetTypeSystem())
+        ->GetClangDeclContext(dc);
   return nullptr;
 }
 
 ObjCMethodDecl *
 TypeSystemClang::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) {
-  if (IsClangDeclContext(dc))
-    return llvm::dyn_cast<clang::ObjCMethodDecl>(
-        (clang::DeclContext *)dc.GetOpaqueDeclContext());
-  return nullptr;
+  return llvm::dyn_cast_or_null<clang::ObjCMethodDecl>(
+      DeclContextGetAsDeclContext(dc));
 }
 
 CXXMethodDecl *
 TypeSystemClang::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) {
-  if (IsClangDeclContext(dc))
-    return llvm::dyn_cast<clang::CXXMethodDecl>(
-        (clang::DeclContext *)dc.GetOpaqueDeclContext());
-  return nullptr;
+  return llvm::dyn_cast_or_null<clang::CXXMethodDecl>(
+      DeclContextGetAsDeclContext(dc));
 }
 
 clang::FunctionDecl *
 TypeSystemClang::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) {
-  if (IsClangDeclContext(dc))
-    return llvm::dyn_cast<clang::FunctionDecl>(
-        (clang::DeclContext *)dc.GetOpaqueDeclContext());
-  return nullptr;
+  return llvm::dyn_cast_or_null<clang::FunctionDecl>(
+      DeclContextGetAsDeclContext(dc));
 }
 
 clang::NamespaceDecl *
 TypeSystemClang::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) {
-  if (IsClangDeclContext(dc))
-    return llvm::dyn_cast<clang::NamespaceDecl>(
-        (clang::DeclContext *)dc.GetOpaqueDeclContext());
-  return nullptr;
+  return llvm::dyn_cast_or_null<clang::NamespaceDecl>(
+      DeclContextGetAsDeclContext(dc));
 }
 
 ClangASTMetadata *
@@ -9246,6 +9343,52 @@
   return nullptr;
 }
 
+TypeSystemClang::ModuleDeclContext
+TypeSystemClang::GetModuleDeclContextFromCompilerDeclContext(
+    CompilerDeclContext ctx) {
+  auto ptr = ModuleDeclContext::WrappedPointer::getFromOpaqueValue(
+      ctx.GetOpaqueDeclContext());
+  if (ptr.is<clang::DeclContext *>()) {
+    auto *ctx = ptr.get<clang::DeclContext *>();
+    assert(!ctx || (&ctx->getParentASTContext() == &getASTContext()));
+    return {ctx, 0};
+  }
+
+  size_t idx = ptr.get<ModuleDeclContext::IndexType>();
+  assert(idx > 0);
+  return m_decl_contexts[idx - 1];
+}
+
+clang::DeclContext *
+TypeSystemClang::GetClangDeclContext(CompilerDeclContext ctx) {
+  return GetModuleDeclContextFromCompilerDeclContext(ctx).decl_context;
+}
+
+CompilerDeclContext TypeSystemClang::GetAsCompilerDeclContext(
+    const clang::DeclContext *decl_context) {
+  assert(&decl_context->getParentASTContext() == &getASTContext() &&
+         "decl context belongs to different typesystem");
+  ModuleDeclContext::WrappedPointer ptr =
+      const_cast<clang::DeclContext *>(decl_context);
+  return {this, ptr.getOpaqueValue()};
+}
+
+CompilerDeclContext
+TypeSystemClang::CreateDeclContext(clang::DeclContext *decl_context,
+                                   unsigned owning_module) {
+  // Check that the DeclContext actually belongs to this ASTContext.
+  assert(&decl_context->getParentASTContext() == &getASTContext());
+  ModuleDeclContext::WrappedPointer ptr;
+  if (!owning_module) {
+    ptr = decl_context;
+    assert(ptr.is<clang::DeclContext *>());
+  } else {
+    m_decl_contexts.emplace_back(decl_context, owning_module);
+    ptr = ModuleDeclContext::IndexType(m_decl_contexts.size());
+  }
+  return {this, ptr.getOpaqueValue()};
+}
+
 TypeSystemClangForExpressions::TypeSystemClangForExpressions(
     Target &target, llvm::Triple triple)
     : TypeSystemClang("scratch ASTContext", triple),
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",
+          {}, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s",
           clang::TTK_Struct, lldb::eLanguageTypeC);
 
       TypeSystemClang::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
Index: lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -668,7 +668,7 @@
   if (!decl_context)
     return GetDeclContextContainingUID(uid);
 
-  return clang_ast_ctx->CreateDeclContext(decl_context);
+  return clang_ast_ctx->CreateDeclContext(decl_context, 0);
 }
 
 lldb_private::CompilerDeclContext
@@ -697,7 +697,7 @@
   auto decl_context = pdb->GetDeclContextContainingSymbol(*symbol);
   assert(decl_context);
 
-  return clang_ast_ctx->CreateDeclContext(decl_context);
+  return clang_ast_ctx->CreateDeclContext(decl_context, 0);
 }
 
 void SymbolFilePDB::ParseDeclsForContext(
@@ -1702,7 +1702,7 @@
   if (!namespace_decl)
     return CompilerDeclContext();
 
-  return clang_type_system->CreateDeclContext(namespace_decl);
+  return clang_type_system->CreateDeclContext(namespace_decl, 0);
 }
 
 lldb_private::ConstString SymbolFilePDB::GetPluginName() {
Index: lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -409,9 +409,9 @@
       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(
+          m_ast.GetAsCompilerDeclContext(decl_context), access, name,
+          tag_type_kind, lldb::eLanguageTypeC_plus_plus, &metadata);
       assert(clang_type.IsValid());
 
       auto record_decl =
@@ -497,8 +497,9 @@
       // 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(), m_ast.GetAsCompilerDeclContext(decl_context), decl,
+          builtin_type, isScoped);
 
       auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);
       assert(enum_decl);
@@ -550,7 +551,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.GetAsCompilerDeclContext(decl_ctx));
       if (!ast_typedef)
         return nullptr;
 
@@ -901,7 +902,7 @@
         return nullptr;
 
       decl = m_ast.CreateVariableDeclaration(
-          decl_context, name.c_str(),
+          m_ast.GetAsCompilerDeclContext(decl_context), name.c_str(),
           ClangUtil::GetQualType(type->GetLayoutCompilerType()));
     }
 
@@ -927,8 +928,8 @@
                                     : clang::StorageClass::SC_None;
 
     auto decl = m_ast.CreateFunctionDeclaration(
-        decl_context, name.c_str(), type->GetForwardCompilerType(), storage,
-        func->hasInlineAttribute());
+        m_ast.GetAsCompilerDeclContext(decl_context), name.c_str(),
+        type->GetForwardCompilerType(), storage, func->hasInlineAttribute());
 
     std::vector<clang::ParmVarDecl *> params;
     if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
@@ -941,8 +942,8 @@
             continue;
 
           clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
-              decl, nullptr, arg_type->GetForwardCompilerType(),
-              clang::SC_None, true);
+              m_ast.GetAsCompilerDeclContext(decl), nullptr,
+              arg_type->GetForwardCompilerType(), clang::SC_None, true);
           if (param)
             params.push_back(param);
         }
@@ -1056,8 +1057,9 @@
           IsAnonymousNamespaceName(namespace_name) ? nullptr
                                                    : namespace_name.data();
       clang::NamespaceDecl *namespace_decl =
-          m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str,
-                                              curr_context);
+          m_ast.GetUniqueNamespaceDeclaration(
+              namespace_name_c_str,
+              m_ast.GetAsCompilerDeclContext(curr_context));
 
       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
@@ -777,7 +777,8 @@
   metadata.SetIsDynamicCXXType(false);
 
   CompilerType ct = m_clang.CreateRecordType(
-      context, access, uname, ttk, lldb::eLanguageTypeC_plus_plus, &metadata);
+      m_clang.GetAsCompilerDeclContext(context), access, uname, ttk,
+      lldb::eLanguageTypeC_plus_plus, &metadata);
 
   lldbassert(ct.IsValid());
 
@@ -804,7 +805,8 @@
 PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
                                         clang::DeclContext &context) {
   return m_clang.GetUniqueNamespaceDeclaration(
-      IsAnonymousNamespaceName(name) ? nullptr : name, &context);
+      IsAnonymousNamespaceName(name) ? nullptr : name,
+      m_clang.GetAsCompilerDeclContext(&context));
 }
 
 clang::BlockDecl *
@@ -814,7 +816,8 @@
 
   clang::DeclContext *scope = GetParentDeclContext(block_id);
 
-  clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope);
+  clang::BlockDecl *block_decl =
+      m_clang.CreateBlockDeclaration(m_clang.GetAsCompilerDeclContext(scope));
   m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl});
 
   DeclStatus status;
@@ -831,7 +834,8 @@
   clang::QualType qt = GetOrCreateType(var_info.type);
 
   clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration(
-      &scope, var_info.name.str().c_str(), qt);
+      m_clang.GetAsCompilerDeclContext(&scope), var_info.name.str().c_str(),
+      qt);
 
   m_uid_to_decl[toOpaqueUid(uid)] = var_decl;
   DeclStatus status;
@@ -1012,7 +1016,8 @@
   proc_name.consume_front("::");
 
   clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
-      parent, proc_name.str().c_str(), func_ct, storage, false);
+      m_clang.GetAsCompilerDeclContext(parent), proc_name.str().c_str(),
+      func_ct, storage, false);
 
   lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
   m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
@@ -1080,8 +1085,8 @@
 
     CompilerType param_type_ct = m_clang.GetType(qt);
     clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
-        &function_decl, param_name.str().c_str(), param_type_ct,
-        clang::SC_None, true);
+        m_clang.GetAsCompilerDeclContext(&function_decl),
+        param_name.str().c_str(), param_type_ct, clang::SC_None, true);
     lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
 
     m_uid_to_decl[toOpaqueUid(param_uid)] = param;
@@ -1102,8 +1107,8 @@
 
   Declaration declaration;
   CompilerType enum_ct = m_clang.CreateEnumerationType(
-      uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type),
-      er.isScoped());
+      uname.c_str(), m_clang.GetAsCompilerDeclContext(decl_context),
+      declaration, ToCompilerType(underlying_type), er.isScoped());
 
   TypeSystemClang::StartTagDeclarationDefinition(enum_ct);
   TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);
@@ -1343,7 +1348,7 @@
 
 CompilerDeclContext
 PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) {
-  return m_clang.CreateDeclContext(&context);
+  return m_clang.GetAsCompilerDeclContext(&context);
 }
 
 clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) {
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -74,10 +74,12 @@
   typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
 
   typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
-  typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
+  typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
+                         lldb_private::CompilerDeclContext>
       DIEToDeclContextMap;
-  typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
-      DeclContextToDIEMap;
+  typedef llvm::DenseMap<const DWARFDebugInfoEntry *, unsigned>
+      DIEToModuleMap;
+  typedef std::multimap<void *, const DWARFDIE> DeclContextToDIEMap;
   typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
       DIEToDeclMap;
   typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
@@ -87,10 +89,12 @@
   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;
   /// @}
 
-  clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
+  lldb_private::CompilerDeclContext
+  GetDeclContextForBlock(const DWARFDIE &die, unsigned owning_module);
 
   clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
 
@@ -115,7 +119,7 @@
       lldb_private::ClangASTImporter::LayoutInfo &layout_info);
 
   size_t
-  ParseChildParameters(clang::DeclContext *containing_decl_ctx,
+  ParseChildParameters(lldb_private::CompilerDeclContext containing_decl_ctx,
                        const DWARFDIE &parent_die, bool skip_artificial,
                        bool &is_static, bool &is_variadic,
                        bool &has_template_params,
@@ -136,19 +140,23 @@
 
   clang::Decl *GetClangDeclForDIE(const DWARFDIE &die);
 
-  clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die);
+  lldb_private::CompilerDeclContext
+  GetClangDeclContextForDIE(const DWARFDIE &die, unsigned owning_module);
 
-  clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
-                                                       DWARFDIE *decl_ctx_die);
+  lldb_private::CompilerDeclContext
+  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,
                                   lldb_private::Type *class_type,
                                   std::vector<DWARFDIE> &failures);
 
-  clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die);
+  lldb_private::CompilerDeclContext
+  GetCachedClangDeclContextForDIE(const DWARFDIE &die);
 
-  void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die);
+  void LinkDeclContextToDIE(lldb_private::CompilerDeclContext decl_ctx,
+                            const DWARFDIE &die);
 
   void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die);
 
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -216,9 +216,10 @@
   dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
   clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type);
   if (tag_decl)
-    LinkDeclContextToDIE(tag_decl, die);
+    LinkDeclContextToDIE(
+        m_ast.CreateDeclContext(tag_decl, tag_decl->getOwningModuleID()), die);
   else {
-    clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
+    CompilerDeclContext defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
     if (defn_decl_ctx)
       LinkDeclContextToDIE(defn_decl_ctx, die);
   }
@@ -231,7 +232,7 @@
                                         clang::DeclContext *decl_ctx,
                                         DWARFDIE die,
                                         const char *type_name_cstr) {
-  auto *tag_decl_ctx = clang::dyn_cast<clang::TagDecl>(decl_ctx);
+  auto *tag_decl_ctx = clang::dyn_cast_or_null<clang::TagDecl>(decl_ctx);
   if (!tag_decl_ctx)
     return;
 
@@ -401,15 +402,15 @@
   SymbolFileDWARF *dwarf = die.GetDWARF();
   if (log) {
     DWARFDIE context_die;
-    clang::DeclContext *context =
+    CompilerDeclContext context =
         GetClangDeclContextContainingDIE(die, &context_die);
 
     dwarf->GetObjectFile()->GetModule()->LogMessage(
         log,
         "DWARFASTParserClang::ParseTypeFromDWARF "
         "(die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')",
-        die.GetOffset(), static_cast<void *>(context), context_die.GetOffset(),
-        die.GetTagAsCString(), die.GetName());
+        die.GetOffset(), context.GetOpaqueDeclContext(),
+        context_die.GetOffset(), die.GetTagAsCString(), die.GetName());
   }
 
   Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
@@ -426,7 +427,7 @@
     if (TypeSP type_sp =
             ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) {
       dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
-      if (clang::DeclContext *decl_ctx =
+      if (CompilerDeclContext decl_ctx =
               GetCachedClangDeclContextForDIE(signature_die))
         LinkDeclContextToDIE(decl_ctx, die);
       return type_sp;
@@ -755,7 +756,7 @@
       // it and cache the fact that we found a complete type for this
       // die
       dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
-      clang::DeclContext *defn_decl_ctx =
+      CompilerDeclContext defn_decl_ctx =
           GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
       if (defn_decl_ctx)
         LinkDeclContextToDIE(defn_decl_ctx, die);
@@ -793,7 +794,10 @@
     enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type);
   }
 
-  LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die);
+  LinkDeclContextToDIE(m_ast.CreateDeclContext(
+                           TypeSystemClang::GetDeclContextForType(clang_type),
+                           GetOwningModuleID(die)),
+                       die);
 
   type_sp = std::make_shared<Type>(
       die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
@@ -859,10 +863,10 @@
   // Parse the function children for the parameters
 
   DWARFDIE decl_ctx_die;
-  clang::DeclContext *containing_decl_ctx =
+  CompilerDeclContext containing_decl_ctx =
       GetClangDeclContextContainingDIE(die, &decl_ctx_die);
   const clang::Decl::Kind containing_decl_kind =
-      containing_decl_ctx->getDeclKind();
+      m_ast.GetClangDeclContext(containing_decl_ctx)->getDeclKind();
 
   bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind);
   // Start off static. This will be set to false in
@@ -936,7 +940,9 @@
                   attrs.is_objc_direct_call);
           type_handled = objc_method_decl != NULL;
           if (type_handled) {
-            LinkDeclContextToDIE(objc_method_decl, die);
+            LinkDeclContextToDIE(m_ast.CreateDeclContext(
+                                     objc_method_decl, GetOwningModuleID(die)),
+                                 die);
             m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID());
           } else {
             dwarf->GetObjectFile()->GetModule()->ReportError(
@@ -989,8 +995,8 @@
             // have been made with the specification and not with this
             // die.
             DWARFDIE spec_die = attrs.specification.Reference();
-            clang::DeclContext *spec_clang_decl_ctx =
-                GetClangDeclContextForDIE(spec_die);
+            CompilerDeclContext spec_clang_decl_ctx =
+                GetClangDeclContextForDIE(spec_die, GetOwningModuleID(die));
             if (spec_clang_decl_ctx) {
               LinkDeclContextToDIE(spec_clang_decl_ctx, die);
             } else {
@@ -1008,8 +1014,8 @@
             class_type->GetForwardCompilerType();
 
             DWARFDIE abs_die = attrs.abstract_origin.Reference();
-            clang::DeclContext *abs_clang_decl_ctx =
-                GetClangDeclContextForDIE(abs_die);
+            CompilerDeclContext abs_clang_decl_ctx =
+                GetClangDeclContextForDIE(abs_die, GetOwningModuleID(die));
             if (abs_clang_decl_ctx) {
               LinkDeclContextToDIE(abs_clang_decl_ctx, die);
             } else {
@@ -1049,7 +1055,10 @@
                           if (method_decl->getType() ==
                               ClangUtil::GetQualType(clang_type)) {
                             add_method = false;
-                            LinkDeclContextToDIE(method_decl, die);
+                            LinkDeclContextToDIE(
+                                m_ast.CreateDeclContext(method_decl,
+                                                        GetOwningModuleID(die)),
+                                die);
                             type_handled = true;
 
                             break;
@@ -1091,7 +1100,10 @@
                     type_handled |= attrs.is_artificial;
 
                     if (cxx_method_decl) {
-                      LinkDeclContextToDIE(cxx_method_decl, die);
+                      LinkDeclContextToDIE(
+                          m_ast.CreateDeclContext(cxx_method_decl,
+                                                  GetOwningModuleID(die)),
+                          die);
 
                       ClangASTMetadata metadata;
                       metadata.SetUserID(die.GetID());
@@ -1150,6 +1162,7 @@
     }
 
     if (!type_handled) {
+      CompilerDeclContext ctx;
       clang::FunctionDecl *function_decl = nullptr;
       clang::FunctionDecl *template_function_decl = nullptr;
 
@@ -1157,11 +1170,12 @@
         DWARFDIE abs_die = attrs.abstract_origin.Reference();
 
         if (dwarf->ResolveType(abs_die)) {
+          ctx = GetCachedClangDeclContextForDIE(abs_die);
           function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(
-              GetCachedClangDeclContextForDIE(abs_die));
+              m_ast.GetClangDeclContext(ctx));
 
           if (function_decl) {
-            LinkDeclContextToDIE(function_decl, die);
+            LinkDeclContextToDIE(ctx, die);
           }
         }
       }
@@ -1169,8 +1183,9 @@
       if (!function_decl) {
         // We just have a function that isn't part of a class
         function_decl = m_ast.CreateFunctionDeclaration(
-            ignore_containing_context ? m_ast.GetTranslationUnitDecl()
-                                      : containing_decl_ctx,
+            ignore_containing_context
+                ? m_ast.CreateDeclContext(m_ast.GetTranslationUnitDecl(), 0)
+                : containing_decl_ctx,
             attrs.name.GetCString(), clang_type, attrs.storage,
             attrs.is_inline);
 
@@ -1178,8 +1193,9 @@
           TypeSystemClang::TemplateParameterInfos template_param_infos;
           ParseTemplateParameterInfos(die, template_param_infos);
           template_function_decl = m_ast.CreateFunctionDeclaration(
-              ignore_containing_context ? m_ast.GetTranslationUnitDecl()
-                                        : containing_decl_ctx,
+              ignore_containing_context
+                  ? m_ast.CreateDeclContext(m_ast.GetTranslationUnitDecl(), 0)
+                  : containing_decl_ctx,
               attrs.name.GetCString(), clang_type, attrs.storage,
               attrs.is_inline);
           clang::FunctionTemplateDecl *func_template_decl =
@@ -1193,7 +1209,7 @@
         lldbassert(function_decl);
 
         if (function_decl) {
-          LinkDeclContextToDIE(function_decl, die);
+          LinkDeclContextToDIE(ctx, die);
 
           if (!function_param_decls.empty()) {
             m_ast.SetFunctionParameters(function_decl,
@@ -1543,7 +1559,7 @@
       // We found a real definition for this type elsewhere so lets use
       // it and cache the fact that we found a complete type for this die
       dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
-      clang::DeclContext *defn_decl_ctx =
+      CompilerDeclContext defn_decl_ctx =
           GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
       if (defn_decl_ctx)
         LinkDeclContextToDIE(defn_decl_ctx, die);
@@ -1554,22 +1570,27 @@
   bool clang_type_was_created = false;
   clang_type.SetCompilerType(
       &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
-  if (!clang_type) {
-    clang::DeclContext *decl_ctx =
-        GetClangDeclContextContainingDIE(die, nullptr);
+  CompilerDeclContext decl_ctx;
+  if (clang_type) {
+    // FIXME: This drops the owning module information.
+    decl_ctx =
+        m_ast.GetAsCompilerDeclContext(m_ast.GetDeclContextForType(clang_type));
+  } else {
+    decl_ctx = GetClangDeclContextContainingDIE(die, nullptr);
+    clang::DeclContext *clang_decl_ctx = m_ast.GetClangDeclContext(decl_ctx);
 
     // If your decl context is a record that was imported from another
     // AST context (in the gmodules case), we need to make sure the type
     // backing the Decl is complete before adding children to it. This is
     // not an issue in the non-gmodules case because the debug info will
     // always contain a full definition of parent types in that case.
-    CompleteExternalTagDeclType(m_ast, GetClangASTImporter(), decl_ctx, die,
+    CompleteExternalTagDeclType(m_ast, GetClangASTImporter(), clang_decl_ctx, die,
                                 attrs.name.GetCString());
 
-    if (attrs.accessibility == eAccessNone && decl_ctx) {
+    if (attrs.accessibility == eAccessNone && clang_decl_ctx) {
       // Check the decl context that contains this class/struct/union. If
       // it is a class we must give it an accessibility.
-      const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
+      const clang::Decl::Kind containing_decl_kind = clang_decl_ctx->getDeclKind();
       if (DeclKindIsCXXClass(containing_decl_kind))
         attrs.accessibility = default_accessibility;
     }
@@ -1621,7 +1642,7 @@
   // Store a forward declaration to this class type in case any
   // parameters in any class methods need it for the clang types for
   // function prototypes.
-  LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
+  LinkDeclContextToDIE(decl_ctx, die);
   type_sp = std::make_shared<Type>(die.GetID(), dwarf, attrs.name,
                                    attrs.byte_size, nullptr, LLDB_INVALID_UID,
                                    Type::eEncodingIsUID, &attrs.decl,
@@ -2183,19 +2204,22 @@
 
 CompilerDeclContext
 DWARFASTParserClang::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
-  clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE(die);
-  if (clang_decl_ctx)
-    return m_ast.CreateDeclContext(clang_decl_ctx);
-  return CompilerDeclContext();
+  CompilerDeclContext clang_decl_ctx =
+      GetClangDeclContextForDIE(die, GetOwningModuleID(die));
+  assert(&m_ast.GetClangDeclContext(clang_decl_ctx)->getParentASTContext() ==
+             &m_ast.getASTContext() &&
+         "decl context belongs to different typesystem");
+  return clang_decl_ctx;
 }
 
 CompilerDeclContext
 DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
-  clang::DeclContext *clang_decl_ctx =
+  CompilerDeclContext clang_decl_ctx =
       GetClangDeclContextContainingDIE(die, nullptr);
-  if (clang_decl_ctx)
-    return m_ast.CreateDeclContext(clang_decl_ctx);
-  return CompilerDeclContext();
+  assert(&m_ast.GetClangDeclContext(clang_decl_ctx)->getParentASTContext() ==
+             &m_ast.getASTContext() &&
+         "decl context belongs to different typesystem");
+  return clang_decl_ctx;
 }
 
 size_t DWARFASTParserClang::ParseChildEnumerators(
@@ -2325,7 +2349,7 @@
         DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die);
         sstr << decl_ctx.GetQualifiedName();
 
-        clang::DeclContext *containing_decl_ctx =
+        CompilerDeclContext containing_decl_ctx =
             GetClangDeclContextContainingDIE(die, nullptr);
         ParseChildParameters(containing_decl_ctx, die, true, is_static,
                              is_variadic, has_template_params, param_types,
@@ -2974,7 +2998,7 @@
 }
 
 size_t DWARFASTParserClang::ParseChildParameters(
-    clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die,
+    CompilerDeclContext containing_decl_ctx, const DWARFDIE &parent_die,
     bool skip_artificial, bool &is_static, bool &is_variadic,
     bool &has_template_params, std::vector<CompilerType> &function_param_types,
     std::vector<clang::ParmVarDecl *> &function_param_decls,
@@ -3033,7 +3057,8 @@
           // In order to determine if a C++ member function is "const" we
           // have to look at the const-ness of "this"...
           if (arg_idx == 0 &&
-              DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()) &&
+              DeclKindIsCXXClass(m_ast.GetClangDeclContext(containing_decl_ctx)
+                                     ->getDeclKind()) &&
               // Often times compilers omit the "this" name for the
               // specification DIEs, so we can't rely upon the name being in
               // the formal parameter DIE...
@@ -3256,12 +3281,8 @@
     SymbolFileDWARF *dwarf = die.GetDWARF();
     Type *type = GetTypeForDIE(die);
     if (dwarf && type) {
-      const char *name = die.GetName();
-      clang::DeclContext *decl_context =
-          TypeSystemClang::DeclContextGetAsDeclContext(
-              dwarf->GetDeclContextContainingUID(die.GetID()));
       decl = m_ast.CreateVariableDeclaration(
-          decl_context, name,
+          dwarf->GetDeclContextContainingUID(die.GetID()), die.GetName(),
           ClangUtil::GetQualType(type->GetForwardCompilerType()));
     }
     break;
@@ -3272,14 +3293,12 @@
     if (imported_uid) {
       CompilerDecl imported_decl = SymbolFileDWARF::GetDecl(imported_uid);
       if (imported_decl) {
-        clang::DeclContext *decl_context =
-            TypeSystemClang::DeclContextGetAsDeclContext(
-                dwarf->GetDeclContextContainingUID(die.GetID()));
         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(
+              dwarf->GetDeclContextContainingUID(die.GetID()),
+              clang_imported_decl);
       }
     }
     break;
@@ -3292,13 +3311,11 @@
       CompilerDeclContext imported_decl_ctx =
           SymbolFileDWARF::GetDeclContext(imported_uid);
       if (imported_decl_ctx) {
-        clang::DeclContext *decl_context =
-            TypeSystemClang::DeclContextGetAsDeclContext(
-                dwarf->GetDeclContextContainingUID(die.GetID()));
         if (clang::NamespaceDecl *ns_decl =
                 TypeSystemClang::DeclContextGetAsNamespaceDecl(
                     imported_decl_ctx))
-          decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
+          decl = m_ast.CreateUsingDirectiveDeclaration(
+              dwarf->GetDeclContextContainingUID(die.GetID()), ns_decl);
       }
     }
     break;
@@ -3313,10 +3330,11 @@
   return decl;
 }
 
-clang::DeclContext *
-DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
+CompilerDeclContext
+DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die,
+                                               unsigned owning_module) {
   if (die) {
-    clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(die);
+    CompilerDeclContext decl_ctx = GetCachedClangDeclContextForDIE(die);
     if (decl_ctx)
       return decl_ctx;
 
@@ -3324,17 +3342,17 @@
     switch (die.Tag()) {
     case DW_TAG_compile_unit:
     case DW_TAG_partial_unit:
-      decl_ctx = m_ast.GetTranslationUnitDecl();
+      decl_ctx = m_ast.CreateDeclContext(m_ast.GetTranslationUnitDecl(), owning_module);
       try_parsing_type = false;
       break;
 
     case DW_TAG_namespace:
-      decl_ctx = ResolveNamespaceDIE(die);
+      decl_ctx = m_ast.CreateDeclContext(ResolveNamespaceDIE(die), owning_module);
       try_parsing_type = false;
       break;
 
     case DW_TAG_lexical_block:
-      decl_ctx = GetDeclContextForBlock(die);
+      decl_ctx = GetDeclContextForBlock(die, owning_module);
       try_parsing_type = false;
       break;
 
@@ -3342,7 +3360,7 @@
       break;
     }
 
-    if (decl_ctx == nullptr && try_parsing_type) {
+    if (!decl_ctx && try_parsing_type) {
       Type *type = die.GetDWARF()->ResolveType(die);
       if (type)
         decl_ctx = GetCachedClangDeclContextForDIE(die);
@@ -3353,7 +3371,32 @@
       return decl_ctx;
     }
   }
-  return nullptr;
+  return {};
+}
+
+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) {
@@ -3404,34 +3447,40 @@
   return DWARFDIE();
 }
 
-clang::DeclContext *
-DWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die) {
+CompilerDeclContext
+DWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die,
+                                            unsigned owning_module) {
   assert(die.Tag() == DW_TAG_lexical_block);
   DWARFDIE containing_function_with_abstract_origin =
       GetContainingFunctionWithAbstractOrigin(die);
   if (!containing_function_with_abstract_origin) {
-    return (clang::DeclContext *)ResolveBlockDIE(die);
+    return m_ast.CreateDeclContext(ResolveBlockDIE(die), owning_module);
   }
   DWARFDIE child = FindFirstChildWithAbstractOrigin(
       die, containing_function_with_abstract_origin);
   CompilerDeclContext decl_context =
       GetDeclContextContainingUIDFromDWARF(child);
-  return (clang::DeclContext *)decl_context.GetOpaqueDeclContext();
+  if (m_ast.GetModuleDeclContextFromCompilerDeclContext(decl_context)
+          .owning_module != owning_module)
+    return m_ast.CreateDeclContext(m_ast.GetClangDeclContext(decl_context),
+                                   owning_module);
+  return decl_context;
 }
 
 clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) {
   if (die && die.Tag() == DW_TAG_lexical_block) {
-    clang::BlockDecl *decl =
-        llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]);
+    clang::BlockDecl *decl = llvm::cast_or_null<clang::BlockDecl>(
+        m_ast.GetClangDeclContext(m_die_to_decl_ctx[die.GetDIE()]));
 
     if (!decl) {
       DWARFDIE decl_context_die;
-      clang::DeclContext *decl_context =
+      CompilerDeclContext decl_context =
           GetClangDeclContextContainingDIE(die, &decl_context_die);
       decl = m_ast.CreateBlockDeclaration(decl_context);
 
       if (decl)
-        LinkDeclContextToDIE((clang::DeclContext *)decl, die);
+        LinkDeclContextToDIE(
+            m_ast.CreateDeclContext(decl, GetOwningModuleID(die)), die);
     }
 
     return decl;
@@ -3444,13 +3493,13 @@
   if (die && die.Tag() == DW_TAG_namespace) {
     // See if we already parsed this namespace DIE and associated it with a
     // uniqued namespace declaration
-    clang::NamespaceDecl *namespace_decl =
-        static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]);
+    clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(
+        m_ast.GetClangDeclContext(m_die_to_decl_ctx[die.GetDIE()]));
     if (namespace_decl)
       return namespace_decl;
     else {
       const char *namespace_name = die.GetName();
-      clang::DeclContext *containing_decl_ctx =
+      CompilerDeclContext containing_decl_ctx =
           GetClangDeclContextContainingDIE(die, nullptr);
       bool is_inline =
           die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0;
@@ -3483,47 +3532,50 @@
       }
 
       if (namespace_decl)
-        LinkDeclContextToDIE((clang::DeclContext *)namespace_decl, die);
+        LinkDeclContextToDIE(
+            m_ast.CreateDeclContext(namespace_decl, GetOwningModuleID(die)),
+            die);
       return namespace_decl;
     }
   }
   return nullptr;
 }
 
-clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE(
+CompilerDeclContext DWARFASTParserClang::GetClangDeclContextContainingDIE(
     const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) {
   SymbolFileDWARF *dwarf = die.GetDWARF();
 
   DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE(die);
+  unsigned owning_module = GetOwningModuleID(die);
 
   if (decl_ctx_die_copy)
     *decl_ctx_die_copy = decl_ctx_die;
 
   if (decl_ctx_die) {
-    clang::DeclContext *clang_decl_ctx =
-        GetClangDeclContextForDIE(decl_ctx_die);
+    CompilerDeclContext clang_decl_ctx =
+      GetClangDeclContextForDIE(decl_ctx_die, owning_module);
     if (clang_decl_ctx)
       return clang_decl_ctx;
   }
-  return m_ast.GetTranslationUnitDecl();
+  return m_ast.CreateDeclContext(m_ast.GetTranslationUnitDecl(), owning_module);
 }
 
-clang::DeclContext *
+CompilerDeclContext
 DWARFASTParserClang::GetCachedClangDeclContextForDIE(const DWARFDIE &die) {
   if (die) {
     DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE());
     if (pos != m_die_to_decl_ctx.end())
       return pos->second;
   }
-  return nullptr;
+  return {};
 }
 
-void DWARFASTParserClang::LinkDeclContextToDIE(clang::DeclContext *decl_ctx,
+void DWARFASTParserClang::LinkDeclContextToDIE(CompilerDeclContext decl_ctx,
                                                const DWARFDIE &die) {
   m_die_to_decl_ctx[die.GetDIE()] = decl_ctx;
   // There can be many DIEs for a single decl context
-  // m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
-  m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die));
+  m_decl_ctx_to_die.insert(
+      std::make_pair(decl_ctx.GetOpaqueDeclContext(), die));
 }
 
 bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
@@ -3650,11 +3702,11 @@
       src_die = src_name_to_die.GetValueAtIndexUnchecked(idx);
       dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
 
-      clang::DeclContext *src_decl_ctx =
+      CompilerDeclContext src_decl_ctx =
           src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
       if (src_decl_ctx) {
         LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
-                  static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+                  src_decl_ctx.GetOpaqueDeclContext(), src_die.GetOffset(),
                   dst_die.GetOffset());
         dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
       } else {
@@ -3694,11 +3746,11 @@
         src_die = src_name_to_die.Find(dst_name, DWARFDIE());
 
         if (src_die && (src_die.Tag() == dst_die.Tag())) {
-          clang::DeclContext *src_decl_ctx =
+          CompilerDeclContext src_decl_ctx =
               src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
           if (src_decl_ctx) {
             LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
-                      static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+                      src_decl_ctx.GetOpaqueDeclContext(), src_die.GetOffset(),
                       dst_die.GetOffset());
             dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
           } else {
@@ -3714,7 +3766,7 @@
             LLDB_LOGF(
                 log,
                 "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
-                static_cast<void *>(src_child_type), src_child_type->GetID(),
+                src_decl_ctx.GetOpaqueDeclContext(), src_child_type->GetID(),
                 src_die.GetOffset(), dst_die.GetOffset());
             dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] =
                 src_child_type;
@@ -3749,11 +3801,11 @@
 
       if (dst_die) {
         // Both classes have the artificial types, link them
-        clang::DeclContext *src_decl_ctx =
+        CompilerDeclContext src_decl_ctx =
             src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
         if (src_decl_ctx) {
           LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
-                    static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+                    src_decl_ctx.GetOpaqueDeclContext(), src_die.GetOffset(),
                     dst_die.GetOffset());
           dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
         } else {
@@ -3769,7 +3821,7 @@
           LLDB_LOGF(
               log,
               "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
-              static_cast<void *>(src_child_type), src_child_type->GetID(),
+              src_decl_ctx.GetOpaqueDeclContext(), src_child_type->GetID(),
               src_die.GetOffset(), dst_die.GetOffset());
           dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
         } else {
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));
+      {}, 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(),
+          {}, 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
@@ -661,7 +661,7 @@
     if (namespace_context->getName().str() ==
         std::string(g_lldb_local_vars_namespace_cstr)) {
       CompilerDeclContext compiler_decl_ctx =
-          m_clang_ast_context->CreateDeclContext(
+          m_clang_ast_context->GetAsCompilerDeclContext(
               const_cast<clang::DeclContext *>(context.m_decl_context));
       FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx);
       return;
@@ -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, {});
   if (!namespace_decl)
     return;
 
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