From: Jonathan D. Turner Date: Tue, 26 Jul 2011 18:21:30 +0000 (+0000) Subject: This patch extends the previous patch by starting to incorporate more functionality... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=48d2c3f7c3ca48da05436afdc8426a245294ee65;p=clang This patch extends the previous patch by starting to incorporate more functionality, like lookup-by-name and exporting lookup tables, into the module manager. Methods now have documentation. A few more functions have been switched over to the new iterator style and away from manual/explicit iteration. Ultimately we want to move away from name lookup here, as symlinks make filenames not a safe unique value, but we use it here as a stopgap before better measures are in place (namely instead using FileEntry* from a global FileManager). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136107 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 34a510b0a9..a97435ba78 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -393,38 +393,59 @@ 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; + + /// \brief All loaded modules, indexed by name. + llvm::StringMap Modules; + public: typedef SmallVector::iterator ModuleIterator; typedef SmallVector::const_iterator ModuleConstIterator; typedef SmallVector::reverse_iterator ModuleReverseIterator; + typedef std::pair ModuleOffset; + ~ModuleManager(); + + /// \brief Forward iterator to traverse all loaded modules ModuleIterator begin() { return Chain.begin(); } + /// \brief Forward iterator end-point to traverse all loaded modules ModuleIterator end() { return Chain.end(); } + /// \brief Const forward iterator to traverse all loaded modules ModuleConstIterator begin() const { return Chain.begin(); } + /// \brief Const forward iterator end-point to traverse all loaded modules ModuleConstIterator end() const { return Chain.end(); } + /// \brief Reverse iterator to traverse all loaded modules ModuleReverseIterator rbegin() { return Chain.rbegin(); } + /// \brief Reverse iterator end-point to traverse all loaded modules ModuleReverseIterator rend() { return Chain.rend(); } - const std::string &getPrimaryFileName() const { return Chain[0]->FileName; } - + /// \brief Returns the primary module associated with the manager, that is, + /// the first module loaded Module &getPrimaryModule() { return *Chain[0]; } + + /// \brief Returns the primary module associated with the manager, that is, + /// the first module loaded. + Module &getPrimaryModule() const { return *Chain[0]; } + + /// \brief Returns the latest module associated with the manager, that is, + /// the last module loaded Module &getLastModule() { return *Chain.back(); } + + /// \brief Returns the module associated with the given index Module &operator[](unsigned Index) const { return *Chain[Index]; } + /// \brief Returns the module associated with the given name + Module *lookup(StringRef Name) { return Modules.lookup(Name); } + + /// \brief Number of modules loaded unsigned size() const { return Chain.size(); } - Module &addModule(ModuleKind Type) { - Module *newModule = new Module(Type); - Chain.push_back(newModule); - return *newModule; - } + /// \brief Creates a new module and adds it to the list of known modules + Module &addModule(StringRef FileName, ModuleKind Type); - ~ModuleManager() { - for (unsigned i = 0, e = Chain.size(); i != e; ++i) - delete Chain[e - i - 1]; - } + /// \brief Exports the list of loaded modules with their corresponding names + void exportLookup(SmallVector &Target); }; } // end namespace serialization @@ -497,12 +518,6 @@ private: /// \brief AST buffers for chained PCHs created and stored in memory. /// First (not depending on another) PCH in chain is in front. std::vector ASTBuffers; - - /// \brief All loaded modules, indexed by name. - llvm::StringMap Modules; - - /// \brief The first module in source order. - Module *FirstInSource; /// \brief The module manager which manages modules and their dependencies ModuleManager ModuleMgr; @@ -684,9 +699,9 @@ private: std::pair, 4> GlobalCXXBaseSpecifiersMapType; - /// \brief Mapping from global CXX base specifier IDs to the module in which the - /// CXX base specifier resides along with the offset that should be added to the - /// global CXX base specifer ID to produce a local ID. + /// \brief Mapping from global CXX base specifier IDs to the module in which + /// the CXX base specifier resides along with the offset that should be added + /// to the global CXX base specifer ID to produce a local ID. GlobalCXXBaseSpecifiersMapType GlobalCXXBaseSpecifiersMap; /// \name CodeGen-relevant special data @@ -1083,7 +1098,7 @@ public: /// \brief Retrieve the name of the named (primary) AST file const std::string &getFileName() const { - return ModuleMgr.getPrimaryFileName(); + return ModuleMgr.getPrimaryModule().FileName; } /// \brief Retrieve the name of the original source file name diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index cd4627bc99..c2901c1827 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -2381,7 +2381,7 @@ void ASTUnit::TranslateStoredDiagnostics( SmallVector Result; Result.reserve(Diags.size()); assert(MMan && "Don't have a module manager"); - serialization::Module *Mod = MMan->Modules.lookup(ModName); + serialization::Module *Mod = MMan->ModuleMgr.lookup(ModName); assert(Mod && "Don't have preamble module"); SLocRemap &Remap = Mod->SLocRemap; for (unsigned I = 0, N = Diags.size(); I != N; ++I) { diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 14ba59c1e0..3994fe6b7b 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2223,7 +2223,7 @@ ASTReader::ReadASTBlock(Module &F) { uint32_t Offset = io::ReadUnalignedLE32(Data); uint16_t Len = io::ReadUnalignedLE16(Data); StringRef Name = StringRef((const char*)Data, Len); - Module *OM = Modules.lookup(Name); + Module *OM = ModuleMgr.lookup(Name); if (!OM) { Error("SourceLocation remap refers to unknown module"); return Failure; @@ -2236,7 +2236,6 @@ ASTReader::ReadASTBlock(Module &F) { break; } - case SOURCE_MANAGER_LINE_TABLE: if (ParseLineTable(F, Record)) return Failure; @@ -2637,19 +2636,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName, ModuleKind Type) { - Module *Prev = !ModuleMgr.size() ? 0 : &ModuleMgr.getLastModule(); - ModuleMgr.addModule(Type); - Module &F = ModuleMgr.getLastModule(); - if (Prev) - Prev->NextInSource = &F; - else - FirstInSource = &F; - F.Loaders.push_back(Prev); - - Modules[FileName.str()] = &F; - - // Set the AST file name. - F.FileName = FileName; + Module &F = ModuleMgr.addModule(FileName, Type); if (FileName != "-") { CurrentDir = llvm::sys::path::parent_path(FileName); @@ -4388,7 +4375,7 @@ void ASTReader::InitializeSema(Sema &S) { SemaObj->StdBadAlloc = SemaDeclRefs[1]; } - for (Module *F = FirstInSource; F; F = F->NextInSource) { + for (Module *F = &ModuleMgr.getPrimaryModule(); F; F = F->NextInSource) { // If there are @selector references added them to its pool. This is for // implementation of -Wselector. @@ -5275,7 +5262,7 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context, : Listener(new PCHValidator(PP, *this)), DeserializationListener(0), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context), - Consumer(0), FirstInSource(0), RelocatablePCH(false), isysroot(isysroot), + Consumer(0), RelocatablePCH(false), isysroot(isysroot), DisableValidation(DisableValidation), DisableStatCache(DisableStatCache), NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0), @@ -5294,7 +5281,7 @@ ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr, Diagnostic &Diags, StringRef isysroot, bool DisableValidation, bool DisableStatCache) : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr), - Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0), FirstInSource(0), + Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0), RelocatablePCH(false), isysroot(isysroot), DisableValidation(DisableValidation), DisableStatCache(DisableStatCache), NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0), @@ -5352,3 +5339,37 @@ Module::~Module() { delete static_cast(HeaderFileInfoTable); delete static_cast(SelectorLookupTable); } + +/// \brief Creates a new module and adds it to the list of known modules +Module &ModuleManager::addModule(StringRef FileName, ModuleKind Type) { + Module *Prev = !size() ? 0 : &getLastModule(); + Module *Current = new Module(Type); + + Current->FileName = FileName.str(); + + Chain.push_back(Current); + Modules[FileName.str()] = Current; + + if (Prev) + Prev->NextInSource = Current; + Current->Loaders.push_back(Prev); + + return *Current; +} + +/// \brief Exports the list of loaded modules with their corresponding names +void ModuleManager::exportLookup(SmallVector &Target) { + Target.reserve(size()); + for (llvm::StringMap::const_iterator + I = Modules.begin(), E = Modules.end(); + I != E; ++I) { + Target.push_back(ModuleOffset(I->getValue()->SLocEntryBaseOffset, + I->getKey())); + } + std::sort(Target.begin(), Target.end()); +} + +ModuleManager::~ModuleManager() { + for (unsigned i = 0, e = Chain.size(); i != e; ++i) + delete Chain[e - i - 1]; +} diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index c94b96d18c..14824a0810 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -969,7 +969,8 @@ void ASTWriter::WriteMetadata(ASTContext &Context, StringRef isysroot, Record.push_back(CLANG_VERSION_MINOR); Record.push_back(!isysroot.empty()); // FIXME: This writes the absolute path for chained headers. - const std::string &BlobStr = Chain ? Chain->getFileName() : Target.getTriple().getTriple(); + const std::string &BlobStr = + Chain ? Chain->getFileName() : Target.getTriple().getTriple(); Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, BlobStr); // Original file name and file ID @@ -1548,14 +1549,8 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // Sorted by offset. typedef std::pair ModuleOffset; SmallVector Modules; - Modules.reserve(Chain->Modules.size()); - for (llvm::StringMap::const_iterator - I = Chain->Modules.begin(), E = Chain->Modules.end(); - I != E; ++I) { - Modules.push_back(ModuleOffset(I->getValue()->SLocEntryBaseOffset, - I->getKey())); - } - std::sort(Modules.begin(), Modules.end()); + + Chain->ModuleMgr.exportLookup(Modules); Abbrev = new BitCodeAbbrev(); Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_MAP));