summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ModuleManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization/ModuleManager.cpp')
-rw-r--r--clang/lib/Serialization/ModuleManager.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp
index 5613d372d20..ca910befcd2 100644
--- a/clang/lib/Serialization/ModuleManager.cpp
+++ b/clang/lib/Serialization/ModuleManager.cpp
@@ -135,19 +135,31 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
return NewModule? NewlyLoaded : AlreadyLoaded;
}
+static void getModuleFileAncestors(
+ ModuleFile *F,
+ llvm::SmallPtrSetImpl<ModuleFile *> &Ancestors) {
+ Ancestors.insert(F);
+ for (ModuleFile *Importer : F->ImportedBy)
+ getModuleFileAncestors(Importer, Ancestors);
+}
+
void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last,
ModuleMap *modMap) {
if (first == last)
return;
- // The first file entry is about to be rebuilt (or there was an error), so
- // there should be no references to it. Remove it from the cache to close it,
- // as Windows doesn't seem to allow renaming over an open file.
- FileMgr.invalidateCache((*first)->File);
-
// Collect the set of module file pointers that we'll be removing.
llvm::SmallPtrSet<ModuleFile *, 4> victimSet(first, last);
+ // The last module file caused the load failure, so it and its ancestors in
+ // the module dependency tree will be rebuilt (or there was an error), so
+ // there should be no references to them. Collect the files to remove from
+ // the cache below, since rebuilding them will create new files at the old
+ // locations.
+ llvm::SmallPtrSet<ModuleFile *, 4> Ancestors;
+ getModuleFileAncestors(*(last-1), Ancestors);
+ assert(Ancestors.count(*first) && "non-dependent module loaded");
+
// Remove any references to the now-destroyed modules.
for (unsigned i = 0, n = Chain.size(); i != n; ++i) {
Chain[i]->ImportedBy.remove_if([&](ModuleFile *MF) {
@@ -165,6 +177,10 @@ void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last,
mod->setASTFile(nullptr);
}
}
+
+ if (Ancestors.count(*victim))
+ FileMgr.invalidateCache((*victim)->File);
+
delete *victim;
}
OpenPOWER on IntegriCloud