Index: clang/include/clang/Frontend/ASTUnit.h =================================================================== --- clang/include/clang/Frontend/ASTUnit.h +++ clang/include/clang/Frontend/ASTUnit.h @@ -71,7 +71,7 @@ class FrontendAction; class HeaderSearch; class InputKind; -class MemoryBufferCache; +class InMemoryModuleCache; class PCHContainerOperations; class PCHContainerReader; class Preprocessor; @@ -107,7 +107,7 @@ IntrusiveRefCntPtr Diagnostics; IntrusiveRefCntPtr FileMgr; IntrusiveRefCntPtr SourceMgr; - IntrusiveRefCntPtr PCMCache; + IntrusiveRefCntPtr ModuleCache; std::unique_ptr HeaderInfo; IntrusiveRefCntPtr Target; std::shared_ptr PP; Index: clang/include/clang/Frontend/CompilerInstance.h =================================================================== --- clang/include/clang/Frontend/CompilerInstance.h +++ clang/include/clang/Frontend/CompilerInstance.h @@ -44,7 +44,7 @@ class FileEntry; class FileManager; class FrontendAction; -class MemoryBufferCache; +class InMemoryModuleCache; class Module; class Preprocessor; class Sema; @@ -92,7 +92,7 @@ IntrusiveRefCntPtr SourceMgr; /// The cache of PCM files. - IntrusiveRefCntPtr PCMCache; + IntrusiveRefCntPtr ModuleCache; /// The preprocessor. std::shared_ptr PP; @@ -192,7 +192,7 @@ explicit CompilerInstance( std::shared_ptr PCHContainerOps = std::make_shared(), - MemoryBufferCache *SharedPCMCache = nullptr); + InMemoryModuleCache *SharedModuleCache = nullptr); ~CompilerInstance() override; /// @name High-Level Operations @@ -671,7 +671,8 @@ /// \return - The new object on success, or null on failure. static IntrusiveRefCntPtr createPCHExternalASTSource( StringRef Path, StringRef Sysroot, bool DisablePCHValidation, - bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, + bool AllowPCHWithCompilerErrors, Preprocessor &PP, + InMemoryModuleCache &ModuleCache, ASTContext &Context, const PCHContainerReader &PCHContainerRdr, ArrayRef> Extensions, DependencyFileGenerator *DependencyFile, @@ -813,7 +814,7 @@ void setExternalSemaSource(IntrusiveRefCntPtr ESS); - MemoryBufferCache &getPCMCache() const { return *PCMCache; } + InMemoryModuleCache &getModuleCache() const { return *ModuleCache; } }; } // end namespace clang Index: clang/include/clang/Lex/Preprocessor.h =================================================================== --- clang/include/clang/Lex/Preprocessor.h +++ clang/include/clang/Lex/Preprocessor.h @@ -71,7 +71,6 @@ class FileManager; class HeaderSearch; class MacroArgs; -class MemoryBufferCache; class PragmaHandler; class PragmaNamespace; class PreprocessingRecord; @@ -132,7 +131,6 @@ const TargetInfo *AuxTarget = nullptr; FileManager &FileMgr; SourceManager &SourceMgr; - MemoryBufferCache &PCMCache; std::unique_ptr ScratchBuf; HeaderSearch &HeaderInfo; ModuleLoader &TheModuleLoader; @@ -779,7 +777,6 @@ public: Preprocessor(std::shared_ptr PPOpts, DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM, - MemoryBufferCache &PCMCache, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup = nullptr, bool OwnsHeaderSearch = false, @@ -819,7 +816,6 @@ const TargetInfo *getAuxTargetInfo() const { return AuxTarget; } FileManager &getFileManager() const { return FileMgr; } SourceManager &getSourceManager() const { return SourceMgr; } - MemoryBufferCache &getPCMCache() const { return PCMCache; } HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; } IdentifierTable &getIdentifierTable() { return Identifiers; } Index: clang/include/clang/Serialization/ASTReader.h =================================================================== --- clang/include/clang/Serialization/ASTReader.h +++ clang/include/clang/Serialization/ASTReader.h @@ -97,7 +97,7 @@ class LangOptions; class LazyASTUnresolvedSet; class MacroInfo; -class MemoryBufferCache; +class InMemoryModuleCache; class NamedDecl; class NamespaceDecl; class ObjCCategoryDecl; @@ -440,9 +440,6 @@ /// The module manager which manages modules and their dependencies ModuleManager ModuleMgr; - /// The cache that manages memory buffers for PCM files. - MemoryBufferCache &PCMCache; - /// A dummy identifier resolver used to merge TU-scope declarations in /// C, for the cases where we don't have a Sema object to provide a real /// identifier resolver. @@ -1481,8 +1478,8 @@ /// /// \param ReadTimer If non-null, a timer used to track the time spent /// deserializing. - ASTReader(Preprocessor &PP, ASTContext *Context, - const PCHContainerReader &PCHContainerRdr, + ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache, + ASTContext *Context, const PCHContainerReader &PCHContainerRdr, ArrayRef> Extensions, StringRef isysroot = "", bool DisableValidation = false, bool AllowASTWithCompilerErrors = false, Index: clang/include/clang/Serialization/ASTWriter.h =================================================================== --- clang/include/clang/Serialization/ASTWriter.h +++ clang/include/clang/Serialization/ASTWriter.h @@ -74,8 +74,8 @@ class LangOptions; class MacroDefinitionRecord; class MacroInfo; -class MemoryBufferCache; class Module; +class InMemoryModuleCache; class ModuleFileExtension; class ModuleFileExtensionWriter; class NamedDecl; @@ -132,7 +132,7 @@ const SmallVectorImpl &Buffer; /// The PCM manager which manages memory buffers for pcm files. - MemoryBufferCache &PCMCache; + InMemoryModuleCache &ModuleCache; /// The ASTContext we're writing. ASTContext *Context = nullptr; @@ -542,7 +542,7 @@ /// Create a new precompiled header writer that outputs to /// the given bitstream. ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl &Buffer, - MemoryBufferCache &PCMCache, + InMemoryModuleCache &ModuleCache, ArrayRef> Extensions, bool IncludeTimestamps = true); ~ASTWriter() override; @@ -980,7 +980,8 @@ SmallVectorImpl &getPCH() const { return Buffer->Data; } public: - PCHGenerator(const Preprocessor &PP, StringRef OutputFile, StringRef isysroot, + PCHGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache, + StringRef OutputFile, StringRef isysroot, std::shared_ptr Buffer, ArrayRef> Extensions, bool AllowASTWithErrors = false, bool IncludeTimestamps = true); Index: clang/include/clang/Serialization/InMemoryModuleCache.h =================================================================== --- clang/include/clang/Serialization/InMemoryModuleCache.h +++ clang/include/clang/Serialization/InMemoryModuleCache.h @@ -1,4 +1,4 @@ -//===- MemoryBufferCache.h - Cache for loaded memory buffers ----*- C++ -*-===// +//===- InMemoryModuleCache.h - In-memory cache for modules ------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,10 +6,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H -#define LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H +#ifndef LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H +#define LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringMap.h" #include @@ -19,17 +20,22 @@ namespace clang { -/// Manage memory buffers across multiple users. +/// In-memory cache for modules. /// -/// Ensures that multiple users have a consistent view of each buffer. This is -/// used by \a CompilerInstance when building PCMs to ensure that each \a -/// ModuleManager sees the same files. +/// This is a cache for modules for use across a compilation, sharing state +/// between the CompilerInstances in an implicit modules build. It must be +/// shared by each CompilerInstance, ASTReader, ASTWriter, and ModuleManager +/// that are coordinating. +/// +/// Critically, it ensures that a single process has a consistent view of each +/// PCM. This is used by \a CompilerInstance when building PCMs to ensure that +/// each \a ModuleManager sees the same files. /// /// \a finalizeCurrentBuffers() should be called before creating a new user. -/// This locks in the current buffers, ensuring that no buffer that has already -/// been accessed can be purged, preventing use-after-frees. -class MemoryBufferCache : public llvm::RefCountedBase { - struct BufferEntry { +/// This locks in the current PCMs, ensuring that no PCM that has already been +/// accessed can be purged, preventing use-after-frees. +class InMemoryModuleCache : public llvm::RefCountedBase { + struct PCM { std::unique_ptr Buffer; /// Track the timeline of when this was added to the cache. @@ -37,7 +43,7 @@ }; /// Cache of buffers. - llvm::StringMap Buffers; + llvm::StringMap PCMs; /// Monotonically increasing index. unsigned NextIndex = 0; @@ -76,4 +82,4 @@ } // end namespace clang -#endif // LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H +#endif // LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H Index: clang/include/clang/Serialization/Module.h =================================================================== --- clang/include/clang/Serialization/Module.h +++ clang/include/clang/Serialization/Module.h @@ -174,7 +174,7 @@ unsigned Generation; /// The memory buffer that stores the data associated with - /// this AST file, owned by the PCMCache in the ModuleManager. + /// this AST file, owned by the InMemoryModuleCache. llvm::MemoryBuffer *Buffer; /// The size of this file, in bits. Index: clang/include/clang/Serialization/ModuleManager.h =================================================================== --- clang/include/clang/Serialization/ModuleManager.h +++ clang/include/clang/Serialization/ModuleManager.h @@ -38,7 +38,7 @@ class FileManager; class GlobalModuleIndex; class HeaderSearch; -class MemoryBufferCache; +class InMemoryModuleCache; class ModuleMap; class PCHContainerReader; @@ -67,7 +67,7 @@ FileManager &FileMgr; /// Cache of PCM files. - IntrusiveRefCntPtr PCMCache; + IntrusiveRefCntPtr ModuleCache; /// Knows how to unwrap module containers. const PCHContainerReader &PCHContainerRdr; @@ -139,7 +139,7 @@ SmallVectorImpl>::reverse_iterator>; using ModuleOffset = std::pair; - explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache, + explicit ModuleManager(FileManager &FileMgr, InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, const HeaderSearch &HeaderSearchInfo); ~ModuleManager(); @@ -317,7 +317,7 @@ /// View the graphviz representation of the module graph. void viewGraph(); - MemoryBufferCache &getPCMCache() const { return *PCMCache; } + InMemoryModuleCache &getModuleCache() const { return *ModuleCache; } }; } // namespace serialization Index: clang/lib/Basic/CMakeLists.txt =================================================================== --- clang/lib/Basic/CMakeLists.txt +++ clang/lib/Basic/CMakeLists.txt @@ -50,7 +50,6 @@ FixedPoint.cpp IdentifierTable.cpp LangOptions.cpp - MemoryBufferCache.cpp Module.cpp ObjCRuntime.cpp OpenMPKinds.cpp Index: clang/lib/Basic/MemoryBufferCache.cpp =================================================================== --- clang/lib/Basic/MemoryBufferCache.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//===- MemoryBufferCache.cpp - Cache for loaded memory buffers ------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "clang/Basic/MemoryBufferCache.h" -#include "llvm/Support/MemoryBuffer.h" - -using namespace clang; - -llvm::MemoryBuffer & -MemoryBufferCache::addBuffer(llvm::StringRef Filename, - std::unique_ptr 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; } Index: clang/lib/Frontend/ASTUnit.cpp =================================================================== --- clang/lib/Frontend/ASTUnit.cpp +++ clang/lib/Frontend/ASTUnit.cpp @@ -30,7 +30,6 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" @@ -60,6 +59,7 @@ #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" #include "clang/Serialization/ContinuousRangeMap.h" +#include "clang/Serialization/InMemoryModuleCache.h" #include "clang/Serialization/Module.h" #include "clang/Serialization/PCHContainerOperations.h" #include "llvm/ADT/ArrayRef.h" @@ -217,8 +217,8 @@ llvm::BitstreamWriter Stream; ASTWriter Writer; - ASTWriterData(MemoryBufferCache &PCMCache) - : Stream(Buffer), Writer(Stream, Buffer, PCMCache, {}) {} + ASTWriterData(InMemoryModuleCache &ModuleCache) + : Stream(Buffer), Writer(Stream, Buffer, ModuleCache, {}) {} }; void ASTUnit::clearFileLevelDecls() { @@ -758,7 +758,7 @@ AST->SourceMgr = new SourceManager(AST->getDiagnostics(), AST->getFileManager(), UserFilesAreVolatile); - AST->PCMCache = new MemoryBufferCache; + AST->ModuleCache = new InMemoryModuleCache; AST->HSOpts = std::make_shared(); AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat(); AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts, @@ -778,7 +778,7 @@ AST->PP = std::make_shared( AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts, - AST->getSourceManager(), *AST->PCMCache, HeaderInfo, AST->ModuleLoader, + AST->getSourceManager(), HeaderInfo, AST->ModuleLoader, /*IILookup=*/nullptr, /*OwnsHeaderSearch=*/false); Preprocessor &PP = *AST->PP; @@ -791,10 +791,10 @@ bool disableValid = false; if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION")) disableValid = true; - AST->Reader = new ASTReader(PP, AST->Ctx.get(), PCHContainerRdr, {}, - /*isysroot=*/"", - /*DisableValidation=*/disableValid, - AllowPCHWithCompilerErrors); + AST->Reader = new ASTReader( + PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {}, + /*isysroot=*/"", + /*DisableValidation=*/disableValid, AllowPCHWithCompilerErrors); AST->Reader->setListener(llvm::make_unique( *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts, @@ -1477,7 +1477,7 @@ AST->UserFilesAreVolatile = UserFilesAreVolatile; AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr, UserFilesAreVolatile); - AST->PCMCache = new MemoryBufferCache; + AST->ModuleCache = new InMemoryModuleCache; return AST; } @@ -1757,7 +1757,7 @@ VFS = llvm::vfs::getRealFileSystem(); VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS); AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS); - AST->PCMCache = new MemoryBufferCache; + AST->ModuleCache = new InMemoryModuleCache; AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; AST->TUKind = TUKind; @@ -1768,7 +1768,7 @@ AST->Invocation = CI; AST->SkipFunctionBodies = SkipFunctionBodies; if (ForSerialization) - AST->WriterData.reset(new ASTWriterData(*AST->PCMCache)); + AST->WriterData.reset(new ASTWriterData(*AST->ModuleCache)); // Zero out now to ease cleanup during crash recovery. CI = nullptr; Diags = nullptr; @@ -2317,8 +2317,8 @@ SmallString<128> Buffer; llvm::BitstreamWriter Stream(Buffer); - MemoryBufferCache PCMCache; - ASTWriter Writer(Stream, Buffer, PCMCache, {}); + InMemoryModuleCache ModuleCache; + ASTWriter Writer(Stream, Buffer, ModuleCache, {}); return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS); } Index: clang/lib/Frontend/ChainedIncludesSource.cpp =================================================================== --- clang/lib/Frontend/ChainedIncludesSource.cpp +++ clang/lib/Frontend/ChainedIncludesSource.cpp @@ -82,9 +82,9 @@ ASTDeserializationListener *deserialListener = nullptr) { Preprocessor &PP = CI.getPreprocessor(); std::unique_ptr Reader; - Reader.reset(new ASTReader(PP, &CI.getASTContext(), + Reader.reset(new ASTReader(PP, CI.getModuleCache(), &CI.getASTContext(), CI.getPCHContainerReader(), - /*Extensions=*/{ }, + /*Extensions=*/{}, /*isysroot=*/"", /*DisableValidation=*/true)); for (unsigned ti = 0; ti < bufNames.size(); ++ti) { StringRef sr(bufNames[ti]); @@ -159,8 +159,8 @@ auto Buffer = std::make_shared(); ArrayRef> Extensions; auto consumer = llvm::make_unique( - Clang->getPreprocessor(), "-", /*isysroot=*/"", Buffer, - Extensions, /*AllowASTWithErrors=*/true); + Clang->getPreprocessor(), Clang->getModuleCache(), "-", /*isysroot=*/"", + Buffer, Extensions, /*AllowASTWithErrors=*/true); Clang->getASTContext().setASTMutationListener( consumer->GetASTMutationListener()); Clang->setASTConsumer(std::move(consumer)); Index: clang/lib/Frontend/CompilerInstance.cpp =================================================================== --- clang/lib/Frontend/CompilerInstance.cpp +++ clang/lib/Frontend/CompilerInstance.cpp @@ -13,7 +13,6 @@ #include "clang/Basic/CharInfo.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Stack.h" #include "clang/Basic/TargetInfo.h" @@ -35,6 +34,7 @@ #include "clang/Sema/Sema.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/GlobalModuleIndex.h" +#include "clang/Serialization/InMemoryModuleCache.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/BuryPointer.h" #include "llvm/Support/CrashRecoveryContext.h" @@ -57,14 +57,15 @@ CompilerInstance::CompilerInstance( std::shared_ptr PCHContainerOps, - MemoryBufferCache *SharedPCMCache) - : ModuleLoader(/* BuildingModule = */ SharedPCMCache), + InMemoryModuleCache *SharedModuleCache) + : ModuleLoader(/* BuildingModule = */ SharedModuleCache), Invocation(new CompilerInvocation()), - PCMCache(SharedPCMCache ? SharedPCMCache : new MemoryBufferCache), + ModuleCache(SharedModuleCache ? SharedModuleCache + : new InMemoryModuleCache), ThePCHContainerOperations(std::move(PCHContainerOps)) { // Don't allow this to invalidate buffers in use by others. - if (SharedPCMCache) - getPCMCache().finalizeCurrentBuffers(); + if (SharedModuleCache) + getModuleCache().finalizeCurrentBuffers(); } CompilerInstance::~CompilerInstance() { @@ -136,7 +137,7 @@ return ModuleManager; } void CompilerInstance::setModuleManager(IntrusiveRefCntPtr Reader) { - assert(PCMCache.get() == &Reader->getModuleManager().getPCMCache() && + assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() && "Expected ASTReader to use the same PCM cache"); ModuleManager = std::move(Reader); } @@ -378,11 +379,11 @@ HeaderSearch *HeaderInfo = new HeaderSearch(getHeaderSearchOptsPtr(), getSourceManager(), getDiagnostics(), getLangOpts(), &getTarget()); - PP = std::make_shared( - Invocation->getPreprocessorOptsPtr(), getDiagnostics(), getLangOpts(), - getSourceManager(), getPCMCache(), *HeaderInfo, *this, - /*IdentifierInfoLookup=*/nullptr, - /*OwnsHeaderSearch=*/true, TUKind); + PP = std::make_shared(Invocation->getPreprocessorOptsPtr(), + getDiagnostics(), getLangOpts(), + getSourceManager(), *HeaderInfo, *this, + /*IdentifierInfoLookup=*/nullptr, + /*OwnsHeaderSearch=*/true, TUKind); getTarget().adjust(getLangOpts()); PP->Initialize(getTarget(), getAuxTarget()); @@ -489,19 +490,17 @@ bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; ModuleManager = createPCHExternalASTSource( Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, - AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), - getPCHContainerReader(), - getFrontendOpts().ModuleFileExtensions, - TheDependencyFileGenerator.get(), - DependencyCollectors, - DeserializationListener, - OwnDeserializationListener, Preamble, - getFrontendOpts().UseGlobalModuleIndex); + AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(), + getASTContext(), getPCHContainerReader(), + getFrontendOpts().ModuleFileExtensions, TheDependencyFileGenerator.get(), + DependencyCollectors, DeserializationListener, OwnDeserializationListener, + Preamble, getFrontendOpts().UseGlobalModuleIndex); } IntrusiveRefCntPtr CompilerInstance::createPCHExternalASTSource( StringRef Path, StringRef Sysroot, bool DisablePCHValidation, - bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, + bool AllowPCHWithCompilerErrors, Preprocessor &PP, + InMemoryModuleCache &ModuleCache, ASTContext &Context, const PCHContainerReader &PCHContainerRdr, ArrayRef> Extensions, DependencyFileGenerator *DependencyFile, @@ -511,7 +510,7 @@ HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); IntrusiveRefCntPtr Reader(new ASTReader( - PP, &Context, PCHContainerRdr, Extensions, + PP, ModuleCache, &Context, PCHContainerRdr, Extensions, Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation, AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false, HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex)); @@ -1094,11 +1093,11 @@ Invocation->getModuleHash() && "Module hash mismatch!"); // Construct a compiler instance that will be used to actually create the - // module. Since we're sharing a PCMCache, + // module. Since we're sharing an in-memory module cache, // CompilerInstance::CompilerInstance is responsible for finalizing the // buffers to prevent use-after-frees. CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(), - &ImportingInstance.getPreprocessor().getPCMCache()); + &ImportingInstance.getModuleCache()); auto &Inv = *Invocation; Instance.setInvocation(std::move(Invocation)); @@ -1255,7 +1254,7 @@ llvm::LockFileManager Locked(ModuleFileName); switch (Locked) { case llvm::LockFileManager::LFS_Error: - // PCMCache takes care of correctness and locks are only necessary for + // ModuleCache takes care of correctness and locks are only necessary for // performance. Fallback to building the module in case of any lock // related errors. Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure) @@ -1282,9 +1281,9 @@ case llvm::LockFileManager::Res_OwnerDied: continue; // try again to get the lock. case llvm::LockFileManager::Res_Timeout: - // Since PCMCache takes care of correctness, we try waiting for another - // process to complete the build so clang does not do it done twice. If - // case of timeout, build it ourselves. + // Since ModuleCache takes care of correctness, we try waiting for + // another process to complete the build so clang does not do it done + // twice. If case of timeout, build it ourselves. Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout) << Module->Name; // Clear the lock file so that future invocations can make progress. @@ -1482,14 +1481,13 @@ "Reading modules", *FrontendTimerGroup); ModuleManager = new ASTReader( - getPreprocessor(), &getASTContext(), getPCHContainerReader(), - getFrontendOpts().ModuleFileExtensions, + getPreprocessor(), getModuleCache(), &getASTContext(), + getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions, Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation, /*AllowASTWithCompilerErrors=*/false, /*AllowConfigurationMismatch=*/false, HSOpts.ModulesValidateSystemHeaders, - getFrontendOpts().UseGlobalModuleIndex, - std::move(ReadTimer)); + getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer)); if (hasASTConsumer()) { ModuleManager->setDeserializationListener( getASTConsumer().GetASTDeserializationListener()); Index: clang/lib/Frontend/FrontendActions.cpp =================================================================== --- clang/lib/Frontend/FrontendActions.cpp +++ clang/lib/Frontend/FrontendActions.cpp @@ -109,10 +109,10 @@ auto Buffer = std::make_shared(); std::vector> Consumers; Consumers.push_back(llvm::make_unique( - CI.getPreprocessor(), OutputFile, Sysroot, - Buffer, FrontendOpts.ModuleFileExtensions, - CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, - FrontendOpts.IncludeTimestamps)); + CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer, + FrontendOpts.ModuleFileExtensions, + CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, + FrontendOpts.IncludeTimestamps)); Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( CI, InFile, OutputFile, std::move(OS), Buffer)); @@ -172,11 +172,11 @@ std::vector> Consumers; Consumers.push_back(llvm::make_unique( - CI.getPreprocessor(), OutputFile, Sysroot, - Buffer, CI.getFrontendOpts().ModuleFileExtensions, - /*AllowASTWithErrors=*/false, - /*IncludeTimestamps=*/ - +CI.getFrontendOpts().BuildingImplicitModule)); + CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer, + CI.getFrontendOpts().ModuleFileExtensions, + /*AllowASTWithErrors=*/false, + /*IncludeTimestamps=*/ + +CI.getFrontendOpts().BuildingImplicitModule)); Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( CI, InFile, OutputFile, std::move(OS), Buffer)); return llvm::make_unique(std::move(Consumers)); @@ -329,8 +329,8 @@ bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot; std::unique_ptr Reader(new ASTReader( - CI.getPreprocessor(), &CI.getASTContext(), CI.getPCHContainerReader(), - CI.getFrontendOpts().ModuleFileExtensions, + CI.getPreprocessor(), CI.getModuleCache(), &CI.getASTContext(), + CI.getPCHContainerReader(), CI.getFrontendOpts().ModuleFileExtensions, Sysroot.empty() ? "" : Sysroot.c_str(), /*DisableValidation*/ false, /*AllowPCHWithCompilerErrors*/ false, Index: clang/lib/Frontend/PrecompiledPreamble.cpp =================================================================== --- clang/lib/Frontend/PrecompiledPreamble.cpp +++ clang/lib/Frontend/PrecompiledPreamble.cpp @@ -157,9 +157,12 @@ class PrecompilePreambleConsumer : public PCHGenerator { public: PrecompilePreambleConsumer(PrecompilePreambleAction &Action, - const Preprocessor &PP, StringRef isysroot, + const Preprocessor &PP, + InMemoryModuleCache &ModuleCache, + StringRef isysroot, std::unique_ptr Out) - : PCHGenerator(PP, "", isysroot, std::make_shared(), + : PCHGenerator(PP, ModuleCache, "", isysroot, + std::make_shared(), ArrayRef>(), /*AllowASTWithErrors=*/true), Action(Action), Out(std::move(Out)) {} @@ -211,7 +214,7 @@ Sysroot.clear(); return llvm::make_unique( - *this, CI.getPreprocessor(), Sysroot, std::move(OS)); + *this, CI.getPreprocessor(), CI.getModuleCache(), Sysroot, std::move(OS)); } template bool moveOnNoError(llvm::ErrorOr Val, T &Output) { Index: clang/lib/Frontend/Rewrite/FrontendActions.cpp =================================================================== --- clang/lib/Frontend/Rewrite/FrontendActions.cpp +++ clang/lib/Frontend/Rewrite/FrontendActions.cpp @@ -237,7 +237,7 @@ // Rewrite the contents of the module in a separate compiler instance. CompilerInstance Instance(CI.getPCHContainerOperations(), - &CI.getPreprocessor().getPCMCache()); + &CI.getModuleCache()); Instance.setInvocation( std::make_shared(CI.getInvocation())); Instance.createDiagnostics( Index: clang/lib/Lex/Preprocessor.cpp =================================================================== --- clang/lib/Lex/Preprocessor.cpp +++ clang/lib/Lex/Preprocessor.cpp @@ -77,12 +77,12 @@ Preprocessor::Preprocessor(std::shared_ptr PPOpts, DiagnosticsEngine &diags, LangOptions &opts, - SourceManager &SM, MemoryBufferCache &PCMCache, - HeaderSearch &Headers, ModuleLoader &TheModuleLoader, + SourceManager &SM, HeaderSearch &Headers, + ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup, bool OwnsHeaders, TranslationUnitKind TUKind) : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts), - FileMgr(Headers.getFileMgr()), SourceMgr(SM), PCMCache(PCMCache), + FileMgr(Headers.getFileMgr()), SourceMgr(SM), ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers), TheModuleLoader(TheModuleLoader), ExternalSource(nullptr), // As the language options may have not been loaded yet (when Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -46,7 +46,6 @@ #include "clang/Basic/IdentifierTable.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/OperatorKinds.h" @@ -76,6 +75,7 @@ #include "clang/Serialization/ASTDeserializationListener.h" #include "clang/Serialization/ContinuousRangeMap.h" #include "clang/Serialization/GlobalModuleIndex.h" +#include "clang/Serialization/InMemoryModuleCache.h" #include "clang/Serialization/Module.h" #include "clang/Serialization/ModuleFileExtension.h" #include "clang/Serialization/ModuleManager.h" @@ -4285,7 +4285,7 @@ } if (Result == OutOfDate && F.Kind == MK_ImplicitModule) { - // If this module has already been finalized in the PCMCache, we're stuck + // If this module has already been finalized in the ModuleCache, 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 @@ -4303,7 +4303,7 @@ // 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)) { + if (getModuleManager().getModuleCache().isBufferFinal(F.FileName)) { Diag(diag::warn_module_system_bit_conflict) << F.FileName; return Success; } @@ -11600,7 +11600,8 @@ } } -ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context, +ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache, + ASTContext *Context, const PCHContainerReader &PCHContainerRdr, ArrayRef> Extensions, StringRef isysroot, bool DisableValidation, @@ -11613,11 +11614,9 @@ : cast(new PCHValidator(PP, *this))), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP), - ContextObj(Context), - ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr, - PP.getHeaderSearchInfo()), - PCMCache(PP.getPCMCache()), DummyIdResolver(PP), - ReadTimer(std::move(ReadTimer)), isysroot(isysroot), + ContextObj(Context), ModuleMgr(PP.getFileManager(), ModuleCache, + PCHContainerRdr, PP.getHeaderSearchInfo()), + DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot), DisableValidation(DisableValidation), AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), AllowConfigurationMismatch(AllowConfigurationMismatch), Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -41,7 +41,6 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/Lambda.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/Module.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/OpenCLOptions.h" @@ -65,6 +64,7 @@ #include "clang/Sema/Sema.h" #include "clang/Sema/Weak.h" #include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/InMemoryModuleCache.h" #include "clang/Serialization/Module.h" #include "clang/Serialization/ModuleFileExtension.h" #include "clang/Serialization/SerializationDiagnostic.h" @@ -4567,10 +4567,11 @@ } ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream, - SmallVectorImpl &Buffer, MemoryBufferCache &PCMCache, + SmallVectorImpl &Buffer, + InMemoryModuleCache &ModuleCache, ArrayRef> Extensions, bool IncludeTimestamps) - : Stream(Stream), Buffer(Buffer), PCMCache(PCMCache), + : Stream(Stream), Buffer(Buffer), ModuleCache(ModuleCache), IncludeTimestamps(IncludeTimestamps) { for (const auto &Ext : Extensions) { if (auto Writer = Ext->createExtensionWriter(*this)) @@ -4620,9 +4621,9 @@ 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()))); + ModuleCache.addBuffer(OutputFile, + llvm::MemoryBuffer::getMemBufferCopy( + StringRef(Buffer.begin(), Buffer.size()))); } return Signature; } Index: clang/lib/Serialization/CMakeLists.txt =================================================================== --- clang/lib/Serialization/CMakeLists.txt +++ clang/lib/Serialization/CMakeLists.txt @@ -14,6 +14,7 @@ ASTWriterStmt.cpp GeneratePCH.cpp GlobalModuleIndex.cpp + InMemoryModuleCache.cpp Module.cpp ModuleFileExtension.cpp ModuleManager.cpp Index: clang/lib/Serialization/GeneratePCH.cpp =================================================================== --- clang/lib/Serialization/GeneratePCH.cpp +++ clang/lib/Serialization/GeneratePCH.cpp @@ -21,13 +21,13 @@ using namespace clang; PCHGenerator::PCHGenerator( - const Preprocessor &PP, StringRef OutputFile, StringRef isysroot, - std::shared_ptr Buffer, + const Preprocessor &PP, InMemoryModuleCache &ModuleCache, + StringRef OutputFile, StringRef isysroot, std::shared_ptr Buffer, ArrayRef> Extensions, bool AllowASTWithErrors, bool IncludeTimestamps) : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()), SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data), - Writer(Stream, this->Buffer->Data, PP.getPCMCache(), Extensions, + Writer(Stream, this->Buffer->Data, ModuleCache, Extensions, IncludeTimestamps), AllowASTWithErrors(AllowASTWithErrors) { this->Buffer->IsComplete = false; Index: clang/lib/Serialization/InMemoryModuleCache.cpp =================================================================== --- /dev/null +++ clang/lib/Serialization/InMemoryModuleCache.cpp @@ -0,0 +1,49 @@ +//===- InMemoryModuleCache.cpp - Cache for loaded memory buffers ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/Serialization/InMemoryModuleCache.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace clang; + +llvm::MemoryBuffer & +InMemoryModuleCache::addBuffer(llvm::StringRef Filename, + std::unique_ptr Buffer) { + auto Insertion = PCMs.insert({Filename, PCM{std::move(Buffer), NextIndex++}}); + assert(Insertion.second && "Already has a buffer"); + return *Insertion.first->second.Buffer; +} + +llvm::MemoryBuffer * +InMemoryModuleCache::lookupBuffer(llvm::StringRef Filename) { + auto I = PCMs.find(Filename); + if (I == PCMs.end()) + return nullptr; + return I->second.Buffer.get(); +} + +bool InMemoryModuleCache::isBufferFinal(llvm::StringRef Filename) { + auto I = PCMs.find(Filename); + if (I == PCMs.end()) + return false; + return I->second.Index < FirstRemovableIndex; +} + +bool InMemoryModuleCache::tryToRemoveBuffer(llvm::StringRef Filename) { + auto I = PCMs.find(Filename); + assert(I != PCMs.end() && "No buffer to remove..."); + if (I->second.Index < FirstRemovableIndex) + return true; + + PCMs.erase(I); + return false; +} + +void InMemoryModuleCache::finalizeCurrentBuffers() { + FirstRemovableIndex = NextIndex; +} Index: clang/lib/Serialization/ModuleManager.cpp =================================================================== --- clang/lib/Serialization/ModuleManager.cpp +++ clang/lib/Serialization/ModuleManager.cpp @@ -14,10 +14,10 @@ #include "clang/Serialization/ModuleManager.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/ModuleMap.h" #include "clang/Serialization/GlobalModuleIndex.h" +#include "clang/Serialization/InMemoryModuleCache.h" #include "clang/Serialization/Module.h" #include "clang/Serialization/PCHContainerOperations.h" #include "llvm/ADT/STLExtras.h" @@ -159,12 +159,13 @@ // Load the contents of the module if (std::unique_ptr Buffer = lookupBuffer(FileName)) { // The buffer was already provided for us. - NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(Buffer)); + NewModule->Buffer = &ModuleCache->addBuffer(FileName, std::move(Buffer)); // Since the cached buffer is reused, it is safe to close the file // descriptor that was opened while stat()ing the PCM in // lookupModuleFile() above, it won't be needed any longer. Entry->closeFile(); - } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(FileName)) { + } else if (llvm::MemoryBuffer *Buffer = + getModuleCache().lookupBuffer(FileName)) { NewModule->Buffer = Buffer; // As above, the file descriptor is no longer needed. Entry->closeFile(); @@ -185,7 +186,7 @@ return Missing; } - NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(*Buf)); + NewModule->Buffer = &getModuleCache().addBuffer(FileName, std::move(*Buf)); } // Initialize the stream. @@ -197,7 +198,7 @@ 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)) + if (!getModuleCache().tryToRemoveBuffer(NewModule->FileName)) FileMgr.invalidateCache(NewModule->File); return OutOfDate; } @@ -267,11 +268,11 @@ // rebuilt (or there was an error). Invalidate them so that we can load the // new files that will be renamed over the old ones. // - // The PCMCache tracks whether the module was successfully loaded in another - // thread/context; in that case, it won't need to be rebuilt (and we can't - // safely invalidate it anyway). + // The ModuleCache tracks whether the module was successfully 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)) + !getModuleCache().tryToRemoveBuffer(victim->FileName)) FileMgr.invalidateCache(victim->File); } @@ -327,11 +328,12 @@ ModulesInCommonWithGlobalIndex.push_back(MF); } -ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache, +ModuleManager::ModuleManager(FileManager &FileMgr, + InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, - const HeaderSearch& HeaderSearchInfo) - : FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(PCHContainerRdr), - HeaderSearchInfo(HeaderSearchInfo) {} + const HeaderSearch &HeaderSearchInfo) + : FileMgr(FileMgr), ModuleCache(&ModuleCache), + PCHContainerRdr(PCHContainerRdr), HeaderSearchInfo(HeaderSearchInfo) {} ModuleManager::~ModuleManager() { delete FirstVisitState; } Index: clang/test/Modules/outofdate-rebuild.m =================================================================== --- clang/test/Modules/outofdate-rebuild.m +++ clang/test/Modules/outofdate-rebuild.m @@ -11,5 +11,5 @@ // RUN: -fsyntax-only // This testcase reproduces a use-after-free in when ModuleManager removes an -// entry from the PCMCache without notifying its parent ASTReader. +// entry from the ModuleCache without notifying its parent ASTReader. @import Cocoa; Index: clang/unittests/Basic/CMakeLists.txt =================================================================== --- clang/unittests/Basic/CMakeLists.txt +++ clang/unittests/Basic/CMakeLists.txt @@ -7,7 +7,6 @@ DiagnosticTest.cpp FileManagerTest.cpp FixedPointTest.cpp - MemoryBufferCacheTest.cpp SourceManagerTest.cpp ) Index: clang/unittests/Basic/SourceManagerTest.cpp =================================================================== --- clang/unittests/Basic/SourceManagerTest.cpp +++ clang/unittests/Basic/SourceManagerTest.cpp @@ -11,7 +11,6 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Lex/HeaderSearch.h" @@ -60,11 +59,10 @@ SourceMgr.setMainFileID(mainFileID); TrivialModuleLoader ModLoader; - MemoryBufferCache PCMCache; HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, Diags, LangOpts, &*Target); Preprocessor PP(std::make_shared(), Diags, LangOpts, - SourceMgr, PCMCache, HeaderInfo, ModLoader, + SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); PP.Initialize(*Target); @@ -229,11 +227,10 @@ SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf)); TrivialModuleLoader ModLoader; - MemoryBufferCache PCMCache; HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, Diags, LangOpts, &*Target); Preprocessor PP(std::make_shared(), Diags, LangOpts, - SourceMgr, PCMCache, HeaderInfo, ModLoader, + SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); PP.Initialize(*Target); @@ -348,11 +345,10 @@ SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf)); TrivialModuleLoader ModLoader; - MemoryBufferCache PCMCache; HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, Diags, LangOpts, &*Target); Preprocessor PP(std::make_shared(), Diags, LangOpts, - SourceMgr, PCMCache, HeaderInfo, ModLoader, + SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); PP.Initialize(*Target); Index: clang/unittests/CMakeLists.txt =================================================================== --- clang/unittests/CMakeLists.txt +++ clang/unittests/CMakeLists.txt @@ -32,3 +32,4 @@ endif() add_subdirectory(Rename) add_subdirectory(Index) +add_subdirectory(Serialization) Index: clang/unittests/Lex/HeaderSearchTest.cpp =================================================================== --- clang/unittests/Lex/HeaderSearchTest.cpp +++ clang/unittests/Lex/HeaderSearchTest.cpp @@ -11,12 +11,12 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Serialization/InMemoryModuleCache.h" #include "gtest/gtest.h" namespace clang { Index: clang/unittests/Lex/LexerTest.cpp =================================================================== --- clang/unittests/Lex/LexerTest.cpp +++ clang/unittests/Lex/LexerTest.cpp @@ -11,7 +11,6 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" @@ -48,12 +47,11 @@ llvm::MemoryBuffer::getMemBuffer(Source); SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); - MemoryBufferCache PCMCache; HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, Diags, LangOpts, Target.get()); std::unique_ptr PP = llvm::make_unique( std::make_shared(), Diags, LangOpts, SourceMgr, - PCMCache, HeaderInfo, ModLoader, + HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); PP->Initialize(*Target); Index: clang/unittests/Lex/PPCallbacksTest.cpp =================================================================== --- clang/unittests/Lex/PPCallbacksTest.cpp +++ clang/unittests/Lex/PPCallbacksTest.cpp @@ -13,7 +13,6 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" @@ -178,14 +177,13 @@ SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); TrivialModuleLoader ModLoader; - MemoryBufferCache PCMCache; HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, Diags, LangOpts, Target.get()); AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader); Preprocessor PP(std::make_shared(), Diags, LangOpts, - SourceMgr, PCMCache, HeaderInfo, ModLoader, + SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); return InclusionDirectiveCallback(PP)->FilenameRange; @@ -198,14 +196,13 @@ SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); TrivialModuleLoader ModLoader; - MemoryBufferCache PCMCache; HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, Diags, LangOpts, Target.get()); AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader); Preprocessor PP(std::make_shared(), Diags, LangOpts, - SourceMgr, PCMCache, HeaderInfo, ModLoader, + SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); return InclusionDirectiveCallback(PP)->FileType; @@ -233,14 +230,13 @@ std::vector DirectiveExprRange(StringRef SourceText) { TrivialModuleLoader ModLoader; - MemoryBufferCache PCMCache; std::unique_ptr Buf = llvm::MemoryBuffer::getMemBuffer(SourceText); SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, Diags, LangOpts, Target.get()); Preprocessor PP(std::make_shared(), Diags, LangOpts, - SourceMgr, PCMCache, HeaderInfo, ModLoader, + SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); PP.Initialize(*Target); @@ -270,12 +266,11 @@ SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf))); TrivialModuleLoader ModLoader; - MemoryBufferCache PCMCache; HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, Diags, OpenCLLangOpts, Target.get()); Preprocessor PP(std::make_shared(), Diags, - OpenCLLangOpts, SourceMgr, PCMCache, HeaderInfo, ModLoader, + OpenCLLangOpts, SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); PP.Initialize(*Target); Index: clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp =================================================================== --- clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp +++ clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp @@ -11,7 +11,6 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" @@ -75,11 +74,10 @@ SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); TrivialModuleLoader ModLoader; - MemoryBufferCache PCMCache; HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, Diags, LangOpts, Target.get()); Preprocessor PP(std::make_shared(), Diags, LangOpts, - SourceMgr, PCMCache, HeaderInfo, ModLoader, + SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); PP.Initialize(*Target); Index: clang/unittests/Serialization/CMakeLists.txt =================================================================== --- /dev/null +++ clang/unittests/Serialization/CMakeLists.txt @@ -0,0 +1,17 @@ +set(LLVM_LINK_COMPONENTS + BitReader + Support + ) + +add_clang_unittest(SerializationTests + InMemoryModuleCacheTest.cpp + ) + +target_link_libraries(SerializationTests + PRIVATE + clangAST + clangBasic + clangLex + clangSema + clangSerialization + ) Index: clang/unittests/Serialization/InMemoryModuleCacheTest.cpp =================================================================== --- clang/unittests/Serialization/InMemoryModuleCacheTest.cpp +++ clang/unittests/Serialization/InMemoryModuleCacheTest.cpp @@ -1,4 +1,4 @@ -//===- MemoryBufferCacheTest.cpp - MemoryBufferCache tests ----------------===// +//===- InMemoryModuleCacheTest.cpp - InMemoryModuleCache tests ------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "clang/Basic/MemoryBufferCache.h" +#include "clang/Serialization/InMemoryModuleCache.h" #include "llvm/Support/MemoryBuffer.h" #include "gtest/gtest.h" @@ -22,7 +22,7 @@ /* RequiresNullTerminator = */ false); } -TEST(MemoryBufferCacheTest, addBuffer) { +TEST(InMemoryModuleCacheTest, addBuffer) { auto B1 = getBuffer(1); auto B2 = getBuffer(2); auto B3 = getBuffer(3); @@ -31,7 +31,7 @@ auto *RawB3 = B3.get(); // Add a few buffers. - MemoryBufferCache Cache; + InMemoryModuleCache Cache; EXPECT_EQ(RawB1, &Cache.addBuffer("1", std::move(B1))); EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2))); EXPECT_EQ(RawB3, &Cache.addBuffer("3", std::move(B3))); @@ -58,9 +58,9 @@ EXPECT_FALSE(Cache.isBufferFinal("3")); } -TEST(MemoryBufferCacheTest, finalizeCurrentBuffers) { +TEST(InMemoryModuleCacheTest, finalizeCurrentBuffers) { // Add a buffer. - MemoryBufferCache Cache; + InMemoryModuleCache Cache; auto B1 = getBuffer(1); auto *RawB1 = B1.get(); Cache.addBuffer("1", std::move(B1));