diff options
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Serialization/ModuleManager.cpp | 39 |
2 files changed, 24 insertions, 24 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 0c9f263faf1..777ea831981 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3464,8 +3464,13 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, case OutOfDate: case VersionMismatch: case ConfigurationMismatch: - case HadErrors: + case HadErrors: { + llvm::SmallPtrSet<ModuleFile *, 4> LoadedSet; + for (const ImportedModule &IM : Loaded) + LoadedSet.insert(IM.Mod); + ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end(), + LoadedSet, Context.getLangOpts().Modules ? &PP.getHeaderSearchInfo().getModuleMap() : nullptr); @@ -3475,7 +3480,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, GlobalIndex.reset(); ModuleMgr.setGlobalIndex(nullptr); return ReadResult; - + } case Success: break; } 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; |