From: Jonathan D. Turner Date: Mon, 25 Jul 2011 20:32:21 +0000 (+0000) Subject: Refactor of how modules are handled in ASTReader to remove explicit uses of a chain... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d6d89fef8c7fff8b1a67c943fb5557a2a803468;p=clang Refactor of how modules are handled in ASTReader to remove explicit uses of a chain of AST files, instead redirect calls through a module manager. This should help move toward a DAG and the potential of loading multiple, unrelated PCH files. It's still early in development. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135957 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 93bb40ed94..34a510b0a9 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -387,7 +387,46 @@ public: /// directly loaded modules. SmallVector Loaders; }; - + +/// \brief The manager for modules loaded by the ASTReader. +class ModuleManager { + /// \brief The chain of AST files. The first entry is the one named by the + /// user, the last one is the one that doesn't depend on anything further. + SmallVector Chain; +public: + typedef SmallVector::iterator ModuleIterator; + typedef SmallVector::const_iterator ModuleConstIterator; + typedef SmallVector::reverse_iterator ModuleReverseIterator; + + ModuleIterator begin() { return Chain.begin(); } + ModuleIterator end() { return Chain.end(); } + + ModuleConstIterator begin() const { return Chain.begin(); } + ModuleConstIterator end() const { return Chain.end(); } + + ModuleReverseIterator rbegin() { return Chain.rbegin(); } + ModuleReverseIterator rend() { return Chain.rend(); } + + const std::string &getPrimaryFileName() const { return Chain[0]->FileName; } + + Module &getPrimaryModule() { return *Chain[0]; } + Module &getLastModule() { return *Chain.back(); } + Module &operator[](unsigned Index) const { return *Chain[Index]; } + + unsigned size() const { return Chain.size(); } + + Module &addModule(ModuleKind Type) { + Module *newModule = new Module(Type); + Chain.push_back(newModule); + return *newModule; + } + + ~ModuleManager() { + for (unsigned i = 0, e = Chain.size(); i != e; ++i) + delete Chain[e - i - 1]; + } +}; + } // end namespace serialization /// \brief Reads an AST files chain containing the contents of a translation @@ -425,7 +464,12 @@ public: typedef serialization::Module Module; typedef serialization::ModuleKind ModuleKind; + typedef serialization::ModuleManager ModuleManager; + typedef ModuleManager::ModuleIterator ModuleIterator; + typedef ModuleManager::ModuleConstIterator ModuleConstIterator; + typedef ModuleManager::ModuleReverseIterator ModuleReverseIterator; + private: /// \brief The receiver of some callbacks invoked by ASTReader. llvm::OwningPtr Listener; @@ -460,10 +504,8 @@ private: /// \brief The first module in source order. Module *FirstInSource; - /// \brief The chain of AST files. The first entry is the one named by the - /// user, the last one is the one that doesn't depend on anything further. - /// That is, the entry I was created with -include-pch I+1. - SmallVector Chain; + /// \brief The module manager which manages modules and their dependencies + ModuleManager ModuleMgr; /// \brief A map of global bit offsets to the module that stores entities /// at those bit offsets. @@ -1040,7 +1082,9 @@ public: } /// \brief Retrieve the name of the named (primary) AST file - const std::string &getFileName() const { return Chain[0]->FileName; } + const std::string &getFileName() const { + return ModuleMgr.getPrimaryFileName(); + } /// \brief Retrieve the name of the original source file name const std::string &getOriginalSourceFile() { return OriginalFileName; } @@ -1096,8 +1140,10 @@ public: /// reader. unsigned getTotalNumPreprocessedEntities() const { unsigned Result = 0; - for (unsigned I = 0, N = Chain.size(); I != N; ++I) - Result += Chain[I]->NumPreallocatedPreprocessingEntities; + for (ModuleConstIterator I = ModuleMgr.begin(), + E = ModuleMgr.end(); I != E; ++I) { + Result += (*I)->NumPreallocatedPreprocessingEntities; + } return Result; } diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 627a394561..8b4167d401 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1740,16 +1740,16 @@ void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, Module &F, } void ASTReader::ReadDefinedMacros() { - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - Module &F = *Chain[N - I - 1]; - llvm::BitstreamCursor &MacroCursor = F.MacroCursor; + for (ModuleReverseIterator I = ModuleMgr.rbegin(), + E = ModuleMgr.rend(); I != E; ++I) { + llvm::BitstreamCursor &MacroCursor = (*I)->MacroCursor; // If there was no preprocessor block, skip this file. if (!MacroCursor.getBitStreamReader()) continue; llvm::BitstreamCursor Cursor = MacroCursor; - Cursor.JumpToBit(F.MacroStartOffset); + Cursor.JumpToBit((*I)->MacroStartOffset); RecordData Record; while (true) { @@ -2465,8 +2465,9 @@ ASTReader::ReadASTBlock(Module &F) { } ASTReader::ASTReadResult ASTReader::validateFileEntries() { - for (unsigned CI = 0, CN = Chain.size(); CI != CN; ++CI) { - Module *F = Chain[CI]; + for (ModuleIterator I = ModuleMgr.begin(), + E = ModuleMgr.end(); I != E; ++I) { + Module *F = *I; llvm::BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor; for (unsigned i = 0, e = F->LocalNumSLocFileEntries; i != e; ++i) { @@ -2582,9 +2583,10 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, Id != IdEnd; ++Id) Identifiers.push_back(Id->second); // We need to search the tables in all files. - for (unsigned J = 0, M = Chain.size(); J != M; ++J) { + for (ModuleIterator J = ModuleMgr.begin(), + M = ModuleMgr.end(); J != M; ++J) { ASTIdentifierLookupTable *IdTable - = (ASTIdentifierLookupTable *)Chain[J]->IdentifierLookupTable; + = (ASTIdentifierLookupTable *)(*J)->IdentifierLookupTable; // Not all AST files necessarily have identifier tables, only the useful // ones. if (!IdTable) @@ -2592,7 +2594,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) { IdentifierInfo *II = Identifiers[I]; // Look in the on-disk hash tables for an entry for this identifier - ASTIdentifierLookupTrait Info(*this, *Chain[J], II); + ASTIdentifierLookupTrait Info(*this, *(*J), II); std::pair Key(II->getNameStart(),II->getLength()); ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info); if (Pos == IdTable->end()) @@ -2622,7 +2624,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, OriginalFileID = SourceMgr.getDecomposedLoc(Loc).first; } else { - OriginalFileID = FileID::get(Chain[0]->SLocEntryBaseID + OriginalFileID = FileID::get(ModuleMgr.getPrimaryModule().SLocEntryBaseID + OriginalFileID.getOpaqueValue() - 1); } @@ -2635,9 +2637,9 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName, ModuleKind Type) { - Module *Prev = Chain.empty() ? 0 : Chain.back(); - Chain.push_back(new Module(Type)); - Module &F = *Chain.back(); + Module *Prev = !ModuleMgr.size() ? 0 : &ModuleMgr.getLastModule(); + ModuleMgr.addModule(Type); + Module &F = ModuleMgr.getLastModule(); if (Prev) Prev->NextInSource = &F; else @@ -3060,12 +3062,12 @@ bool ASTReader::ParseLanguageOptions( } void ASTReader::ReadPreprocessedEntities() { - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - Module &F = *Chain[I]; + for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) { + Module &F = *(*I); if (!F.PreprocessorDetailCursor.getBitStreamReader()) continue; - SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor); + SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor); F.PreprocessorDetailCursor.JumpToBit(F.PreprocessorDetailStartOffset); while (LoadPreprocessedEntity(F)) { } } @@ -3083,8 +3085,8 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntityAtOffset(uint64_t Offset) { HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) { HeaderFileInfoTrait Trait(FE->getName()); - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - Module &F = *Chain[I]; + for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) { + Module &F = *(*I); HeaderFileInfoLookupTable *Table = static_cast(F.HeaderFileInfoTable); if (!Table) @@ -3107,8 +3109,8 @@ HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) { } void ASTReader::ReadPragmaDiagnosticMappings(Diagnostic &Diag) { - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - Module &F = *Chain[I]; + for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) { + Module &F = *(*I); unsigned Idx = 0; while (Idx < F.PragmaDiagMappings.size()) { SourceLocation Loc = ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]); @@ -4304,8 +4306,9 @@ void ASTReader::dump() { /// Return the amount of memory used by memory buffers, breaking down /// by heap-backed versus mmap'ed memory. void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const { - for (unsigned i = 0, e = Chain.size(); i != e; ++i) - if (llvm::MemoryBuffer *buf = Chain[i]->Buffer.get()) { + for (ModuleConstIterator I = ModuleMgr.begin(), + E = ModuleMgr.end(); I != E; ++I) { + if (llvm::MemoryBuffer *buf = (*I)->Buffer.get()) { size_t bytes = buf->getBufferSize(); switch (buf->getBufferKind()) { case llvm::MemoryBuffer::MemoryBuffer_Malloc: @@ -4316,6 +4319,7 @@ void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const { break; } } + } } void ASTReader::InitializeSema(Sema &S) { @@ -4402,7 +4406,7 @@ void ASTReader::InitializeSema(Sema &S) { // The special data sets below always come from the most recent PCH, // which is at the front of the chain. - Module &F = *Chain.front(); + Module &F = ModuleMgr.getPrimaryModule(); // If there were any pending implicit instantiations, deserialize them // and add them to Sema's queue of such instantiations. @@ -4459,9 +4463,9 @@ void ASTReader::InitializeSema(Sema &S) { IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) { // Try to find this name within our on-disk hash tables. We start with the // most recent one, since that one contains the most up-to-date info. - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) { ASTIdentifierLookupTable *IdTable - = (ASTIdentifierLookupTable *)Chain[I]->IdentifierLookupTable; + = (ASTIdentifierLookupTable *)(*I)->IdentifierLookupTable; if (!IdTable) continue; std::pair Key(NameStart, NameEnd - NameStart); @@ -4504,9 +4508,9 @@ namespace clang { } ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader) - : Reader(Reader), Index(Reader.Chain.size() - 1) { + : Reader(Reader), Index(Reader.ModuleMgr.size() - 1) { ASTIdentifierLookupTable *IdTable - = (ASTIdentifierLookupTable *)Reader.Chain[Index]->IdentifierLookupTable; + = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].IdentifierLookupTable; Current = IdTable->key_begin(); End = IdTable->key_end(); } @@ -4519,7 +4523,8 @@ StringRef ASTIdentifierIterator::Next() { --Index; ASTIdentifierLookupTable *IdTable - = (ASTIdentifierLookupTable *)Reader.Chain[Index]->IdentifierLookupTable; + = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index]. + IdentifierLookupTable; Current = IdTable->key_begin(); End = IdTable->key_end(); } @@ -4538,8 +4543,8 @@ IdentifierIterator *ASTReader::getIdentifiers() const { std::pair ASTReader::ReadMethodPool(Selector Sel) { // Find this selector in a hash table. We want to find the most recent entry. - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - Module &F = *Chain[I]; + for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) { + Module &F = *(*I); if (!F.SelectorLookupTable) continue; @@ -5305,8 +5310,6 @@ ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr, } ASTReader::~ASTReader() { - for (unsigned i = 0, e = Chain.size(); i != e; ++i) - delete Chain[e - i - 1]; // Delete all visible decl lookup tables for (DeclContextOffsetsMap::iterator I = DeclContextOffsets.begin(), E = DeclContextOffsets.end();