diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/Basic/MemoryBufferCache.cpp | 48 | ||||
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 23 | ||||
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 82 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Serialization/GeneratePCH.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Serialization/ModuleManager.cpp | 27 |
9 files changed, 175 insertions, 45 deletions
diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index 8929ec30ff7..23242ba3f60 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -74,6 +74,7 @@ add_clang_library(clangBasic FileSystemStatCache.cpp IdentifierTable.cpp LangOptions.cpp + MemoryBufferCache.cpp Module.cpp ObjCRuntime.cpp OpenMPKinds.cpp diff --git a/clang/lib/Basic/MemoryBufferCache.cpp b/clang/lib/Basic/MemoryBufferCache.cpp new file mode 100644 index 00000000000..c1fc571ec9b --- /dev/null +++ b/clang/lib/Basic/MemoryBufferCache.cpp @@ -0,0 +1,48 @@ +//===- MemoryBufferCache.cpp - Cache for loaded memory buffers ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/MemoryBufferCache.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace clang; + +llvm::MemoryBuffer & +MemoryBufferCache::addBuffer(llvm::StringRef Filename, + std::unique_ptr<llvm::MemoryBuffer> Buffer) { + auto Insertion = + Buffers.insert({Filename, BufferEntry{std::move(Buffer), NextIndex++}}); + assert(Insertion.second && "Already has a buffer"); + return *Insertion.first->second.Buffer; +} + +llvm::MemoryBuffer *MemoryBufferCache::lookupBuffer(llvm::StringRef Filename) { + auto I = Buffers.find(Filename); + if (I == Buffers.end()) + return nullptr; + return I->second.Buffer.get(); +} + +bool MemoryBufferCache::isBufferFinal(llvm::StringRef Filename) { + auto I = Buffers.find(Filename); + if (I == Buffers.end()) + return false; + return I->second.Index < FirstRemovableIndex; +} + +bool MemoryBufferCache::tryToRemoveBuffer(llvm::StringRef Filename) { + auto I = Buffers.find(Filename); + assert(I != Buffers.end() && "No buffer to remove..."); + if (I->second.Index < FirstRemovableIndex) + return true; + + Buffers.erase(I); + return false; +} + +void MemoryBufferCache::finalizeCurrentBuffers() { FirstRemovableIndex = NextIndex; } diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index ac5c7ca3be3..952992a9e8b 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -18,6 +18,7 @@ #include "clang/AST/StmtVisitor.h" #include "clang/AST/TypeOrdering.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Basic/VirtualFileSystem.h" @@ -185,7 +186,8 @@ struct ASTUnit::ASTWriterData { llvm::BitstreamWriter Stream; ASTWriter Writer; - ASTWriterData() : Stream(Buffer), Writer(Stream, Buffer, {}) {} + ASTWriterData(MemoryBufferCache &PCMCache) + : Stream(Buffer), Writer(Stream, Buffer, PCMCache, {}) {} }; void ASTUnit::clearFileLevelDecls() { @@ -681,6 +683,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( AST->SourceMgr = new SourceManager(AST->getDiagnostics(), AST->getFileManager(), UserFilesAreVolatile); + AST->PCMCache = new MemoryBufferCache; AST->HSOpts = std::make_shared<HeaderSearchOptions>(); AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat(); AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts, @@ -701,7 +704,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( AST->PP = std::make_shared<Preprocessor>( std::move(PPOpts), AST->getDiagnostics(), AST->ASTFileLangOpts, - AST->getSourceManager(), HeaderInfo, *AST, + AST->getSourceManager(), *AST->PCMCache, HeaderInfo, *AST, /*IILookup=*/nullptr, /*OwnsHeaderSearch=*/false); Preprocessor &PP = *AST->PP; @@ -1727,6 +1730,7 @@ ASTUnit::create(std::shared_ptr<CompilerInvocation> CI, AST->UserFilesAreVolatile = UserFilesAreVolatile; AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr, UserFilesAreVolatile); + AST->PCMCache = new MemoryBufferCache; return AST; } @@ -1997,6 +2001,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine( if (!VFS) return nullptr; AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS); + AST->PCMCache = new MemoryBufferCache; AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; AST->TUKind = TUKind; @@ -2008,7 +2013,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine( AST->StoredDiagnostics.swap(StoredDiagnostics); AST->Invocation = CI; if (ForSerialization) - AST->WriterData.reset(new ASTWriterData()); + AST->WriterData.reset(new ASTWriterData(*AST->PCMCache)); // Zero out now to ease cleanup during crash recovery. CI = nullptr; Diags = nullptr; @@ -2523,7 +2528,8 @@ bool ASTUnit::serialize(raw_ostream &OS) { SmallString<128> Buffer; llvm::BitstreamWriter Stream(Buffer); - ASTWriter Writer(Stream, Buffer, {}); + MemoryBufferCache PCMCache; + ASTWriter Writer(Stream, Buffer, PCMCache, {}); return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS); } diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index a0e81f01f9b..4841c103f61 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -13,6 +13,7 @@ #include "clang/AST/Decl.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" @@ -55,9 +56,15 @@ using namespace clang; CompilerInstance::CompilerInstance( std::shared_ptr<PCHContainerOperations> PCHContainerOps, - bool BuildingModule) - : ModuleLoader(BuildingModule), Invocation(new CompilerInvocation()), - ThePCHContainerOperations(std::move(PCHContainerOps)) {} + MemoryBufferCache *SharedPCMCache) + : ModuleLoader(/* BuildingModule = */ SharedPCMCache), + Invocation(new CompilerInvocation()), + PCMCache(SharedPCMCache ? SharedPCMCache : new MemoryBufferCache), + ThePCHContainerOperations(std::move(PCHContainerOps)) { + // Don't allow this to invalidate buffers in use by others. + if (SharedPCMCache) + getPCMCache().finalizeCurrentBuffers(); +} CompilerInstance::~CompilerInstance() { assert(OutputFiles.empty() && "Still output files in flight?"); @@ -128,6 +135,8 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { return ModuleManager; } void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { + assert(PCMCache.get() == &Reader->getModuleManager().getPCMCache() && + "Expected ASTReader to use the same PCM cache"); ModuleManager = std::move(Reader); } @@ -370,7 +379,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { getDiagnostics(), getLangOpts(), &getTarget()); PP = std::make_shared<Preprocessor>( Invocation->getPreprocessorOptsPtr(), getDiagnostics(), getLangOpts(), - getSourceManager(), *HeaderInfo, *this, PTHMgr, + getSourceManager(), getPCMCache(), *HeaderInfo, *this, PTHMgr, /*OwnsHeaderSearch=*/true, TUKind); PP->Initialize(getTarget(), getAuxTarget()); @@ -1073,9 +1082,11 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance, Invocation->getModuleHash() && "Module hash mismatch!"); // Construct a compiler instance that will be used to actually create the - // module. + // module. Since we're sharing a PCMCache, + // CompilerInstance::CompilerInstance is responsible for finalizing the + // buffers to prevent use-after-frees. CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(), - /*BuildingModule=*/true); + &ImportingInstance.getPreprocessor().getPCMCache()); auto &Inv = *Invocation; Instance.setInvocation(std::move(Invocation)); diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 91319bedd6f..babef5dcc7c 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -70,15 +70,15 @@ ExternalPreprocessorSource::~ExternalPreprocessorSource() { } Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts, DiagnosticsEngine &diags, LangOptions &opts, - SourceManager &SM, HeaderSearch &Headers, - ModuleLoader &TheModuleLoader, + SourceManager &SM, MemoryBufferCache &PCMCache, + HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup, bool OwnsHeaders, TranslationUnitKind TUKind) : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts), Target(nullptr), AuxTarget(nullptr), FileMgr(Headers.getFileMgr()), SourceMgr(SM), - ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers), - TheModuleLoader(TheModuleLoader), ExternalSource(nullptr), - Identifiers(opts, IILookup), + PCMCache(PCMCache), ScratchBuf(new ScratchBuffer(SourceMgr)), + HeaderInfo(Headers), TheModuleLoader(TheModuleLoader), + ExternalSource(nullptr), Identifiers(opts, IILookup), PragmaHandlers(new PragmaNamespace(StringRef())), IncrementalProcessing(false), TUKind(TUKind), CodeComplete(nullptr), CodeCompletionFile(nullptr), CodeCompletionOffset(0), diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index e4eddaef989..eac08545b16 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -37,6 +37,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemOptions.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/Sanitizers.h" @@ -463,19 +464,9 @@ static bool checkDiagnosticMappings(DiagnosticsEngine &StoredDiags, return checkDiagnosticGroupMappings(StoredDiags, Diags, Complain); } -bool PCHValidator::ReadDiagnosticOptions( - IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) { - DiagnosticsEngine &ExistingDiags = PP.getDiagnostics(); - IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs()); - IntrusiveRefCntPtr<DiagnosticsEngine> Diags( - new DiagnosticsEngine(DiagIDs, DiagOpts.get())); - // This should never fail, because we would have processed these options - // before writing them to an ASTFile. - ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false); - - ModuleManager &ModuleMgr = Reader.getModuleManager(); - assert(ModuleMgr.size() >= 1 && "what ASTFile is this then"); - +/// Return the top import module if it is implicit, nullptr otherwise. +static Module *getTopImportImplicitModule(ModuleManager &ModuleMgr, + Preprocessor &PP) { // If the original import came from a file explicitly generated by the user, // don't check the diagnostic mappings. // FIXME: currently this is approximated by checking whether this is not a @@ -487,17 +478,37 @@ bool PCHValidator::ReadDiagnosticOptions( while (!TopImport->ImportedBy.empty()) TopImport = TopImport->ImportedBy[0]; if (TopImport->Kind != MK_ImplicitModule) - return false; + return nullptr; StringRef ModuleName = TopImport->ModuleName; assert(!ModuleName.empty() && "diagnostic options read before module name"); Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName); assert(M && "missing module"); + return M; +} + +bool PCHValidator::ReadDiagnosticOptions( + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) { + DiagnosticsEngine &ExistingDiags = PP.getDiagnostics(); + IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags( + new DiagnosticsEngine(DiagIDs, DiagOpts.get())); + // This should never fail, because we would have processed these options + // before writing them to an ASTFile. + ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false); + + ModuleManager &ModuleMgr = Reader.getModuleManager(); + assert(ModuleMgr.size() >= 1 && "what ASTFile is this then"); + + Module *TopM = getTopImportImplicitModule(ModuleMgr, PP); + if (!TopM) + return false; // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that // contains the union of their flags. - return checkDiagnosticMappings(*Diags, ExistingDiags, M->IsSystem, Complain); + return checkDiagnosticMappings(*Diags, ExistingDiags, TopM->IsSystem, + Complain); } /// \brief Collect the macro definitions provided by the given preprocessor @@ -4064,12 +4075,41 @@ ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy, Listener.get(), WasImportedBy ? false : HSOpts.ModulesValidateDiagnosticOptions); + // If F was directly imported by another module, it's implicitly validated by + // the importing module. if (DisableValidation || WasImportedBy || (AllowConfigurationMismatch && Result == ConfigurationMismatch)) return Success; - if (Result == Failure) + if (Result == Failure) { Error("malformed block record in AST file"); + return Failure; + } + + if (Result == OutOfDate && F.Kind == MK_ImplicitModule) { + // If this module has already been finalized in the PCMCache, we're stuck + // with it; we can only load a single version of each module. + // + // This can happen when a module is imported in two contexts: in one, as a + // user module; in another, as a system module (due to an import from + // another module marked with the [system] flag). It usually indicates a + // bug in the module map: this module should also be marked with [system]. + // + // If -Wno-system-headers (the default), and the first import is as a + // system module, then validation will fail during the as-user import, + // since -Werror flags won't have been validated. However, it's reasonable + // to treat this consistently as a system module. + // + // If -Wsystem-headers, the PCM on disk was built with + // -Wno-system-headers, and the first import is as a user module, then + // validation will fail during the as-system import since the PCM on disk + // doesn't guarantee that -Werror was respected. However, the -Werror + // flags were checked during the initial as-user import. + if (PCMCache.isBufferFinal(F.FileName)) { + Diag(diag::warn_module_system_bit_conflict) << F.FileName; + return Success; + } + } return Result; } @@ -4122,7 +4162,7 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( if (Listener && ValidateDiagnosticOptions && !AllowCompatibleConfigurationMismatch && ParseDiagnosticOptions(Record, Complain, *Listener)) - return OutOfDate; + Result = OutOfDate; // Don't return early. Read the signature. break; } case DIAG_PRAGMA_MAPPINGS: @@ -7301,7 +7341,7 @@ LLVM_DUMP_METHOD void ASTReader::dump() { /// by heap-backed versus mmap'ed memory. void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const { for (ModuleFile &I : ModuleMgr) { - if (llvm::MemoryBuffer *buf = I.Buffer.get()) { + if (llvm::MemoryBuffer *buf = I.Buffer) { size_t bytes = buf->getBufferSize(); switch (buf->getBufferKind()) { case llvm::MemoryBuffer::MemoryBuffer_Malloc: @@ -9628,8 +9668,10 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, : cast<ASTReaderListener>(new PCHValidator(PP, *this))), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP), - Context(Context), ModuleMgr(PP.getFileManager(), PCHContainerRdr), - DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot), + Context(Context), + ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr), + PCMCache(PP.getPCMCache()), DummyIdResolver(PP), + ReadTimer(std::move(ReadTimer)), isysroot(isysroot), DisableValidation(DisableValidation), AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), AllowConfigurationMismatch(AllowConfigurationMismatch), diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e9e64c2a66f..524bc2dae73 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -35,6 +35,7 @@ #include "clang/Basic/FileSystemOptions.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/Module.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/SourceManager.h" @@ -4304,10 +4305,11 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { } ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream, - SmallVectorImpl<char> &Buffer, + SmallVectorImpl<char> &Buffer, MemoryBufferCache &PCMCache, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, bool IncludeTimestamps) - : Stream(Stream), Buffer(Buffer), IncludeTimestamps(IncludeTimestamps) { + : Stream(Stream), Buffer(Buffer), PCMCache(PCMCache), + IncludeTimestamps(IncludeTimestamps) { for (const auto &Ext : Extensions) { if (auto Writer = Ext->createExtensionWriter(*this)) ModuleFileExtensionWriters.push_back(std::move(Writer)); @@ -4354,6 +4356,12 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, this->BaseDirectory.clear(); WritingAST = false; + if (SemaRef.Context.getLangOpts().ImplicitModules && WritingModule) { + // Construct MemoryBuffer and update buffer manager. + PCMCache.addBuffer(OutputFile, + llvm::MemoryBuffer::getMemBufferCopy( + StringRef(Buffer.begin(), Buffer.size()))); + } return Signature; } diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp index 141a5594aed..429ae8ebda5 100644 --- a/clang/lib/Serialization/GeneratePCH.cpp +++ b/clang/lib/Serialization/GeneratePCH.cpp @@ -28,7 +28,8 @@ PCHGenerator::PCHGenerator( bool AllowASTWithErrors, bool IncludeTimestamps) : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()), SemaPtr(nullptr), Buffer(Buffer), Stream(Buffer->Data), - Writer(Stream, Buffer->Data, Extensions, IncludeTimestamps), + Writer(Stream, Buffer->Data, PP.getPCMCache(), Extensions, + IncludeTimestamps), AllowASTWithErrors(AllowASTWithErrors) { Buffer->IsComplete = false; } diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index f0654fc10b4..d9c9fb702be 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// #include "clang/Serialization/ModuleManager.h" +#include "clang/Basic/MemoryBufferCache.h" #include "clang/Frontend/PCHContainerOperations.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/ModuleMap.h" @@ -137,7 +138,9 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, // Load the contents of the module if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) { // The buffer was already provided for us. - NewModule->Buffer = std::move(Buffer); + NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(Buffer)); + } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(FileName)) { + NewModule->Buffer = Buffer; } else { // Open the AST file. llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf((std::error_code())); @@ -158,7 +161,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, return Missing; } - NewModule->Buffer = std::move(*Buf); + NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(*Buf)); } // Initialize the stream. @@ -167,8 +170,13 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, // Read the signature eagerly now so that we can check it. Avoid calling // ReadSignature unless there's something to check though. if (ExpectedSignature && checkSignature(ReadSignature(NewModule->Data), - ExpectedSignature, ErrorStr)) + ExpectedSignature, ErrorStr)) { + // Try to remove the buffer. If it can't be removed, then it was already + // validated by this process. + if (!PCMCache->tryToRemoveBuffer(NewModule->FileName)) + FileMgr.invalidateCache(NewModule->File); return OutOfDate; + } // We're keeping this module. Store it everywhere. Module = Modules[Entry] = NewModule.get(); @@ -235,7 +243,12 @@ void ModuleManager::removeModules( // 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) + // + // The PCMCache tracks whether the module was succesfully loaded in another + // thread/context; in that case, it won't need to be rebuilt (and we can't + // safely invalidate it anyway). + if (LoadedSuccessfully.count(&*victim) == 0 && + !PCMCache->tryToRemoveBuffer(victim->FileName)) FileMgr.invalidateCache(victim->File); } @@ -292,10 +305,10 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) { ModulesInCommonWithGlobalIndex.push_back(MF); } -ModuleManager::ModuleManager(FileManager &FileMgr, +ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache, const PCHContainerReader &PCHContainerRdr) - : FileMgr(FileMgr), PCHContainerRdr(PCHContainerRdr), GlobalIndex(), - FirstVisitState(nullptr) {} + : FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(PCHContainerRdr), + GlobalIndex(), FirstVisitState(nullptr) {} ModuleManager::~ModuleManager() { delete FirstVisitState; } |