r246546 - Reverting r246497 (which requires also reverting r246524 and r246521 to avoid merge conflicts). It broke the build on MSVC 2015. It also broke an MSVC 2013 bot with testing issues.

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 1 06:24:40 PDT 2015


Author: aaronballman
Date: Tue Sep  1 08:24:39 2015
New Revision: 246546

URL: http://llvm.org/viewvc/llvm-project?rev=246546&view=rev
Log:
Reverting r246497 (which requires also reverting r246524 and r246521 to avoid merge conflicts). It broke the build on MSVC 2015. It also broke an MSVC 2013 bot with testing issues.

llvm\tools\clang\lib\serialization\MultiOnDiskHashTable.h(117):
error C2065: 'Files': undeclared identifier

http://bb.pgr.jp/builders/ninja-clang-i686-msc18-R/builds/2917

Removed:
    cfe/trunk/lib/Serialization/MultiOnDiskHashTable.h
Modified:
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/include/clang/Serialization/Module.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTReaderInternals.h
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/lib/Serialization/Module.cpp
    cfe/trunk/test/Modules/cxx-templates.cpp
    cfe/trunk/test/Modules/merge-using-decls.cpp

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Sep  1 08:24:39 2015
@@ -1530,23 +1530,4 @@ 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

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Tue Sep  1 08:24:39 2015
@@ -282,8 +282,9 @@ class ReadMethodPoolVisitor;
 
 namespace reader {
   class ASTIdentifierLookupTrait;
-  /// \brief The on-disk hash table(s) used for DeclContext name lookup.
-  struct DeclContextLookupTable;
+  /// \brief The on-disk hash table used for the DeclContext's Name lookup table.
+  typedef llvm::OnDiskIterableChainedHashTable<ASTDeclContextNameLookupTrait>
+    ASTDeclContextNameLookupTable;
 }
 
 } // end namespace serialization
@@ -506,10 +507,6 @@ 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
@@ -517,6 +514,7 @@ private:
   struct PendingVisibleUpdate {
     ModuleFile *Mod;
     const unsigned char *Data;
+    unsigned BucketOffset;
   };
   typedef SmallVector<PendingVisibleUpdate, 1> DeclContextVisibleUpdates;
 
@@ -1091,10 +1089,6 @@ 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;
@@ -1876,13 +1870,6 @@ 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.

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Tue Sep  1 08:24:39 2015
@@ -529,8 +529,8 @@ private:
   bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
   bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC);
 
-  void GenerateNameLookupTable(const DeclContext *DC,
-                               llvm::SmallVectorImpl<char> &LookupTable);
+  uint32_t 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,7 +849,6 @@ public:
   unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; }
 
   bool hasChain() const { return Chain; }
-  ASTReader *getChain() const { return Chain; }
 
   // ASTDeserializationListener implementation
   void ReaderInitialized(ASTReader *Reader) override;

Modified: cfe/trunk/include/clang/Serialization/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/Module.h (original)
+++ cfe/trunk/include/clang/Serialization/Module.h Tue Sep  1 08:24:39 2015
@@ -50,6 +50,14 @@ 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.
@@ -408,6 +416,13 @@ 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;

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Sep  1 08:24:39 2015
@@ -20,7 +20,6 @@
 #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"
@@ -904,13 +903,6 @@ unsigned DeclarationNameKey::getHash() c
   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;
@@ -956,15 +948,15 @@ ASTDeclContextNameLookupTrait::ReadKey(c
   return DeclarationNameKey(Kind, Data);
 }
 
-void ASTDeclContextNameLookupTrait::ReadDataInto(internal_key_type,
-                                                 const unsigned char *d,
-                                                 unsigned DataLen,
-                                                 data_type_builder &Val) {
+ASTDeclContextNameLookupTrait::data_type
+ASTDeclContextNameLookupTrait::ReadData(internal_key_type,
+                                        const unsigned char *d,
+                                        unsigned DataLen) {
   using namespace llvm::support;
-  for (unsigned NumDecls = DataLen / 4; NumDecls; --NumDecls) {
-    uint32_t LocalID = endian::readNext<uint32_t, little, unaligned>(d);
-    Val.insert(Reader.getGlobalDeclID(F, LocalID));
-  }
+  unsigned NumDecls = DataLen / 4;
+  LE32DeclID *Start = reinterpret_cast<LE32DeclID *>(
+                        const_cast<unsigned char *>(d));
+  return std::make_pair(Start, Start + NumDecls);
 }
 
 bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
@@ -1023,8 +1015,9 @@ bool ASTReader::ReadVisibleDeclContextSt
 
   // We can't safely determine the primary context yet, so delay attaching the
   // lookup table until we're done with recursive deserialization.
-  auto *Data = (const unsigned char*)Blob.data();
-  PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&M, Data});
+  unsigned BucketOffset = Record[0];
+  PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{
+      &M, (const unsigned char *)Blob.data(), BucketOffset});
   return false;
 }
 
@@ -2559,7 +2552,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, u
       unsigned Idx = 0;
       serialization::DeclID ID = ReadDeclID(F, Record, Idx);
       auto *Data = (const unsigned char*)Blob.data();
-      PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&F, Data});
+      unsigned BucketOffset = Record[Idx++];
+      PendingVisibleUpdates[ID].push_back(
+          PendingVisibleUpdate{&F, Data, BucketOffset});
       // If we've already loaded the decl, perform the updates when we finish
       // loading this block.
       if (Decl *D = GetExistingDecl(ID))
@@ -6360,48 +6355,196 @@ void ASTReader::FindFileRegionDecls(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() && DC == DC->getPrimaryContext() &&
+  assert(DC->hasExternalVisibleStorage() &&
          "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;
-  for (DeclID ID : It->second.Table.find(Name)) {
-    NamedDecl *ND = cast<NamedDecl>(GetDecl(ID));
-    if (ND->getDeclName() == Name)
-      Decls.push_back(ND);
-  }
+  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);
 
   ++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;
-
-  auto It = Lookups.find(DC);
-  assert(It != Lookups.end() &&
-         "have external visible storage but no lookup tables");
-
   DeclsMap Decls;
 
-  for (DeclID ID : It->second.Table.findAll()) {
-    NamedDecl *ND = cast<NamedDecl>(GetDecl(ID));
-    Decls[ND->getDeclName()].push_back(ND);
+  // 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);
+
+  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])));
+    }
   }
 
+  DeclContextAllNamesVisitor Visitor(*this, Contexts, Decls,
+                                     /*VisitAll=*/DC->isFileContext());
+  ModuleMgr.visit(Visitor);
   ++NumVisibleDeclContextsRead;
 
   for (DeclsMap::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
@@ -6410,12 +6553,6 @@ void ASTReader::completeVisibleDeclsMap(
   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
@@ -7247,36 +7384,6 @@ 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())
-    return ((F->BaseSubmoduleID + NUM_PREDEF_SUBMODULE_IDS) << 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;
@@ -8325,8 +8432,6 @@ 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);
       }

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Sep  1 08:24:39 2015
@@ -1489,8 +1489,6 @@ 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);
@@ -3348,10 +3346,15 @@ void ASTReader::loadDeclUpdateRecords(se
     PendingVisibleUpdates.erase(I);
 
     auto *DC = cast<DeclContext>(D)->getPrimaryContext();
-    for (const PendingVisibleUpdate &Update : VisibleUpdates)
-      Lookups[DC].Table.add(
-          Update.Mod, Update.Data,
+    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,
           reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod));
+    }
     DC->setHasExternalVisibleStorage(true);
   }
 

Modified: cfe/trunk/lib/Serialization/ASTReaderInternals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderInternals.h?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderInternals.h (original)
+++ cfe/trunk/lib/Serialization/ASTReaderInternals.h Tue Sep  1 08:24:39 2015
@@ -15,12 +15,8 @@
 
 #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 {
@@ -43,38 +39,14 @@ class ASTDeclContextNameLookupTrait {
   ModuleFile &F;
   
 public:
-  // 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.
-  typedef llvm::SmallVector<DeclID, 4> data_type;
-  struct data_type_builder {
-    data_type &Data;
-    llvm::DenseSet<DeclID> Found;
-
-    data_type_builder(data_type &D) : Data(D) {}
-    void insert(DeclID ID) {
-      // Just use a linear scan unless we have more than a few IDs.
-      if (Found.empty() && !Data.empty()) {
-        if (Data.size() <= 4) {
-          for (auto I : Found)
-            if (I == ID)
-              return;
-          Data.push_back(ID);
-          return;
-        }
-
-        // Switch to tracking found IDs in the set.
-        Found.insert(Data.begin(), Data.end());
-      }
-
-      if (Found.insert(ID).second)
-        Data.push_back(ID);
-    }
-  };
+  /// \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;
   typedef unsigned hash_value_type;
   typedef unsigned offset_type;
-  typedef ModuleFile *file_type;
 
   typedef DeclarationName external_key_type;
   typedef DeclarationNameKey internal_key_type;
@@ -82,7 +54,8 @@ 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;
   }
 
@@ -98,20 +71,8 @@ public:
 
   internal_key_type ReadKey(const unsigned char *d, unsigned);
 
-  void ReadDataInto(internal_key_type, const unsigned char *d,
-                    unsigned DataLen, data_type_builder &Val);
-
-  static void MergeDataInto(const data_type &From, data_type_builder &To) {
-    To.Data.reserve(To.Data.size() + From.size());
-    for (DeclID ID : From)
-      To.insert(ID);
-  }
-
-  file_type ReadFileRef(const unsigned char *&d);
-};
-
-struct DeclContextLookupTable {
-  MultiOnDiskHashTable<ASTDeclContextNameLookupTrait> Table;
+  data_type ReadData(internal_key_type, const unsigned char *d,
+                     unsigned DataLen);
 };
 
 /// \brief Base class for the trait describing the on-disk hash table for the

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Sep  1 08:24:39 2015
@@ -13,8 +13,6 @@
 
 #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"
@@ -3379,14 +3377,12 @@ 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;
 
-  /// A start and end index into DeclIDs, representing a sequence of decls.
-  typedef std::pair<unsigned, unsigned> data_type;
+  typedef DeclContext::lookup_result data_type;
   typedef const data_type& data_type_ref;
 
   typedef unsigned hash_value_type;
@@ -3394,40 +3390,10 @@ 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) {
@@ -3454,9 +3420,7 @@ public:
     LE.write<uint16_t>(KeyLen);
 
     // 4 bytes for each DeclID.
-    unsigned DataLen = 4 * (Lookup.second - Lookup.first);
-    assert(uint16_t(DataLen) == DataLen &&
-           "too many decls for serialized lookup result");
+    unsigned DataLen = 4 * Lookup.size();
     LE.write<uint16_t>(DataLen);
 
     return std::make_pair(KeyLen, DataLen);
@@ -3496,8 +3460,11 @@ public:
     using namespace llvm::support;
     endian::Writer<little> LE(Out);
     uint64_t Start = Out.tell(); (void)Start;
-    for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
-      LE.write<uint32_t>(DeclIDs[I]);
+    for (DeclContext::lookup_iterator I = Lookup.begin(), E = Lookup.end();
+         I != E; ++I)
+      LE.write<uint32_t>(
+          Writer.GetDeclRef(getDeclForLocalLookup(Writer.getLangOpts(), *I)));
+
     assert(Out.tell() - Start == DataLen && "Data length is wrong");
   }
 };
@@ -3517,7 +3484,7 @@ bool ASTWriter::isLookupResultEntirelyEx
   return true;
 }
 
-void
+uint32_t
 ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
                                    llvm::SmallVectorImpl<char> &LookupTable) {
   assert(!ConstDC->HasLazyLocalLexicalLookups &&
@@ -3529,8 +3496,8 @@ ASTWriter::GenerateNameLookupTable(const
   assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table");
 
   // Create the on-disk hash table representation.
-  MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
-                                ASTDeclContextNameLookupTrait> Generator;
+  llvm::OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait>
+      Generator;
   ASTDeclContextNameLookupTrait Trait(*this);
 
   // The first step is to collect the declaration names which we need to
@@ -3665,7 +3632,7 @@ ASTWriter::GenerateNameLookupTable(const
 
     switch (Name.getNameKind()) {
     default:
-      Generator.insert(Name, Trait.getData(Result), Trait);
+      Generator.insert(Name, Result, Trait);
       break;
 
     case DeclarationName::CXXConstructorName:
@@ -3683,15 +3650,17 @@ ASTWriter::GenerateNameLookupTable(const
   // the key, only the kind of name is used.
   if (!ConstructorDecls.empty())
     Generator.insert(ConstructorDecls.front()->getDeclName(),
-                     Trait.getData(ConstructorDecls), Trait);
+                     DeclContext::lookup_result(ConstructorDecls), Trait);
   if (!ConversionDecls.empty())
     Generator.insert(ConversionDecls.front()->getDeclName(),
-                     Trait.getData(ConversionDecls), Trait);
+                     DeclContext::lookup_result(ConversionDecls), 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);
+  // 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);
 }
 
 /// \brief Write the block containing all of the declaration IDs
@@ -3774,11 +3743,12 @@ uint64_t ASTWriter::WriteDeclContextVisi
 
   // Create the on-disk hash table in a buffer.
   SmallString<4096> LookupTable;
-  GenerateNameLookupTable(DC, LookupTable);
+  uint32_t BucketOffset = 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;
@@ -3801,7 +3771,7 @@ void ASTWriter::WriteDeclContextVisibleU
 
   // Create the on-disk hash table in a buffer.
   SmallString<4096> LookupTable;
-  GenerateNameLookupTable(DC, LookupTable);
+  uint32_t BucketOffset = 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.
@@ -3812,6 +3782,7 @@ void ASTWriter::WriteDeclContextVisibleU
   RecordData Record;
   Record.push_back(UPDATE_VISIBLE);
   Record.push_back(getDeclID(cast<Decl>(DC)));
+  Record.push_back(BucketOffset);
   Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
 }
 
@@ -4275,6 +4246,7 @@ void ASTWriter::WriteASTCore(Sema &SemaR
   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);

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Tue Sep  1 08:24:39 2015
@@ -2049,6 +2049,7 @@ 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);
 }

Modified: cfe/trunk/lib/Serialization/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/Module.cpp?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/Module.cpp (original)
+++ cfe/trunk/lib/Serialization/Module.cpp Tue Sep  1 08:24:39 2015
@@ -45,6 +45,13 @@ ModuleFile::ModuleFile(ModuleKind Kind,
 {}
 
 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);

Removed: cfe/trunk/lib/Serialization/MultiOnDiskHashTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/MultiOnDiskHashTable.h?rev=246545&view=auto
==============================================================================
--- cfe/trunk/lib/Serialization/MultiOnDiskHashTable.h (original)
+++ cfe/trunk/lib/Serialization/MultiOnDiskHashTable.h (removed)
@@ -1,323 +0,0 @@
-//===--- 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 typename Info::data_type_builder data_type_builder;
-  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);
-        data_type_builder ValueBuilder(Merged->Data[Key]);
-        InfoObj.ReadDataInto(Key, LocalPtr + L.first, L.second,
-                             ValueBuilder);
-      }
-
-      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;
-    }
-
-    data_type_builder ResultBuilder(Result);
-
-    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(),
-                                     ResultBuilder);
-    }
-
-    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;
-    data_type_builder ResultBuilder(Result);
-
-    if (!PendingOverrides.empty())
-      removeOverriddenTables();
-
-    if (MergedTable *M = getMergedTable()) {
-      for (auto &KV : M->Data)
-        Info::MergeDataInto(KV.second, ResultBuilder);
-    }
-
-    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, ResultBuilder);
-      }
-    }
-
-    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

Modified: cfe/trunk/test/Modules/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-templates.cpp?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cxx-templates.cpp (original)
+++ cfe/trunk/test/Modules/cxx-templates.cpp Tue Sep  1 08:24:39 2015
@@ -28,8 +28,8 @@ void g() {
   f<double>(1.0);
   f<int>();
   f(); // expected-error {{no matching function}}
-  // expected-note at Inputs/cxx-templates-a.h:3 {{couldn't infer template argument}}
-  // expected-note at Inputs/cxx-templates-a.h:4 {{requires 1 argument}}
+  // expected-note at Inputs/cxx-templates-b.h:3 {{couldn't infer template argument}}
+  // expected-note at Inputs/cxx-templates-b.h:4 {{requires single argument}}
 
   N::f(0);
   N::f<double>(1.0);
@@ -179,14 +179,10 @@ 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

Modified: cfe/trunk/test/Modules/merge-using-decls.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/merge-using-decls.cpp?rev=246546&r1=246545&r2=246546&view=diff
==============================================================================
--- cfe/trunk/test/Modules/merge-using-decls.cpp (original)
+++ cfe/trunk/test/Modules/merge-using-decls.cpp Tue Sep  1 08:24:39 2015
@@ -31,8 +31,6 @@ template int UseAll<YA>();
 template int UseAll<YB>();
 template int UseAll<Y>();
 
-// 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 ORDER == 1
 // Here, we're instantiating the definition from 'A' and merging the definition
 // from 'B' into it.




More information about the cfe-commits mailing list