summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ModuleManager.cpp
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-05-30 21:20:54 +0000
committerBen Langmuir <blangmuir@apple.com>2014-05-30 21:20:54 +0000
commit4f05478c9729a00e61757b7842099f0e1db988e8 (patch)
tree42d87bebe435ab4c5b4b1c63e49061f82a16d862 /clang/lib/Serialization/ModuleManager.cpp
parent357e5e9cafbd2ea7999415067df42e85938c80c7 (diff)
downloadbcm5719-llvm-4f05478c9729a00e61757b7842099f0e1db988e8.tar.gz
bcm5719-llvm-4f05478c9729a00e61757b7842099f0e1db988e8.zip
Invalidate the file system cache entries for files that may rebuild
This reapplies r209910 with a fix for the assertion failures hit on the buildbots. original commit message: I thought we could get away without this, but it means that the FileEntry objects actually refer to the wrong files, since pcms are not updated inplace, they are atomically renamed into place after compiling a module. So we are close to the original behaviour of invalidating the cache for all modules being removed, but now we should only invalidate the ones that depend on whichever module failed to load. Unfortunately I haven't come up with a new test that didn't require a race between parallel invocations of clang. <rdar://problem/17038180> llvm-svn: 209922
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