summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp122
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,
OpenPOWER on IntegriCloud