Thanks!

2015-09-01 16:24 GMT+03:00 Aaron Ballman via cfe-commits <
cfe-commits@lists.llvm.org>:

> 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@Inputs/cxx-templates-a.h:3 {{couldn't infer template
> argument}}
> -  // expected-note@Inputs/cxx-templates-a.h:4 {{requires 1 argument}}
> +  // expected-note@Inputs/cxx-templates-b.h:3 {{couldn't infer template
> argument}}
> +  // expected-note@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.
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to