summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ModuleManager.cpp
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-06-20 00:24:56 +0000
committerBen Langmuir <blangmuir@apple.com>2014-06-20 00:24:56 +0000
commit9801b253ad3be9d9151e78e738115fa7725db7ff (patch)
tree40c20e00bcd7930f74093dce2a82fbea5396516b /clang/lib/Serialization/ModuleManager.cpp
parent577508df831184a5123aaa6a6cb510becdcd3440 (diff)
downloadbcm5719-llvm-9801b253ad3be9d9151e78e738115fa7725db7ff.tar.gz
bcm5719-llvm-9801b253ad3be9d9151e78e738115fa7725db7ff.zip
Avoid invalidating successfully loaded module files
Successfully loaded module files may be referenced in other ModuleManagers, so don't invalidate them. Two related things are fixed: 1) I thought the last module in the manager was always the one that failed, but it isn't. So check explicitly against the list of vetted modules from ReadASTCore. 2) We now keep the file descriptor of pcm file open, which avoids the possibility of having two different pcms for the same module loaded when building in parallel with headers being modified during a build. <rdar://problem/16835846> llvm-svn: 211330
Diffstat (limited to 'clang/lib/Serialization/ModuleManager.cpp')
-rw-r--r--clang/lib/Serialization/ModuleManager.cpp39
1 files changed, 17 insertions, 22 deletions
diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp
index c5b4dd120cb..0a9ea69d695 100644
--- a/clang/lib/Serialization/ModuleManager.cpp
+++ b/clang/lib/Serialization/ModuleManager.cpp
@@ -109,8 +109,15 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
ec = llvm::MemoryBuffer::getSTDIN(New->Buffer);
if (ec)
ErrorStr = ec.message();
- } else
- New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr));
+ } else {
+ // Leave the FileEntry open so if it gets read again by another
+ // ModuleManager it must be the same underlying file.
+ // FIXME: Because FileManager::getFile() doesn't guarantee that it will
+ // give us an open file, this may not be 100% reliable.
+ New->Buffer.reset(FileMgr.getBufferForFile(New->File, &ErrorStr,
+ /*IsVolatile*/false,
+ /*ShouldClose*/false));
+ }
if (!New->Buffer)
return Missing;
@@ -135,31 +142,16 @@ 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) {
+void ModuleManager::removeModules(
+ ModuleIterator first, ModuleIterator last,
+ llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
+ ModuleMap *modMap) {
if (first == last)
return;
// 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) {
@@ -178,7 +170,10 @@ void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last,
}
}
- if (Ancestors.count(*victim))
+ // Files that didn't make it through ReadASTCore successfully will be
+ // rebuilt (or there was an error). Invalidate them so that we can load the
+ // new files that will be renamed over the old ones.
+ if (LoadedSuccessfully.count(*victim) == 0)
FileMgr.invalidateCache((*victim)->File);
delete *victim;
OpenPOWER on IntegriCloud