diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp | 122 |
1 files changed, 28 insertions, 94 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp b/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp index 2716194..74f75a1 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp @@ -95,6 +95,8 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, New->File = Entry; New->ImportLoc = ImportLoc; Chain.push_back(New); + if (!New->isModule()) + PCHChain.push_back(New); if (!ImportedBy) Roots.push_back(New); NewModule = true; @@ -159,6 +161,8 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, Modules.erase(Entry); assert(Chain.back() == ModuleEntry); Chain.pop_back(); + if (!ModuleEntry->isModule()) + PCHChain.pop_back(); if (Roots.back() == ModuleEntry) Roots.pop_back(); else @@ -190,6 +194,9 @@ void ModuleManager::removeModules( if (first == last) return; + // Explicitly clear VisitOrder since we might not notice it is stale. + VisitOrder.clear(); + // Collect the set of module file pointers that we'll be removing. llvm::SmallPtrSet<ModuleFile *, 4> victimSet(first, last); @@ -203,6 +210,15 @@ void ModuleManager::removeModules( Roots.erase(std::remove_if(Roots.begin(), Roots.end(), IsVictim), Roots.end()); + // Remove the modules from the PCH chain. + for (auto I = first; I != last; ++I) { + if (!(*I)->isModule()) { + PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), *I), + PCHChain.end()); + break; + } + } + // Delete the modules and erase them from the various structures. for (ModuleIterator victim = first; victim != last; ++victim) { Modules.erase((*victim)->File); @@ -236,15 +252,6 @@ ModuleManager::addInMemoryBuffer(StringRef FileName, InMemoryBuffers[Entry] = std::move(Buffer); } -bool ModuleManager::addKnownModuleFile(StringRef FileName) { - const FileEntry *File; - if (lookupModuleFile(FileName, 0, 0, File)) - return true; - if (!Modules.count(File)) - AdditionalKnownModuleFiles.insert(File); - return false; -} - ModuleManager::VisitState *ModuleManager::allocateVisitState() { // Fast path: if we have a cached state, use it. if (FirstVisitState) { @@ -281,8 +288,6 @@ void ModuleManager::setGlobalIndex(GlobalModuleIndex *Index) { } void ModuleManager::moduleFileAccepted(ModuleFile *MF) { - AdditionalKnownModuleFiles.remove(MF->File); - if (!GlobalIndex || GlobalIndex->loadedModuleFile(MF)) return; @@ -300,10 +305,8 @@ ModuleManager::~ModuleManager() { delete FirstVisitState; } -void -ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), - void *UserData, - llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) { +void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor, + llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) { // If the visitation order vector is the wrong size, recompute the order. if (VisitOrder.size() != Chain.size()) { unsigned N = size(); @@ -316,28 +319,24 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), SmallVector<ModuleFile *, 4> Queue; Queue.reserve(N); llvm::SmallVector<unsigned, 4> UnusedIncomingEdges; - UnusedIncomingEdges.reserve(size()); - for (ModuleIterator M = begin(), MEnd = end(); M != MEnd; ++M) { - if (unsigned Size = (*M)->ImportedBy.size()) - UnusedIncomingEdges.push_back(Size); - else { - UnusedIncomingEdges.push_back(0); + UnusedIncomingEdges.resize(size()); + for (auto M = rbegin(), MEnd = rend(); M != MEnd; ++M) { + unsigned Size = (*M)->ImportedBy.size(); + UnusedIncomingEdges[(*M)->Index] = Size; + if (!Size) Queue.push_back(*M); - } } // Traverse the graph, making sure to visit a module before visiting any // of its dependencies. - unsigned QueueStart = 0; - while (QueueStart < Queue.size()) { - ModuleFile *CurrentModule = Queue[QueueStart++]; + while (!Queue.empty()) { + ModuleFile *CurrentModule = Queue.pop_back_val(); VisitOrder.push_back(CurrentModule); // For any module that this module depends on, push it on the // stack (if it hasn't already been marked as visited). - for (llvm::SetVector<ModuleFile *>::iterator - M = CurrentModule->Imports.begin(), - MEnd = CurrentModule->Imports.end(); + for (auto M = CurrentModule->Imports.rbegin(), + MEnd = CurrentModule->Imports.rend(); M != MEnd; ++M) { // Remove our current module as an impediment to visiting the // module we depend on. If we were the last unvisited module @@ -379,7 +378,7 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), // Visit the module. assert(State->VisitNumber[CurrentModule->Index] == VisitNumber - 1); State->VisitNumber[CurrentModule->Index] = VisitNumber; - if (!Visitor(*CurrentModule, UserData)) + if (!Visitor(*CurrentModule)) continue; // The visitor has requested that cut off visitation of any @@ -410,71 +409,6 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), returnVisitState(State); } -static void markVisitedDepthFirst(ModuleFile &M, - SmallVectorImpl<bool> &Visited) { - for (llvm::SetVector<ModuleFile *>::iterator IM = M.Imports.begin(), - IMEnd = M.Imports.end(); - IM != IMEnd; ++IM) { - if (Visited[(*IM)->Index]) - continue; - Visited[(*IM)->Index] = true; - if (!M.DirectlyImported) - markVisitedDepthFirst(**IM, Visited); - } -} - -/// \brief Perform a depth-first visit of the current module. -static bool visitDepthFirst( - ModuleFile &M, - ModuleManager::DFSPreorderControl (*PreorderVisitor)(ModuleFile &M, - void *UserData), - bool (*PostorderVisitor)(ModuleFile &M, void *UserData), void *UserData, - SmallVectorImpl<bool> &Visited) { - if (PreorderVisitor) { - switch (PreorderVisitor(M, UserData)) { - case ModuleManager::Abort: - return true; - case ModuleManager::SkipImports: - markVisitedDepthFirst(M, Visited); - return false; - case ModuleManager::Continue: - break; - } - } - - // Visit children - for (llvm::SetVector<ModuleFile *>::iterator IM = M.Imports.begin(), - IMEnd = M.Imports.end(); - IM != IMEnd; ++IM) { - if (Visited[(*IM)->Index]) - continue; - Visited[(*IM)->Index] = true; - - if (visitDepthFirst(**IM, PreorderVisitor, PostorderVisitor, UserData, Visited)) - return true; - } - - if (PostorderVisitor) - return PostorderVisitor(M, UserData); - - return false; -} - -void ModuleManager::visitDepthFirst( - ModuleManager::DFSPreorderControl (*PreorderVisitor)(ModuleFile &M, - void *UserData), - bool (*PostorderVisitor)(ModuleFile &M, void *UserData), void *UserData) { - SmallVector<bool, 16> Visited(size(), false); - for (unsigned I = 0, N = Roots.size(); I != N; ++I) { - if (Visited[Roots[I]->Index]) - continue; - Visited[Roots[I]->Index] = true; - - if (::visitDepthFirst(*Roots[I], PreorderVisitor, PostorderVisitor, UserData, Visited)) - return; - } -} - bool ModuleManager::lookupModuleFile(StringRef FileName, off_t ExpectedSize, time_t ExpectedModTime, |