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.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