diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index eb8b99bf3421306c7317d95a24cf6f2c6f8873fe..46a3a4e11f1b33bfdb06f9078f96f11ee0f6b0a3 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -1530,4 +1530,23 @@ namespace clang {
   }
 } // end namespace clang
 
+namespace llvm {
+  template <> struct DenseMapInfo<clang::serialization::DeclarationNameKey> {
+    static clang::serialization::DeclarationNameKey getEmptyKey() {
+      return clang::serialization::DeclarationNameKey(-1, 1);
+    }
+    static clang::serialization::DeclarationNameKey getTombstoneKey() {
+      return clang::serialization::DeclarationNameKey(-1, 2);
+    }
+    static unsigned
+    getHashValue(const clang::serialization::DeclarationNameKey &Key) {
+      return Key.getHash();
+    }
+    static bool isEqual(const clang::serialization::DeclarationNameKey &L,
+                        const clang::serialization::DeclarationNameKey &R) {
+      return L == R;
+    }
+  };
+}
+
 #endif
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index dca2032655f915a7c0a20c5522d3cb5b38671ce6..84f1b6629111d8666ed6771940733bca8e19f782 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -282,9 +282,8 @@ class ReadMethodPoolVisitor;
 
 namespace reader {
   class ASTIdentifierLookupTrait;
-  /// \brief The on-disk hash table used for the DeclContext's Name lookup table.
-  typedef llvm::OnDiskIterableChainedHashTable<ASTDeclContextNameLookupTrait>
-    ASTDeclContextNameLookupTable;
+  /// \brief The on-disk hash table(s) used for DeclContext name lookup.
+  struct DeclContextLookupTable;
 }
 
 } // end namespace serialization
@@ -507,6 +506,10 @@ private:
   /// \brief Map from the TU to its lexical contents from each module file.
   std::vector<std::pair<ModuleFile*, LexicalContents>> TULexicalDecls;
 
+  /// \brief Map from a DeclContext to its lookup tables.
+  llvm::DenseMap<const DeclContext *,
+                 serialization::reader::DeclContextLookupTable> Lookups;
+
   // Updates for visible decls can occur for other contexts than just the
   // TU, and when we read those update records, the actual context may not
   // be available yet, so have this pending map using the ID as a key. It
@@ -514,7 +517,6 @@ private:
   struct PendingVisibleUpdate {
     ModuleFile *Mod;
     const unsigned char *Data;
-    unsigned BucketOffset;
   };
   typedef SmallVector<PendingVisibleUpdate, 1> DeclContextVisibleUpdates;
 
@@ -1089,6 +1091,10 @@ public:
         Visit(GetExistingDecl(ID));
   }
 
+  /// \brief Get the loaded lookup tables for \p Primary, if any.
+  const serialization::reader::DeclContextLookupTable *
+  getLoadedLookupTables(DeclContext *Primary) const;
+
 private:
   struct ImportedModule {
     ModuleFile *Mod;
@@ -1870,6 +1876,13 @@ public:
   /// Note: overrides method in ExternalASTSource
   Module *getModule(unsigned ID) override;
 
+  /// \brief Retrieve the module file with a given local ID within the specified
+  /// ModuleFile.
+  ModuleFile *getLocalModuleFile(ModuleFile &M, unsigned ID);
+
+  /// \brief Get an ID for the given module file.
+  unsigned getModuleFileID(ModuleFile *M);
+
   /// \brief Return a descriptor for the corresponding module.
   llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override;
   /// \brief Return a descriptor for the module.
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 3711e155f633dd85ffe22f8d4275f36928e6e982..1c045c26b7ea0572898b9e0aa7dcb82da337c7ab 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -529,8 +529,8 @@ private:
   bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
   bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC);
 
-  uint32_t GenerateNameLookupTable(const DeclContext *DC,
-                                   llvm::SmallVectorImpl<char> &LookupTable);
+  void GenerateNameLookupTable(const DeclContext *DC,
+                               llvm::SmallVectorImpl<char> &LookupTable);
   uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
   uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
   void WriteTypeDeclOffsets();
@@ -849,6 +849,7 @@ public:
   unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; }
 
   bool hasChain() const { return Chain; }
+  ASTReader *getChain() const { return Chain; }
 
   // ASTDeserializationListener implementation
   void ReaderInitialized(ASTReader *Reader) override;
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 93067031ae8ef4f3af2fbcd0ea8ba54f45fec710..1b9560188cb0f17d80a80b3b297b870c150d0bf7 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -50,14 +50,6 @@ enum ModuleKind {
   MK_MainFile        ///< File is a PCH file treated as the actual main file.
 };
 
-/// \brief Information about the contents of a DeclContext.
-struct DeclContextInfo {
-  DeclContextInfo() : NameLookupTableData() {}
-
-  llvm::OnDiskIterableChainedHashTable<reader::ASTDeclContextNameLookupTrait>
-    *NameLookupTableData; // an ASTDeclContextNameLookupTable.
-};
-
 /// \brief The input file that has been loaded from this AST file, along with
 /// bools indicating whether this was an overridden buffer or if it was
 /// out-of-date or not-found.
@@ -416,13 +408,6 @@ public:
   /// indexed by the C++ ctor initializer list ID minus 1.
   const uint32_t *CXXCtorInitializersOffsets;
 
-  typedef llvm::DenseMap<const DeclContext *, DeclContextInfo>
-  DeclContextInfosMap;
-
-  /// \brief Information about the lexical and visible declarations
-  /// for each DeclContext.
-  DeclContextInfosMap DeclContextInfos;
-
   /// \brief Array of file-level DeclIDs sorted by file.
   const serialization::DeclID *FileSortedDecls;
   unsigned NumFileSortedDecls;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index af1130df3ff7c7bba36c108d4a99df9d19779823..91a977bb6914eb0a6eba4cc09ab8d9655666bc48 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -20,6 +20,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Frontend/PCHContainerOperations.h"
+#include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLocVisitor.h"
@@ -903,6 +904,13 @@ unsigned DeclarationNameKey::getHash() const {
   return ID.ComputeHash();
 }
 
+ModuleFile *
+ASTDeclContextNameLookupTrait::ReadFileRef(const unsigned char *&d) {
+  using namespace llvm::support;
+  uint32_t ModuleFileID = endian::readNext<uint32_t, little, unaligned>(d);
+  return Reader.getLocalModuleFile(F, ModuleFileID);
+}
+
 std::pair<unsigned, unsigned>
 ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char *&d) {
   using namespace llvm::support;
@@ -948,15 +956,15 @@ ASTDeclContextNameLookupTrait::ReadKey(const unsigned char *d, unsigned) {
   return DeclarationNameKey(Kind, Data);
 }
 
-ASTDeclContextNameLookupTrait::data_type
-ASTDeclContextNameLookupTrait::ReadData(internal_key_type,
-                                        const unsigned char *d,
-                                        unsigned DataLen) {
+void ASTDeclContextNameLookupTrait::ReadDataInto(internal_key_type,
+                                                 const unsigned char *d,
+                                                 unsigned DataLen,
+                                                 data_type &Val) {
   using namespace llvm::support;
-  unsigned NumDecls = DataLen / 4;
-  LE32DeclID *Start = reinterpret_cast<LE32DeclID *>(
-                        const_cast<unsigned char *>(d));
-  return std::make_pair(Start, Start + NumDecls);
+  for (unsigned NumDecls = DataLen / 4; NumDecls; --NumDecls) {
+    uint32_t LocalID = endian::readNext<uint32_t, little, unaligned>(d);
+    Val.insert(Reader.getGlobalDeclID(F, LocalID));
+  }
 }
 
 bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
@@ -1015,9 +1023,8 @@ bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M,
 
   // We can't safely determine the primary context yet, so delay attaching the
   // lookup table until we're done with recursive deserialization.
-  unsigned BucketOffset = Record[0];
-  PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{
-      &M, (const unsigned char *)Blob.data(), BucketOffset});
+  auto *Data = (const unsigned char*)Blob.data();
+  PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&M, Data});
   return false;
 }
 
@@ -2551,9 +2558,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
       unsigned Idx = 0;
       serialization::DeclID ID = ReadDeclID(F, Record, Idx);
       auto *Data = (const unsigned char*)Blob.data();
-      unsigned BucketOffset = Record[Idx++];
-      PendingVisibleUpdates[ID].push_back(
-          PendingVisibleUpdate{&F, Data, BucketOffset});
+      PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&F, Data});
       // If we've already loaded the decl, perform the updates when we finish
       // loading this block.
       if (Decl *D = GetExistingDecl(ID))
@@ -6354,196 +6359,48 @@ void ASTReader::FindFileRegionDecls(FileID File,
     Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt)));
 }
 
-/// \brief Retrieve the "definitive" module file for the definition of the
-/// given declaration context, if there is one.
-///
-/// The "definitive" module file is the only place where we need to look to
-/// find information about the declarations within the given declaration
-/// context. For example, C++ and Objective-C classes, C structs/unions, and
-/// Objective-C protocols, categories, and extensions are all defined in a
-/// single place in the source code, so they have definitive module files
-/// associated with them. C++ namespaces, on the other hand, can have
-/// definitions in multiple different module files.
-///
-/// Note: this needs to be kept in sync with ASTWriter::AddedVisibleDecl's
-/// NDEBUG checking.
-static ModuleFile *getDefinitiveModuleFileFor(const DeclContext *DC,
-                                              ASTReader &Reader) {
-  if (const DeclContext *DefDC = getDefinitiveDeclContext(DC))
-    return Reader.getOwningModuleFile(cast<Decl>(DefDC));
-
-  return nullptr;
-}
-
-namespace {
-  /// \brief ModuleFile visitor used to perform name lookup into a
-  /// declaration context.
-  class DeclContextNameLookupVisitor {
-    ASTReader &Reader;
-    const DeclContext *Context;
-    DeclarationName Name;
-    DeclarationNameKey NameKey;
-    unsigned NameHash;
-    SmallVectorImpl<NamedDecl *> &Decls;
-    llvm::SmallPtrSetImpl<NamedDecl *> &DeclSet;
-
-  public:
-    DeclContextNameLookupVisitor(ASTReader &Reader, const DeclContext *Context,
-                                 DeclarationName Name,
-                                 SmallVectorImpl<NamedDecl *> &Decls,
-                                 llvm::SmallPtrSetImpl<NamedDecl *> &DeclSet)
-        : Reader(Reader), Context(Context), Name(Name), NameKey(Name),
-          NameHash(NameKey.getHash()), Decls(Decls), DeclSet(DeclSet) {}
-
-    bool operator()(ModuleFile &M) {
-      // Check whether we have any visible declaration information for
-      // this context in this module.
-      auto Info = M.DeclContextInfos.find(Context);
-      if (Info == M.DeclContextInfos.end() || !Info->second.NameLookupTableData)
-        return false;
-
-      // Look for this name within this module.
-      ASTDeclContextNameLookupTable *LookupTable =
-          Info->second.NameLookupTableData;
-      ASTDeclContextNameLookupTable::iterator Pos =
-          LookupTable->find_hashed(NameKey, NameHash);
-      if (Pos == LookupTable->end())
-        return false;
-
-      bool FoundAnything = false;
-      ASTDeclContextNameLookupTrait::data_type Data = *Pos;
-      for (; Data.first != Data.second; ++Data.first) {
-        NamedDecl *ND = Reader.GetLocalDeclAs<NamedDecl>(M, *Data.first);
-        if (!ND)
-          continue;
-
-        if (ND->getDeclName() != Name) {
-          // Not all names map to a unique DeclarationNameKey.
-          assert(DeclarationNameKey(ND->getDeclName()) == NameKey &&
-                 "mismatched name for decl in decl context lookup table?");
-          continue;
-        }
-
-        // Record this declaration.
-        FoundAnything = true;
-        if (DeclSet.insert(ND).second)
-          Decls.push_back(ND);
-      }
-
-      return FoundAnything;
-    }
-  };
-}
-
 bool
 ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
                                           DeclarationName Name) {
-  assert(DC->hasExternalVisibleStorage() &&
+  assert(DC->hasExternalVisibleStorage() && DC == DC->getPrimaryContext() &&
          "DeclContext has no visible decls in storage");
   if (!Name)
     return false;
 
+  auto It = Lookups.find(DC);
+  if (It == Lookups.end())
+    return false;
+
   Deserializing LookupResults(this);
 
+  // Load the list of declarations.
   SmallVector<NamedDecl *, 64> Decls;
-  llvm::SmallPtrSet<NamedDecl*, 64> DeclSet;
-
-  DeclContextNameLookupVisitor Visitor(*this, DC, Name, Decls, DeclSet);
-
-  // If we can definitively determine which module file to look into,
-  // only look there. Otherwise, look in all module files.
-  if (ModuleFile *Definitive = getDefinitiveModuleFileFor(DC, *this))
-    Visitor(*Definitive);
-  else
-    ModuleMgr.visit(Visitor);
+  for (DeclID ID : It->second.Table.find(Name)) {
+    NamedDecl *ND = cast<NamedDecl>(GetDecl(ID));
+    if (ND->getDeclName() == Name)
+      Decls.push_back(ND);
+  }
 
   ++NumVisibleDeclContextsRead;
   SetExternalVisibleDeclsForName(DC, Name, Decls);
   return !Decls.empty();
 }
 
-namespace {
-  /// \brief ModuleFile visitor used to retrieve all visible names in a
-  /// declaration context.
-  class DeclContextAllNamesVisitor {
-    ASTReader &Reader;
-    SmallVectorImpl<const DeclContext *> &Contexts;
-    DeclsMap &Decls;
-    llvm::SmallPtrSet<NamedDecl *, 256> DeclSet;
-    bool VisitAll;
-
-  public:
-    DeclContextAllNamesVisitor(ASTReader &Reader,
-                               SmallVectorImpl<const DeclContext *> &Contexts,
-                               DeclsMap &Decls, bool VisitAll)
-      : Reader(Reader), Contexts(Contexts), Decls(Decls), VisitAll(VisitAll) { }
-
-    bool operator()(ModuleFile &M) {
-      // Check whether we have any visible declaration information for
-      // this context in this module.
-      ModuleFile::DeclContextInfosMap::iterator Info;
-      bool FoundInfo = false;
-      for (unsigned I = 0, N = Contexts.size(); I != N; ++I) {
-        Info = M.DeclContextInfos.find(Contexts[I]);
-        if (Info != M.DeclContextInfos.end() &&
-            Info->second.NameLookupTableData) {
-          FoundInfo = true;
-          break;
-        }
-      }
-
-      if (!FoundInfo)
-        return false;
-
-      ASTDeclContextNameLookupTable *LookupTable =
-        Info->second.NameLookupTableData;
-      bool FoundAnything = false;
-      for (ASTDeclContextNameLookupTable::data_iterator
-             I = LookupTable->data_begin(), E = LookupTable->data_end();
-           I != E;
-           ++I) {
-        ASTDeclContextNameLookupTrait::data_type Data = *I;
-        for (; Data.first != Data.second; ++Data.first) {
-          NamedDecl *ND = Reader.GetLocalDeclAs<NamedDecl>(M, *Data.first);
-          if (!ND)
-            continue;
-
-          // Record this declaration.
-          FoundAnything = true;
-          if (DeclSet.insert(ND).second)
-            Decls[ND->getDeclName()].push_back(ND);
-        }
-      }
-
-      return FoundAnything && !VisitAll;
-    }
-  };
-}
-
 void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
   if (!DC->hasExternalVisibleStorage())
     return;
-  DeclsMap Decls;
 
-  // Compute the declaration contexts we need to look into. Multiple such
-  // declaration contexts occur when two declaration contexts from disjoint
-  // modules get merged, e.g., when two namespaces with the same name are
-  // independently defined in separate modules.
-  SmallVector<const DeclContext *, 2> Contexts;
-  Contexts.push_back(DC);
+  auto It = Lookups.find(DC);
+  assert(It != Lookups.end() &&
+         "have external visible storage but no lookup tables");
 
-  if (DC->isNamespace()) {
-    KeyDeclsMap::iterator Key =
-        KeyDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
-    if (Key != KeyDecls.end()) {
-      for (unsigned I = 0, N = Key->second.size(); I != N; ++I)
-        Contexts.push_back(cast<DeclContext>(GetDecl(Key->second[I])));
-    }
+  DeclsMap Decls;
+
+  for (DeclID ID : It->second.Table.findAll()) {
+    NamedDecl *ND = cast<NamedDecl>(GetDecl(ID));
+    Decls[ND->getDeclName()].push_back(ND);
   }
 
-  DeclContextAllNamesVisitor Visitor(*this, Contexts, Decls,
-                                     /*VisitAll=*/DC->isFileContext());
-  ModuleMgr.visit(Visitor);
   ++NumVisibleDeclContextsRead;
 
   for (DeclsMap::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
@@ -6552,6 +6409,12 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
   const_cast<DeclContext *>(DC)->setHasExternalVisibleStorage(false);
 }
 
+const serialization::reader::DeclContextLookupTable *
+ASTReader::getLoadedLookupTables(DeclContext *Primary) const {
+  auto I = Lookups.find(Primary);
+  return I == Lookups.end() ? nullptr : &I->second;
+}
+
 /// \brief Under non-PCH compilation the consumer receives the objc methods
 /// before receiving the implementation, and codegen depends on this.
 /// We simulate this by deserializing and passing to consumer the methods of the
@@ -7383,6 +7246,37 @@ Module *ASTReader::getModule(unsigned ID) {
   return getSubmodule(ID);
 }
 
+ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &F, unsigned ID) {
+  if (ID & 1) {
+    // It's a module, look it up by submodule ID.
+    auto I = GlobalSubmoduleMap.find(getGlobalSubmoduleID(F, ID >> 1));
+    return I == GlobalSubmoduleMap.end() ? nullptr : I->second;
+  } else {
+    // It's a prefix (preamble, PCH, ...). Look it up by index.
+    unsigned IndexFromEnd = ID >> 1;
+    assert(IndexFromEnd && "got reference to unknown module file");
+    return getModuleManager().pch_modules().end()[-IndexFromEnd];
+  }
+}
+
+unsigned ASTReader::getModuleFileID(ModuleFile *F) {
+  if (!F)
+    return 1;
+
+  // For a file representing a module, use the submodule ID of the top-level
+  // module as the file ID. For any other kind of file, the number of such
+  // files loaded beforehand will be the same on reload.
+  // FIXME: Is this true even if we have an explicit module file and a PCH?
+  if (F->isModule())
+    // FIXME: BaseSubmoduleID appears to be off by one.
+    return ((F->BaseSubmoduleID + 1) << 1) | 1;
+
+  auto PCHModules = getModuleManager().pch_modules();
+  auto I = std::find(PCHModules.begin(), PCHModules.end(), F);
+  assert(I != PCHModules.end() && "emitting reference to unknown file");
+  return (I - PCHModules.end()) << 1;
+}
+
 ExternalASTSource::ASTSourceDescriptor
 ASTReader::getSourceDescriptor(const Module &M) {
   StringRef Dir, Filename;
@@ -8431,6 +8325,8 @@ void ASTReader::FinishedDeserializing() {
       for (auto Update : Updates) {
         auto *FPT = Update.second->getType()->castAs<FunctionProtoType>();
         auto ESI = FPT->getExtProtoInfo().ExceptionSpec;
+        if (auto *Listener = Context.getASTMutationListener())
+          Listener->ResolvedExceptionSpec(cast<FunctionDecl>(Update.second));
         for (auto *Redecl : Update.second->redecls())
           Context.adjustExceptionSpec(cast<FunctionDecl>(Redecl), ESI);
       }
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 25a684a531ef6e9b302a20e2e9a0d2adf87804fd..2677592465d98eac1c6886b3d3c2eb3916b3c77d 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1489,6 +1489,8 @@ void ASTDeclReader::MergeDefinitionData(
     Reader.PendingDefinitions.erase(MergeDD.Definition);
     MergeDD.Definition->IsCompleteDefinition = false;
     mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
+    assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
+           "already loaded pending lookups for merged definition");
   }
 
   auto PFDI = Reader.PendingFakeDefinitionData.find(&DD);
@@ -3346,15 +3348,10 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
     PendingVisibleUpdates.erase(I);
 
     auto *DC = cast<DeclContext>(D)->getPrimaryContext();
-    for (const PendingVisibleUpdate &Update : VisibleUpdates) {
-      auto *&LookupTable = Update.Mod->DeclContextInfos[DC].NameLookupTableData;
-      assert(!LookupTable && "multiple lookup tables for DC in module");
-      LookupTable = reader::ASTDeclContextNameLookupTable::Create(
-          Update.Data + Update.BucketOffset,
-          Update.Data + sizeof(uint32_t),
-          Update.Data,
+    for (const PendingVisibleUpdate &Update : VisibleUpdates)
+      Lookups[DC].Table.add(
+          Update.Mod, Update.Data,
           reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod));
-    }
     DC->setHasExternalVisibleStorage(true);
   }
 
diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h
index 9e097000f25307f166190bf66f99c0722b607e76..5c239e3a0213301f6f714c0df4d3a6b1345ac1ec 100644
--- a/lib/Serialization/ASTReaderInternals.h
+++ b/lib/Serialization/ASTReaderInternals.h
@@ -15,8 +15,12 @@
 
 #include "clang/AST/DeclarationName.h"
 #include "clang/Serialization/ASTBitCodes.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/OnDiskHashTable.h"
+#include "MultiOnDiskHashTable.h"
 #include <utility>
 
 namespace clang {
@@ -39,14 +43,15 @@ class ASTDeclContextNameLookupTrait {
   ModuleFile &F;
   
 public:
-  /// \brief Pair of begin/end iterators for DeclIDs.
-  ///
-  /// Note that these declaration IDs are local to the module that contains this
-  /// particular lookup t
-  typedef llvm::support::ulittle32_t LE32DeclID;
-  typedef std::pair<LE32DeclID *, LE32DeclID *> data_type;
+  // Maximum number of lookup tables we allow before condensing the tables.
+  static const int MaxTables = 4;
+
+  /// The lookup result is a list of global declaration IDs.
+  // FIXME: LLVM doesn't really have a good data structure for this.
+  typedef llvm::DenseSet<DeclID> data_type;
   typedef unsigned hash_value_type;
   typedef unsigned offset_type;
+  typedef ModuleFile *file_type;
 
   typedef DeclarationName external_key_type;
   typedef DeclarationNameKey internal_key_type;
@@ -54,8 +59,7 @@ public:
   explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F)
     : Reader(Reader), F(F) { }
 
-  static bool EqualKey(const internal_key_type& a,
-                       const internal_key_type& b) {
+  static bool EqualKey(const internal_key_type &a, const internal_key_type &b) {
     return a == b;
   }
 
@@ -71,8 +75,18 @@ public:
 
   internal_key_type ReadKey(const unsigned char *d, unsigned);
 
-  data_type ReadData(internal_key_type, const unsigned char *d,
-                     unsigned DataLen);
+  void ReadDataInto(internal_key_type, const unsigned char *d,
+                    unsigned DataLen, data_type &Val);
+
+  static void MergeDataInto(const data_type &From, data_type &To) {
+    To.insert(From.begin(), From.end());
+  }
+
+  file_type ReadFileRef(const unsigned char *&d);
+};
+
+struct DeclContextLookupTable {
+  MultiOnDiskHashTable<ASTDeclContextNameLookupTrait> Table;
 };
 
 /// \brief Base class for the trait describing the on-disk hash table for the
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index b5340dc41d230e2bc27c6cb2abd40569cd03e80c..51839afce1a5cffefc33f2ab285774dbfd3bbf2c 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -13,6 +13,8 @@
 
 #include "clang/Serialization/ASTWriter.h"
 #include "ASTCommon.h"
+#include "ASTReaderInternals.h"
+#include "MultiOnDiskHashTable.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclContextInternals.h"
@@ -3338,12 +3340,14 @@ namespace {
 // Trait used for the on-disk hash table used in the method pool.
 class ASTDeclContextNameLookupTrait {
   ASTWriter &Writer;
+  llvm::SmallVector<DeclID, 64> DeclIDs;
 
 public:
   typedef DeclarationNameKey key_type;
   typedef key_type key_type_ref;
 
-  typedef DeclContext::lookup_result data_type;
+  /// A start and end index into DeclIDs, representing a sequence of decls.
+  typedef std::pair<unsigned, unsigned> data_type;
   typedef const data_type& data_type_ref;
 
   typedef unsigned hash_value_type;
@@ -3351,10 +3355,40 @@ public:
 
   explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { }
 
+  template<typename Coll>
+  data_type getData(const Coll &Decls) {
+    unsigned Start = DeclIDs.size();
+    for (NamedDecl *D : Decls) {
+      DeclIDs.push_back(
+          Writer.GetDeclRef(getDeclForLocalLookup(Writer.getLangOpts(), D)));
+    }
+    return std::make_pair(Start, DeclIDs.size());
+  }
+
+  data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) {
+    unsigned Start = DeclIDs.size();
+    for (auto ID : FromReader)
+      DeclIDs.push_back(ID);
+    return std::make_pair(Start, DeclIDs.size());
+  }
+
+  static bool EqualKey(key_type_ref a, key_type_ref b) {
+    return a == b;
+  }
+
   hash_value_type ComputeHash(DeclarationNameKey Name) {
     return Name.getHash();
   }
 
+  void EmitFileRef(raw_ostream &Out, ModuleFile *F) const {
+    assert(Writer.hasChain() &&
+           "have reference to loaded module file but no chain?");
+
+    using namespace llvm::support;
+    endian::Writer<little>(Out)
+        .write<uint32_t>(Writer.getChain()->getModuleFileID(F));
+  }
+
   std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
                                                   DeclarationNameKey Name,
                                                   data_type_ref Lookup) {
@@ -3381,7 +3415,9 @@ public:
     LE.write<uint16_t>(KeyLen);
 
     // 4 bytes for each DeclID.
-    unsigned DataLen = 4 * Lookup.size();
+    unsigned DataLen = 4 * (Lookup.second - Lookup.first);
+    assert(uint16_t(DataLen) == DataLen &&
+           "too many decls for serialized lookup result");
     LE.write<uint16_t>(DataLen);
 
     return std::make_pair(KeyLen, DataLen);
@@ -3421,11 +3457,8 @@ public:
     using namespace llvm::support;
     endian::Writer<little> LE(Out);
     uint64_t Start = Out.tell(); (void)Start;
-    for (DeclContext::lookup_iterator I = Lookup.begin(), E = Lookup.end();
-         I != E; ++I)
-      LE.write<uint32_t>(
-          Writer.GetDeclRef(getDeclForLocalLookup(Writer.getLangOpts(), *I)));
-
+    for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
+      LE.write<uint32_t>(DeclIDs[I]);
     assert(Out.tell() - Start == DataLen && "Data length is wrong");
   }
 };
@@ -3445,7 +3478,7 @@ bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
   return true;
 }
 
-uint32_t
+void
 ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
                                    llvm::SmallVectorImpl<char> &LookupTable) {
   assert(!ConstDC->HasLazyLocalLexicalLookups &&
@@ -3457,8 +3490,8 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
   assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table");
 
   // Create the on-disk hash table representation.
-  llvm::OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait>
-      Generator;
+  MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
+                                ASTDeclContextNameLookupTrait> Generator;
   ASTDeclContextNameLookupTrait Trait(*this);
 
   // The first step is to collect the declaration names which we need to
@@ -3593,7 +3626,7 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
 
     switch (Name.getNameKind()) {
     default:
-      Generator.insert(Name, Result, Trait);
+      Generator.insert(Name, Trait.getData(Result), Trait);
       break;
 
     case DeclarationName::CXXConstructorName:
@@ -3611,17 +3644,15 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
   // the key, only the kind of name is used.
   if (!ConstructorDecls.empty())
     Generator.insert(ConstructorDecls.front()->getDeclName(),
-                     DeclContext::lookup_result(ConstructorDecls), Trait);
+                     Trait.getData(ConstructorDecls), Trait);
   if (!ConversionDecls.empty())
     Generator.insert(ConversionDecls.front()->getDeclName(),
-                     DeclContext::lookup_result(ConversionDecls), Trait);
+                     Trait.getData(ConversionDecls), Trait);
 
-  // Create the on-disk hash table in a buffer.
-  llvm::raw_svector_ostream Out(LookupTable);
-  // Make sure that no bucket is at offset 0
-  using namespace llvm::support;
-  endian::Writer<little>(Out).write<uint32_t>(0);
-  return Generator.Emit(Out, Trait);
+  // Create the on-disk hash table. Also emit the existing imported and
+  // merged table if there is one.
+  auto *Lookups = Chain ? Chain->getLoadedLookupTables(DC) : nullptr;
+  Generator.emit(LookupTable, Trait, Lookups ? &Lookups->Table : nullptr);
 }
 
 /// \brief Write the block containing all of the declaration IDs
@@ -3704,12 +3735,11 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
 
   // Create the on-disk hash table in a buffer.
   SmallString<4096> LookupTable;
-  uint32_t BucketOffset = GenerateNameLookupTable(DC, LookupTable);
+  GenerateNameLookupTable(DC, LookupTable);
 
   // Write the lookup table
   RecordData Record;
   Record.push_back(DECL_CONTEXT_VISIBLE);
-  Record.push_back(BucketOffset);
   Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
                             LookupTable);
   ++NumVisibleDeclContexts;
@@ -3732,7 +3762,7 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
 
   // Create the on-disk hash table in a buffer.
   SmallString<4096> LookupTable;
-  uint32_t BucketOffset = GenerateNameLookupTable(DC, LookupTable);
+  GenerateNameLookupTable(DC, LookupTable);
 
   // If we're updating a namespace, select a key declaration as the key for the
   // update record; those are the only ones that will be checked on reload.
@@ -3743,7 +3773,6 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
   RecordData Record;
   Record.push_back(UPDATE_VISIBLE);
   Record.push_back(getDeclID(cast<Decl>(DC)));
-  Record.push_back(BucketOffset);
   Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
 }
 
@@ -4207,7 +4236,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
   Abv = new llvm::BitCodeAbbrev();
   Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
-  Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
   UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv);
   WriteDeclContextVisibleUpdate(TU);
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 24e07c42a41ede0a315efbc959e51100221a1353..1095a4b4774e7ac0d7c805f70890a56f3db73059 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -2049,7 +2049,6 @@ void ASTWriter::WriteDeclAbbrevs() {
 
   Abv = new BitCodeAbbrev();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
   DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv);
 }
diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp
index 9111fc40a0270357ea9aa145ab739a16be2434c1..4884f0b0948062f58bb946a36a34285a2d334460 100644
--- a/lib/Serialization/Module.cpp
+++ b/lib/Serialization/Module.cpp
@@ -45,13 +45,6 @@ ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation)
 {}
 
 ModuleFile::~ModuleFile() {
-  for (DeclContextInfosMap::iterator I = DeclContextInfos.begin(),
-       E = DeclContextInfos.end();
-       I != E; ++I) {
-    if (I->second.NameLookupTableData)
-      delete I->second.NameLookupTableData;
-  }
-  
   delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
   delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
   delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
diff --git a/lib/Serialization/MultiOnDiskHashTable.h b/lib/Serialization/MultiOnDiskHashTable.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf06a77912f70f818010b497b3065fc8e35d752a
--- /dev/null
+++ b/lib/Serialization/MultiOnDiskHashTable.h
@@ -0,0 +1,318 @@
+//===--- MultiOnDiskHashTable.h - Merged set of hash tables -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides a hash table data structure suitable for incremental and
+//  distributed storage across a set of files.
+//
+//  Multiple hash tables from different files are implicitly merged to improve
+//  performance, and on reload the merged table will override those from other
+//  files.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H
+#define LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H
+
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/OnDiskHashTable.h"
+
+namespace clang {
+namespace serialization {
+
+class ModuleFile;
+
+/// \brief A collection of on-disk hash tables, merged when relevant for performance.
+template<typename Info> class MultiOnDiskHashTable {
+public:
+  /// A handle to a file, used when overriding tables.
+  typedef typename Info::file_type file_type;
+  /// A pointer to an on-disk representation of the hash table.
+  typedef const unsigned char *storage_type;
+
+  typedef typename Info::external_key_type external_key_type;
+  typedef typename Info::internal_key_type internal_key_type;
+  typedef typename Info::data_type data_type;
+  typedef unsigned hash_value_type;
+
+private:
+  /// \brief A hash table stored on disk.
+  struct OnDiskTable {
+    typedef llvm::OnDiskIterableChainedHashTable<Info> HashTable;
+
+    file_type File;
+    HashTable Table;
+
+    OnDiskTable(file_type File, unsigned NumBuckets, unsigned NumEntries,
+                storage_type Buckets, storage_type Payload, storage_type Base,
+                const Info &InfoObj)
+        : File(File),
+          Table(NumBuckets, NumEntries, Buckets, Payload, Base, InfoObj) {}
+  };
+
+  struct MergedTable {
+    std::vector<file_type> Files;
+    llvm::DenseMap<internal_key_type, data_type> Data;
+  };
+
+  typedef llvm::PointerUnion<OnDiskTable*, MergedTable*> Table;
+  typedef llvm::TinyPtrVector<void*> TableVector;
+
+  /// \brief The current set of on-disk and merged tables.
+  /// We manually store the opaque value of the Table because TinyPtrVector
+  /// can't cope with holding a PointerUnion directly.
+  /// There can be at most one MergedTable in this vector, and if present,
+  /// it is the first table.
+  TableVector Tables;
+
+  /// \brief Files corresponding to overridden tables that we've not yet
+  /// discarded.
+  llvm::TinyPtrVector<file_type> PendingOverrides;
+
+  struct AsOnDiskTable {
+    typedef OnDiskTable *result_type;
+    result_type operator()(void *P) const {
+      return Table::getFromOpaqueValue(P).template get<OnDiskTable *>();
+    }
+  };
+  typedef llvm::mapped_iterator<TableVector::iterator, AsOnDiskTable>
+      table_iterator;
+  typedef llvm::iterator_range<table_iterator> table_range;
+
+  /// \brief The current set of on-disk tables.
+  table_range tables() {
+    auto Begin = Tables.begin(), End = Tables.end();
+    if (getMergedTable())
+      ++Begin;
+    return llvm::make_range(llvm::map_iterator(Begin, AsOnDiskTable()),
+                            llvm::map_iterator(End, AsOnDiskTable()));
+  }
+
+  MergedTable *getMergedTable() const {
+    // If we already have a merged table, it's the first one.
+    return Tables.empty() ? nullptr : Table::getFromOpaqueValue(*Tables.begin())
+                                          .template dyn_cast<MergedTable*>();
+  }
+
+  /// \brief Delete all our current on-disk tables.
+  void clear() {
+    if (auto *M = getMergedTable())
+      delete M;
+    for (auto *T : tables())
+      delete T;
+  }
+
+  void removeOverriddenTables() {
+    llvm::DenseSet<file_type> Files;
+    Files.insert(PendingOverrides.begin(), PendingOverrides.end());
+    Tables.erase(
+        std::remove_if(tables().begin().getCurrent(), Tables.end(), [&](void *T) -> bool {
+          auto *ODT = Table::getFromOpaqueValue(T).template get<OnDiskTable*>();
+          return Files.count(ODT->File);
+        }), Tables.end());
+    PendingOverrides.clear();
+  }
+
+  void condense() {
+    MergedTable *Merged = getMergedTable();
+    if (!Merged)
+      Merged = new MergedTable;
+
+    // Read in all the tables and merge them together.
+    // FIXME: Be smarter about which tables we merge.
+    for (auto *ODT : tables()) {
+      auto &HT = ODT->Table;
+      Info &InfoObj = HT.getInfoObj();
+
+      for (auto I = HT.data_begin(), E = HT.data_end(); I != E; ++I) {
+        auto *LocalPtr = I.getItem();
+
+        // FIXME: Don't rely on the OnDiskHashTable format here.
+        auto L = InfoObj.ReadKeyDataLength(LocalPtr);
+        const internal_key_type &Key = InfoObj.ReadKey(LocalPtr, L.first);
+        InfoObj.ReadDataInto(Key, LocalPtr + L.first, L.second,
+                             Merged->Data[Key]);
+      }
+
+      Merged->Files.push_back(ODT->File);
+      delete ODT;
+    }
+
+    Tables.clear();
+    Tables.push_back(Table(Merged).getOpaqueValue());
+  }
+
+  /// The generator is permitted to read our merged table.
+  template<typename ReaderInfo, typename WriterInfo>
+  friend class MultiOnDiskHashTableGenerator;
+
+public:
+  MultiOnDiskHashTable() {}
+  MultiOnDiskHashTable(MultiOnDiskHashTable &&O)
+      : Tables(std::move(O.Tables)),
+        PendingOverrides(std::move(O.PendingOverrides)) {
+    O.Tables.clear();
+  }
+  MultiOnDiskHashTable &operator=(MultiOnDiskHashTable &&O) {
+    if (&O == this)
+      return *this;
+    clear();
+    Tables = std::move(O.Tables);
+    O.Tables.clear();
+    PendingOverrides = std::move(O.PendingOverrides);
+    return *this;
+  }
+  ~MultiOnDiskHashTable() { clear(); }
+
+  /// \brief Add the table \p Data loaded from file \p File.
+  void add(file_type File, storage_type Data, Info InfoObj = Info()) {
+    using namespace llvm::support;
+    storage_type Ptr = Data;
+
+    uint32_t BucketOffset = endian::readNext<uint32_t, little, unaligned>(Ptr);
+
+    // Read the list of overridden files.
+    uint32_t NumFiles = endian::readNext<uint32_t, little, unaligned>(Ptr);
+    // FIXME: Add a reserve() to TinyPtrVector so that we don't need to make
+    // an additional copy.
+    llvm::SmallVector<file_type, 16> OverriddenFiles;
+    OverriddenFiles.reserve(NumFiles);
+    for (/**/; NumFiles != 0; --NumFiles)
+      OverriddenFiles.push_back(InfoObj.ReadFileRef(Ptr));
+    PendingOverrides.insert(PendingOverrides.end(), OverriddenFiles.begin(),
+                            OverriddenFiles.end());
+
+    // Read the OnDiskChainedHashTable header.
+    storage_type Buckets = Data + BucketOffset;
+    auto NumBucketsAndEntries =
+        OnDiskTable::HashTable::readNumBucketsAndEntries(Buckets);
+
+    // Register the table.
+    Table NewTable = new OnDiskTable(File, NumBucketsAndEntries.first,
+                                     NumBucketsAndEntries.second,
+                                     Buckets, Ptr, Data, std::move(InfoObj));
+    Tables.push_back(NewTable.getOpaqueValue());
+  }
+
+  /// \brief Find and read the lookup results for \p EKey.
+  data_type find(const external_key_type &EKey) {
+    data_type Result;
+
+    if (!PendingOverrides.empty())
+      removeOverriddenTables();
+
+    if (Tables.size() > Info::MaxTables)
+      condense();
+
+    internal_key_type Key = Info::GetInternalKey(EKey);
+    auto KeyHash = Info::ComputeHash(Key);
+
+    if (MergedTable *M = getMergedTable()) {
+      auto It = M->Data.find(Key);
+      if (It != M->Data.end())
+        Result = It->second;
+    }
+
+    for (auto *ODT : tables()) {
+      auto &HT = ODT->Table;
+      auto It = HT.find_hashed(Key, KeyHash);
+      if (It != HT.end())
+        HT.getInfoObj().ReadDataInto(Key, It.getDataPtr(), It.getDataLen(),
+                                     Result);
+    }
+
+    return Result;
+  }
+
+  /// \brief Read all the lookup results into a single value. This only makes
+  /// sense if merging values across keys is meaningful.
+  data_type findAll() {
+    data_type Result;
+
+    if (!PendingOverrides.empty())
+      removeOverriddenTables();
+
+    if (MergedTable *M = getMergedTable()) {
+      for (auto &KV : M->Data)
+        Info::MergeDataInto(KV.second, Result);
+    }
+
+    for (auto *ODT : tables()) {
+      auto &HT = ODT->Table;
+      Info &InfoObj = HT.getInfoObj();
+      for (auto I = HT.data_begin(), E = HT.data_end(); I != E; ++I) {
+        auto *LocalPtr = I.getItem();
+
+        // FIXME: Don't rely on the OnDiskHashTable format here.
+        auto L = InfoObj.ReadKeyDataLength(LocalPtr);
+        const internal_key_type &Key = InfoObj.ReadKey(LocalPtr, L.first);
+        InfoObj.ReadDataInto(Key, LocalPtr + L.first, L.second, Result);
+      }
+    }
+
+    return Result;
+  }
+};
+
+/// \brief Writer for the on-disk hash table.
+template<typename ReaderInfo, typename WriterInfo>
+class MultiOnDiskHashTableGenerator {
+  typedef MultiOnDiskHashTable<ReaderInfo> BaseTable;
+  typedef llvm::OnDiskChainedHashTableGenerator<WriterInfo> Generator;
+
+  Generator Gen;
+
+public:
+  MultiOnDiskHashTableGenerator() : Gen() {}
+
+  void insert(typename WriterInfo::key_type_ref Key,
+              typename WriterInfo::data_type_ref Data, WriterInfo &Info) {
+    Gen.insert(Key, Data, Info);
+  }
+
+  void emit(llvm::SmallVectorImpl<char> &Out, WriterInfo &Info,
+            const BaseTable *Base) {
+    using namespace llvm::support;
+    llvm::raw_svector_ostream OutStream(Out);
+
+    // Write our header information.
+    {
+      endian::Writer<little> Writer(OutStream);
+
+      // Reserve four bytes for the bucket offset.
+      Writer.write<uint32_t>(0);
+
+      if (auto *Merged = Base ? Base->getMergedTable() : nullptr) {
+        // Write list of overridden files.
+        Writer.write<uint32_t>(Merged->Files.size());
+        for (const auto &F : Merged->Files)
+          Info.EmitFileRef(OutStream, F);
+
+        // Add all merged entries from Base to the generator.
+        for (auto &KV : Merged->Data) {
+          if (!Gen.contains(KV.first, Info))
+            Gen.insert(KV.first, Info.ImportData(KV.second), Info);
+        }
+      } else {
+        Writer.write<uint32_t>(0);
+      }
+    }
+
+    // Write the table itself.
+    uint32_t BucketOffset = Gen.Emit(OutStream, Info);
+
+    // Replace the first four bytes with the bucket offset.
+    endian::write32le(Out.data(), BucketOffset);
+  }
+};
+
+} // end namespace clang::serialization
+} // end namespace clang
+
+
+#endif
diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp
index 8e91b8247f2101a8e521fd9a83c298747710a18a..ea6f05d3318629ddccfa527642136a403d2d32aa 100644
--- a/test/Modules/cxx-templates.cpp
+++ b/test/Modules/cxx-templates.cpp
@@ -29,14 +29,14 @@ void g() {
   f<int>();
   f(); // expected-error {{no matching function}}
   // expected-note@Inputs/cxx-templates-b.h:3 {{couldn't infer template argument}}
-  // expected-note@Inputs/cxx-templates-b.h:4 {{requires single argument}}
+  // expected-note-re@Inputs/cxx-templates-a.h:4 {{requires {{single|1}} argument}}
 
   N::f(0);
   N::f<double>(1.0);
   N::f<int>();
   N::f(); // expected-error {{no matching function}}
   // expected-note@Inputs/cxx-templates-b.h:6 {{couldn't infer template argument}}
-  // expected-note@Inputs/cxx-templates-b.h:7 {{requires single argument}}
+  // expected-note-re@Inputs/cxx-templates-a.h:7 {{requires {{single|1}} argument}}
 
   template_param_kinds_1<0>(); // ok, from cxx-templates-a.h
   template_param_kinds_1<int>(); // ok, from cxx-templates-b.h
@@ -179,10 +179,14 @@ namespace Std {
 
 // CHECK-GLOBAL:      DeclarationName 'f'
 // CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
+// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
+// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
 // CHECK-GLOBAL-NEXT: `-FunctionTemplate {{.*}} 'f'
 
 // CHECK-NAMESPACE-N:      DeclarationName 'f'
 // CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f'
+// CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f'
+// CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f'
 // CHECK-NAMESPACE-N-NEXT: `-FunctionTemplate {{.*}} 'f'
 
 // CHECK-DUMP:      ClassTemplateDecl {{.*}} <{{.*[/\\]}}cxx-templates-common.h:1:1, {{.*}}>  col:{{.*}} in cxx_templates_common SomeTemplate
diff --git a/test/Modules/merge-using-decls.cpp b/test/Modules/merge-using-decls.cpp
index 789f75b574003fd52d776a4098b240b4c192bca1..15d4af4837a869e21f2c4f23ef1955702db19f82 100644
--- a/test/Modules/merge-using-decls.cpp
+++ b/test/Modules/merge-using-decls.cpp
@@ -31,7 +31,9 @@ template int UseAll<YA>();
 template int UseAll<YB>();
 template int UseAll<Y>();
 
-#if ORDER == 1
+// Which of these two sets of diagnostics is chosen is not important. It's OK
+// if this varies with ORDER, but it must be consistent across runs.
+#if 1
 // Here, we're instantiating the definition from 'A' and merging the definition
 // from 'B' into it.