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