Browse Source

Modules: Rename MemoryBufferCache to InMemoryModuleCache

Change MemoryBufferCache to InMemoryModuleCache, moving it from Basic to
Serialization.  Another patch will start using it to manage module build
more explicitly, but this is split out because it's mostly mechanical.

Because of the move to Serialization we can no longer abuse the
Preprocessor to forward it to the ASTReader.  Besides the rename and
file move, that means Preprocessor::Preprocessor has one fewer parameter
and ASTReader::ASTReader has one more.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@355777 91177308-0d34-0410-b5e6-96231b3b80d8
Duncan P. N. Exon Smith 6 years ago
parent
commit
d28cf14aed
33 changed files with 227 additions and 217 deletions
  1. 2 2
      include/clang/Frontend/ASTUnit.h
  2. 6 5
      include/clang/Frontend/CompilerInstance.h
  3. 0 4
      include/clang/Lex/Preprocessor.h
  4. 3 6
      include/clang/Serialization/ASTReader.h
  5. 5 4
      include/clang/Serialization/ASTWriter.h
  6. 19 13
      include/clang/Serialization/InMemoryModuleCache.h
  7. 1 1
      include/clang/Serialization/Module.h
  8. 4 4
      include/clang/Serialization/ModuleManager.h
  9. 0 1
      lib/Basic/CMakeLists.txt
  10. 0 47
      lib/Basic/MemoryBufferCache.cpp
  11. 14 14
      lib/Frontend/ASTUnit.cpp
  12. 4 4
      lib/Frontend/ChainedIncludesSource.cpp
  13. 30 32
      lib/Frontend/CompilerInstance.cpp
  14. 11 11
      lib/Frontend/FrontendActions.cpp
  15. 6 3
      lib/Frontend/PrecompiledPreamble.cpp
  16. 1 1
      lib/Frontend/Rewrite/FrontendActions.cpp
  17. 3 3
      lib/Lex/Preprocessor.cpp
  18. 8 9
      lib/Serialization/ASTReader.cpp
  19. 7 6
      lib/Serialization/ASTWriter.cpp
  20. 1 0
      lib/Serialization/CMakeLists.txt
  21. 3 3
      lib/Serialization/GeneratePCH.cpp
  22. 49 0
      lib/Serialization/InMemoryModuleCache.cpp
  23. 15 13
      lib/Serialization/ModuleManager.cpp
  24. 1 1
      test/Modules/outofdate-rebuild.m
  25. 0 1
      unittests/Basic/CMakeLists.txt
  26. 3 7
      unittests/Basic/SourceManagerTest.cpp
  27. 1 0
      unittests/CMakeLists.txt
  28. 1 1
      unittests/Lex/HeaderSearchTest.cpp
  29. 1 3
      unittests/Lex/LexerTest.cpp
  30. 4 9
      unittests/Lex/PPCallbacksTest.cpp
  31. 1 3
      unittests/Lex/PPConditionalDirectiveRecordTest.cpp
  32. 17 0
      unittests/Serialization/CMakeLists.txt
  33. 6 6
      unittests/Serialization/InMemoryModuleCacheTest.cpp

+ 2 - 2
include/clang/Frontend/ASTUnit.h

@@ -71,7 +71,7 @@ class FileManager;
 class FrontendAction;
 class FrontendAction;
 class HeaderSearch;
 class HeaderSearch;
 class InputKind;
 class InputKind;
-class MemoryBufferCache;
+class InMemoryModuleCache;
 class PCHContainerOperations;
 class PCHContainerOperations;
 class PCHContainerReader;
 class PCHContainerReader;
 class Preprocessor;
 class Preprocessor;
@@ -107,7 +107,7 @@ private:
   IntrusiveRefCntPtr<DiagnosticsEngine>   Diagnostics;
   IntrusiveRefCntPtr<DiagnosticsEngine>   Diagnostics;
   IntrusiveRefCntPtr<FileManager>         FileMgr;
   IntrusiveRefCntPtr<FileManager>         FileMgr;
   IntrusiveRefCntPtr<SourceManager>       SourceMgr;
   IntrusiveRefCntPtr<SourceManager>       SourceMgr;
-  IntrusiveRefCntPtr<MemoryBufferCache>   PCMCache;
+  IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
   std::unique_ptr<HeaderSearch>           HeaderInfo;
   std::unique_ptr<HeaderSearch>           HeaderInfo;
   IntrusiveRefCntPtr<TargetInfo>          Target;
   IntrusiveRefCntPtr<TargetInfo>          Target;
   std::shared_ptr<Preprocessor>           PP;
   std::shared_ptr<Preprocessor>           PP;

+ 6 - 5
include/clang/Frontend/CompilerInstance.h

@@ -44,7 +44,7 @@ class ExternalASTSource;
 class FileEntry;
 class FileEntry;
 class FileManager;
 class FileManager;
 class FrontendAction;
 class FrontendAction;
-class MemoryBufferCache;
+class InMemoryModuleCache;
 class Module;
 class Module;
 class Preprocessor;
 class Preprocessor;
 class Sema;
 class Sema;
@@ -92,7 +92,7 @@ class CompilerInstance : public ModuleLoader {
   IntrusiveRefCntPtr<SourceManager> SourceMgr;
   IntrusiveRefCntPtr<SourceManager> SourceMgr;
 
 
   /// The cache of PCM files.
   /// The cache of PCM files.
-  IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
+  IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
 
 
   /// The preprocessor.
   /// The preprocessor.
   std::shared_ptr<Preprocessor> PP;
   std::shared_ptr<Preprocessor> PP;
@@ -192,7 +192,7 @@ public:
   explicit CompilerInstance(
   explicit CompilerInstance(
       std::shared_ptr<PCHContainerOperations> PCHContainerOps =
       std::shared_ptr<PCHContainerOperations> PCHContainerOps =
           std::make_shared<PCHContainerOperations>(),
           std::make_shared<PCHContainerOperations>(),
-      MemoryBufferCache *SharedPCMCache = nullptr);
+      InMemoryModuleCache *SharedModuleCache = nullptr);
   ~CompilerInstance() override;
   ~CompilerInstance() override;
 
 
   /// @name High-Level Operations
   /// @name High-Level Operations
@@ -671,7 +671,8 @@ public:
   /// \return - The new object on success, or null on failure.
   /// \return - The new object on success, or null on failure.
   static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
   static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
       StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
       StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
-      bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
+      bool AllowPCHWithCompilerErrors, Preprocessor &PP,
+      InMemoryModuleCache &ModuleCache, ASTContext &Context,
       const PCHContainerReader &PCHContainerRdr,
       const PCHContainerReader &PCHContainerRdr,
       ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
       ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
       DependencyFileGenerator *DependencyFile,
       DependencyFileGenerator *DependencyFile,
@@ -813,7 +814,7 @@ public:
 
 
   void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
   void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
 
 
-  MemoryBufferCache &getPCMCache() const { return *PCMCache; }
+  InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
 };
 };
 
 
 } // end namespace clang
 } // end namespace clang

+ 0 - 4
include/clang/Lex/Preprocessor.h

@@ -71,7 +71,6 @@ class FileEntry;
 class FileManager;
 class FileManager;
 class HeaderSearch;
 class HeaderSearch;
 class MacroArgs;
 class MacroArgs;
-class MemoryBufferCache;
 class PragmaHandler;
 class PragmaHandler;
 class PragmaNamespace;
 class PragmaNamespace;
 class PreprocessingRecord;
 class PreprocessingRecord;
@@ -132,7 +131,6 @@ class Preprocessor {
   const TargetInfo *AuxTarget = nullptr;
   const TargetInfo *AuxTarget = nullptr;
   FileManager       &FileMgr;
   FileManager       &FileMgr;
   SourceManager     &SourceMgr;
   SourceManager     &SourceMgr;
-  MemoryBufferCache &PCMCache;
   std::unique_ptr<ScratchBuffer> ScratchBuf;
   std::unique_ptr<ScratchBuffer> ScratchBuf;
   HeaderSearch      &HeaderInfo;
   HeaderSearch      &HeaderInfo;
   ModuleLoader      &TheModuleLoader;
   ModuleLoader      &TheModuleLoader;
@@ -779,7 +777,6 @@ private:
 public:
 public:
   Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
   Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
                DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM,
                DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM,
-               MemoryBufferCache &PCMCache,
                HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
                HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
                IdentifierInfoLookup *IILookup = nullptr,
                IdentifierInfoLookup *IILookup = nullptr,
                bool OwnsHeaderSearch = false,
                bool OwnsHeaderSearch = false,
@@ -819,7 +816,6 @@ public:
   const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
   const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
   FileManager &getFileManager() const { return FileMgr; }
   FileManager &getFileManager() const { return FileMgr; }
   SourceManager &getSourceManager() const { return SourceMgr; }
   SourceManager &getSourceManager() const { return SourceMgr; }
-  MemoryBufferCache &getPCMCache() const { return PCMCache; }
   HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
   HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
 
 
   IdentifierTable &getIdentifierTable() { return Identifiers; }
   IdentifierTable &getIdentifierTable() { return Identifiers; }

+ 3 - 6
include/clang/Serialization/ASTReader.h

@@ -97,7 +97,7 @@ class HeaderSearchOptions;
 class LangOptions;
 class LangOptions;
 class LazyASTUnresolvedSet;
 class LazyASTUnresolvedSet;
 class MacroInfo;
 class MacroInfo;
-class MemoryBufferCache;
+class InMemoryModuleCache;
 class NamedDecl;
 class NamedDecl;
 class NamespaceDecl;
 class NamespaceDecl;
 class ObjCCategoryDecl;
 class ObjCCategoryDecl;
@@ -440,9 +440,6 @@ private:
   /// The module manager which manages modules and their dependencies
   /// The module manager which manages modules and their dependencies
   ModuleManager ModuleMgr;
   ModuleManager ModuleMgr;
 
 
-  /// The cache that manages memory buffers for PCM files.
-  MemoryBufferCache &PCMCache;
-
   /// A dummy identifier resolver used to merge TU-scope declarations in
   /// 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
   /// C, for the cases where we don't have a Sema object to provide a real
   /// identifier resolver.
   /// identifier resolver.
@@ -1481,8 +1478,8 @@ public:
   ///
   ///
   /// \param ReadTimer If non-null, a timer used to track the time spent
   /// \param ReadTimer If non-null, a timer used to track the time spent
   /// deserializing.
   /// deserializing.
-  ASTReader(Preprocessor &PP, ASTContext *Context,
-            const PCHContainerReader &PCHContainerRdr,
+  ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
+            ASTContext *Context, const PCHContainerReader &PCHContainerRdr,
             ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
             ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
             StringRef isysroot = "", bool DisableValidation = false,
             StringRef isysroot = "", bool DisableValidation = false,
             bool AllowASTWithCompilerErrors = false,
             bool AllowASTWithCompilerErrors = false,

+ 5 - 4
include/clang/Serialization/ASTWriter.h

@@ -74,8 +74,8 @@ class IdentifierResolver;
 class LangOptions;
 class LangOptions;
 class MacroDefinitionRecord;
 class MacroDefinitionRecord;
 class MacroInfo;
 class MacroInfo;
-class MemoryBufferCache;
 class Module;
 class Module;
+class InMemoryModuleCache;
 class ModuleFileExtension;
 class ModuleFileExtension;
 class ModuleFileExtensionWriter;
 class ModuleFileExtensionWriter;
 class NamedDecl;
 class NamedDecl;
@@ -132,7 +132,7 @@ private:
   const SmallVectorImpl<char> &Buffer;
   const SmallVectorImpl<char> &Buffer;
 
 
   /// The PCM manager which manages memory buffers for pcm files.
   /// The PCM manager which manages memory buffers for pcm files.
-  MemoryBufferCache &PCMCache;
+  InMemoryModuleCache &ModuleCache;
 
 
   /// The ASTContext we're writing.
   /// The ASTContext we're writing.
   ASTContext *Context = nullptr;
   ASTContext *Context = nullptr;
@@ -542,7 +542,7 @@ public:
   /// Create a new precompiled header writer that outputs to
   /// Create a new precompiled header writer that outputs to
   /// the given bitstream.
   /// the given bitstream.
   ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
   ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
-            MemoryBufferCache &PCMCache,
+            InMemoryModuleCache &ModuleCache,
             ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
             ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
             bool IncludeTimestamps = true);
             bool IncludeTimestamps = true);
   ~ASTWriter() override;
   ~ASTWriter() override;
@@ -981,7 +981,8 @@ protected:
   SmallVectorImpl<char> &getPCH() const { return Buffer->Data; }
   SmallVectorImpl<char> &getPCH() const { return Buffer->Data; }
 
 
 public:
 public:
-  PCHGenerator(const Preprocessor &PP, StringRef OutputFile, StringRef isysroot,
+  PCHGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
+               StringRef OutputFile, StringRef isysroot,
                std::shared_ptr<PCHBuffer> Buffer,
                std::shared_ptr<PCHBuffer> Buffer,
                ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
                ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
                bool AllowASTWithErrors = false, bool IncludeTimestamps = true);
                bool AllowASTWithErrors = false, bool IncludeTimestamps = true);

+ 19 - 13
include/clang/Basic/MemoryBufferCache.h → 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.
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
 // 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/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringMap.h"
 #include <memory>
 #include <memory>
 
 
@@ -19,17 +20,22 @@ class MemoryBuffer;
 
 
 namespace clang {
 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.
 /// \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<MemoryBufferCache> {
-  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<InMemoryModuleCache> {
+  struct PCM {
     std::unique_ptr<llvm::MemoryBuffer> Buffer;
     std::unique_ptr<llvm::MemoryBuffer> Buffer;
 
 
     /// Track the timeline of when this was added to the cache.
     /// Track the timeline of when this was added to the cache.
@@ -37,7 +43,7 @@ class MemoryBufferCache : public llvm::RefCountedBase<MemoryBufferCache> {
   };
   };
 
 
   /// Cache of buffers.
   /// Cache of buffers.
-  llvm::StringMap<BufferEntry> Buffers;
+  llvm::StringMap<PCM> PCMs;
 
 
   /// Monotonically increasing index.
   /// Monotonically increasing index.
   unsigned NextIndex = 0;
   unsigned NextIndex = 0;
@@ -76,4 +82,4 @@ public:
 
 
 } // end namespace clang
 } // end namespace clang
 
 
-#endif // LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
+#endif // LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H

+ 1 - 1
include/clang/Serialization/Module.h

@@ -174,7 +174,7 @@ public:
   unsigned Generation;
   unsigned Generation;
 
 
   /// The memory buffer that stores the data associated with
   /// 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;
   llvm::MemoryBuffer *Buffer;
 
 
   /// The size of this file, in bits.
   /// The size of this file, in bits.

+ 4 - 4
include/clang/Serialization/ModuleManager.h

@@ -38,7 +38,7 @@ class FileEntry;
 class FileManager;
 class FileManager;
 class GlobalModuleIndex;
 class GlobalModuleIndex;
 class HeaderSearch;
 class HeaderSearch;
-class MemoryBufferCache;
+class InMemoryModuleCache;
 class ModuleMap;
 class ModuleMap;
 class PCHContainerReader;
 class PCHContainerReader;
 
 
@@ -67,7 +67,7 @@ class ModuleManager {
   FileManager &FileMgr;
   FileManager &FileMgr;
 
 
   /// Cache of PCM files.
   /// Cache of PCM files.
-  IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
+  IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
 
 
   /// Knows how to unwrap module containers.
   /// Knows how to unwrap module containers.
   const PCHContainerReader &PCHContainerRdr;
   const PCHContainerReader &PCHContainerRdr;
@@ -139,7 +139,7 @@ public:
       SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>;
       SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>;
   using ModuleOffset = std::pair<uint32_t, StringRef>;
   using ModuleOffset = std::pair<uint32_t, StringRef>;
 
 
-  explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
+  explicit ModuleManager(FileManager &FileMgr, InMemoryModuleCache &ModuleCache,
                          const PCHContainerReader &PCHContainerRdr,
                          const PCHContainerReader &PCHContainerRdr,
                          const HeaderSearch &HeaderSearchInfo);
                          const HeaderSearch &HeaderSearchInfo);
   ~ModuleManager();
   ~ModuleManager();
@@ -317,7 +317,7 @@ public:
   /// View the graphviz representation of the module graph.
   /// View the graphviz representation of the module graph.
   void viewGraph();
   void viewGraph();
 
 
-  MemoryBufferCache &getPCMCache() const { return *PCMCache; }
+  InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
 };
 };
 
 
 } // namespace serialization
 } // namespace serialization

+ 0 - 1
lib/Basic/CMakeLists.txt

@@ -50,7 +50,6 @@ add_clang_library(clangBasic
   FixedPoint.cpp
   FixedPoint.cpp
   IdentifierTable.cpp
   IdentifierTable.cpp
   LangOptions.cpp
   LangOptions.cpp
-  MemoryBufferCache.cpp
   Module.cpp
   Module.cpp
   ObjCRuntime.cpp
   ObjCRuntime.cpp
   OpenMPKinds.cpp
   OpenMPKinds.cpp

+ 0 - 47
lib/Basic/MemoryBufferCache.cpp

@@ -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<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; }

+ 14 - 14
lib/Frontend/ASTUnit.cpp

@@ -30,7 +30,6 @@
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManager.h"
@@ -60,6 +59,7 @@
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/ASTWriter.h"
 #include "clang/Serialization/ASTWriter.h"
 #include "clang/Serialization/ContinuousRangeMap.h"
 #include "clang/Serialization/ContinuousRangeMap.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
 #include "clang/Serialization/Module.h"
 #include "clang/Serialization/Module.h"
 #include "clang/Serialization/PCHContainerOperations.h"
 #include "clang/Serialization/PCHContainerOperations.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -217,8 +217,8 @@ struct ASTUnit::ASTWriterData {
   llvm::BitstreamWriter Stream;
   llvm::BitstreamWriter Stream;
   ASTWriter Writer;
   ASTWriter Writer;
 
 
-  ASTWriterData(MemoryBufferCache &PCMCache)
-      : Stream(Buffer), Writer(Stream, Buffer, PCMCache, {}) {}
+  ASTWriterData(InMemoryModuleCache &ModuleCache)
+      : Stream(Buffer), Writer(Stream, Buffer, ModuleCache, {}) {}
 };
 };
 
 
 void ASTUnit::clearFileLevelDecls() {
 void ASTUnit::clearFileLevelDecls() {
@@ -758,7 +758,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
                                      AST->getFileManager(),
                                      AST->getFileManager(),
                                      UserFilesAreVolatile);
                                      UserFilesAreVolatile);
-  AST->PCMCache = new MemoryBufferCache;
+  AST->ModuleCache = new InMemoryModuleCache;
   AST->HSOpts = std::make_shared<HeaderSearchOptions>();
   AST->HSOpts = std::make_shared<HeaderSearchOptions>();
   AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat();
   AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat();
   AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
   AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
@@ -778,7 +778,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
 
 
   AST->PP = std::make_shared<Preprocessor>(
   AST->PP = std::make_shared<Preprocessor>(
       AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
       AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
-      AST->getSourceManager(), *AST->PCMCache, HeaderInfo, AST->ModuleLoader,
+      AST->getSourceManager(), HeaderInfo, AST->ModuleLoader,
       /*IILookup=*/nullptr,
       /*IILookup=*/nullptr,
       /*OwnsHeaderSearch=*/false);
       /*OwnsHeaderSearch=*/false);
   Preprocessor &PP = *AST->PP;
   Preprocessor &PP = *AST->PP;
@@ -791,10 +791,10 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
   bool disableValid = false;
   bool disableValid = false;
   if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
   if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
     disableValid = true;
     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<ASTInfoCollector>(
   AST->Reader->setListener(llvm::make_unique<ASTInfoCollector>(
       *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
       *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
@@ -1477,7 +1477,7 @@ ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
                                      UserFilesAreVolatile);
                                      UserFilesAreVolatile);
-  AST->PCMCache = new MemoryBufferCache;
+  AST->ModuleCache = new InMemoryModuleCache;
 
 
   return AST;
   return AST;
 }
 }
@@ -1757,7 +1757,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
     VFS = llvm::vfs::getRealFileSystem();
     VFS = llvm::vfs::getRealFileSystem();
   VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
   VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
   AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
   AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
-  AST->PCMCache = new MemoryBufferCache;
+  AST->ModuleCache = new InMemoryModuleCache;
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
   AST->CaptureDiagnostics = CaptureDiagnostics;
   AST->TUKind = TUKind;
   AST->TUKind = TUKind;
@@ -1768,7 +1768,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
   AST->Invocation = CI;
   AST->Invocation = CI;
   AST->SkipFunctionBodies = SkipFunctionBodies;
   AST->SkipFunctionBodies = SkipFunctionBodies;
   if (ForSerialization)
   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.
   // Zero out now to ease cleanup during crash recovery.
   CI = nullptr;
   CI = nullptr;
   Diags = nullptr;
   Diags = nullptr;
@@ -2317,8 +2317,8 @@ bool ASTUnit::serialize(raw_ostream &OS) {
 
 
   SmallString<128> Buffer;
   SmallString<128> Buffer;
   llvm::BitstreamWriter Stream(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);
   return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
 }
 }
 
 

+ 4 - 4
lib/Frontend/ChainedIncludesSource.cpp

@@ -82,9 +82,9 @@ createASTReader(CompilerInstance &CI, StringRef pchFile,
                 ASTDeserializationListener *deserialListener = nullptr) {
                 ASTDeserializationListener *deserialListener = nullptr) {
   Preprocessor &PP = CI.getPreprocessor();
   Preprocessor &PP = CI.getPreprocessor();
   std::unique_ptr<ASTReader> Reader;
   std::unique_ptr<ASTReader> Reader;
-  Reader.reset(new ASTReader(PP, &CI.getASTContext(),
+  Reader.reset(new ASTReader(PP, CI.getModuleCache(), &CI.getASTContext(),
                              CI.getPCHContainerReader(),
                              CI.getPCHContainerReader(),
-                             /*Extensions=*/{ },
+                             /*Extensions=*/{},
                              /*isysroot=*/"", /*DisableValidation=*/true));
                              /*isysroot=*/"", /*DisableValidation=*/true));
   for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
   for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
     StringRef sr(bufNames[ti]);
     StringRef sr(bufNames[ti]);
@@ -159,8 +159,8 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
     auto Buffer = std::make_shared<PCHBuffer>();
     auto Buffer = std::make_shared<PCHBuffer>();
     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions;
     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions;
     auto consumer = llvm::make_unique<PCHGenerator>(
     auto consumer = llvm::make_unique<PCHGenerator>(
-        Clang->getPreprocessor(), "-", /*isysroot=*/"", Buffer,
-        Extensions, /*AllowASTWithErrors=*/true);
+        Clang->getPreprocessor(), Clang->getModuleCache(), "-", /*isysroot=*/"",
+        Buffer, Extensions, /*AllowASTWithErrors=*/true);
     Clang->getASTContext().setASTMutationListener(
     Clang->getASTContext().setASTMutationListener(
                                             consumer->GetASTMutationListener());
                                             consumer->GetASTMutationListener());
     Clang->setASTConsumer(std::move(consumer));
     Clang->setASTConsumer(std::move(consumer));

+ 30 - 32
lib/Frontend/CompilerInstance.cpp

@@ -13,7 +13,6 @@
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileManager.h"
-#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Stack.h"
 #include "clang/Basic/Stack.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetInfo.h"
@@ -35,6 +34,7 @@
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/Sema.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/BuryPointer.h"
 #include "llvm/Support/BuryPointer.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/CrashRecoveryContext.h"
@@ -57,14 +57,15 @@ using namespace clang;
 
 
 CompilerInstance::CompilerInstance(
 CompilerInstance::CompilerInstance(
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
-    MemoryBufferCache *SharedPCMCache)
-    : ModuleLoader(/* BuildingModule = */ SharedPCMCache),
+    InMemoryModuleCache *SharedModuleCache)
+    : ModuleLoader(/* BuildingModule = */ SharedModuleCache),
       Invocation(new CompilerInvocation()),
       Invocation(new CompilerInvocation()),
-      PCMCache(SharedPCMCache ? SharedPCMCache : new MemoryBufferCache),
+      ModuleCache(SharedModuleCache ? SharedModuleCache
+                                    : new InMemoryModuleCache),
       ThePCHContainerOperations(std::move(PCHContainerOps)) {
       ThePCHContainerOperations(std::move(PCHContainerOps)) {
   // Don't allow this to invalidate buffers in use by others.
   // Don't allow this to invalidate buffers in use by others.
-  if (SharedPCMCache)
-    getPCMCache().finalizeCurrentBuffers();
+  if (SharedModuleCache)
+    getModuleCache().finalizeCurrentBuffers();
 }
 }
 
 
 CompilerInstance::~CompilerInstance() {
 CompilerInstance::~CompilerInstance() {
@@ -136,7 +137,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const {
   return ModuleManager;
   return ModuleManager;
 }
 }
 void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) {
 void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) {
-  assert(PCMCache.get() == &Reader->getModuleManager().getPCMCache() &&
+  assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() &&
          "Expected ASTReader to use the same PCM cache");
          "Expected ASTReader to use the same PCM cache");
   ModuleManager = std::move(Reader);
   ModuleManager = std::move(Reader);
 }
 }
@@ -378,11 +379,11 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
   HeaderSearch *HeaderInfo =
   HeaderSearch *HeaderInfo =
       new HeaderSearch(getHeaderSearchOptsPtr(), getSourceManager(),
       new HeaderSearch(getHeaderSearchOptsPtr(), getSourceManager(),
                        getDiagnostics(), getLangOpts(), &getTarget());
                        getDiagnostics(), getLangOpts(), &getTarget());
-  PP = std::make_shared<Preprocessor>(
-      Invocation->getPreprocessorOptsPtr(), getDiagnostics(), getLangOpts(),
-      getSourceManager(), getPCMCache(), *HeaderInfo, *this,
-      /*IdentifierInfoLookup=*/nullptr,
-      /*OwnsHeaderSearch=*/true, TUKind);
+  PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOptsPtr(),
+                                      getDiagnostics(), getLangOpts(),
+                                      getSourceManager(), *HeaderInfo, *this,
+                                      /*IdentifierInfoLookup=*/nullptr,
+                                      /*OwnsHeaderSearch=*/true, TUKind);
   getTarget().adjust(getLangOpts());
   getTarget().adjust(getLangOpts());
   PP->Initialize(getTarget(), getAuxTarget());
   PP->Initialize(getTarget(), getAuxTarget());
 
 
@@ -489,19 +490,17 @@ void CompilerInstance::createPCHExternalASTSource(
   bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
   bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
   ModuleManager = createPCHExternalASTSource(
   ModuleManager = createPCHExternalASTSource(
       Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
       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<ASTReader> CompilerInstance::createPCHExternalASTSource(
 IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
     StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
     StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
-    bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
+    bool AllowPCHWithCompilerErrors, Preprocessor &PP,
+    InMemoryModuleCache &ModuleCache, ASTContext &Context,
     const PCHContainerReader &PCHContainerRdr,
     const PCHContainerReader &PCHContainerRdr,
     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
     DependencyFileGenerator *DependencyFile,
     DependencyFileGenerator *DependencyFile,
@@ -511,7 +510,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
   HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
   HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
 
 
   IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
   IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
-      PP, &Context, PCHContainerRdr, Extensions,
+      PP, ModuleCache, &Context, PCHContainerRdr, Extensions,
       Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation,
       Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation,
       AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,
       AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,
       HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex));
       HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex));
@@ -1094,11 +1093,11 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
          Invocation->getModuleHash() && "Module hash mismatch!");
          Invocation->getModuleHash() && "Module hash mismatch!");
 
 
   // Construct a compiler instance that will be used to actually create the
   // 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
   // CompilerInstance::CompilerInstance is responsible for finalizing the
   // buffers to prevent use-after-frees.
   // buffers to prevent use-after-frees.
   CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(),
   CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(),
-                            &ImportingInstance.getPreprocessor().getPCMCache());
+                            &ImportingInstance.getModuleCache());
   auto &Inv = *Invocation;
   auto &Inv = *Invocation;
   Instance.setInvocation(std::move(Invocation));
   Instance.setInvocation(std::move(Invocation));
 
 
@@ -1255,7 +1254,7 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
     llvm::LockFileManager Locked(ModuleFileName);
     llvm::LockFileManager Locked(ModuleFileName);
     switch (Locked) {
     switch (Locked) {
     case llvm::LockFileManager::LFS_Error:
     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
       // performance. Fallback to building the module in case of any lock
       // related errors.
       // related errors.
       Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure)
       Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure)
@@ -1282,9 +1281,9 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
       case llvm::LockFileManager::Res_OwnerDied:
       case llvm::LockFileManager::Res_OwnerDied:
         continue; // try again to get the lock.
         continue; // try again to get the lock.
       case llvm::LockFileManager::Res_Timeout:
       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)
         Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout)
             << Module->Name;
             << Module->Name;
         // Clear the lock file so that future invocations can make progress.
         // Clear the lock file so that future invocations can make progress.
@@ -1482,14 +1481,13 @@ void CompilerInstance::createModuleManager() {
                                                  "Reading modules",
                                                  "Reading modules",
                                                  *FrontendTimerGroup);
                                                  *FrontendTimerGroup);
     ModuleManager = new ASTReader(
     ModuleManager = new ASTReader(
-        getPreprocessor(), &getASTContext(), getPCHContainerReader(),
-        getFrontendOpts().ModuleFileExtensions,
+        getPreprocessor(), getModuleCache(), &getASTContext(),
+        getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions,
         Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation,
         Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation,
         /*AllowASTWithCompilerErrors=*/false,
         /*AllowASTWithCompilerErrors=*/false,
         /*AllowConfigurationMismatch=*/false,
         /*AllowConfigurationMismatch=*/false,
         HSOpts.ModulesValidateSystemHeaders,
         HSOpts.ModulesValidateSystemHeaders,
-        getFrontendOpts().UseGlobalModuleIndex,
-        std::move(ReadTimer));
+        getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer));
     if (hasASTConsumer()) {
     if (hasASTConsumer()) {
       ModuleManager->setDeserializationListener(
       ModuleManager->setDeserializationListener(
         getASTConsumer().GetASTDeserializationListener());
         getASTConsumer().GetASTDeserializationListener());

+ 11 - 11
lib/Frontend/FrontendActions.cpp

@@ -109,10 +109,10 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   auto Buffer = std::make_shared<PCHBuffer>();
   auto Buffer = std::make_shared<PCHBuffer>();
   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
   Consumers.push_back(llvm::make_unique<PCHGenerator>(
   Consumers.push_back(llvm::make_unique<PCHGenerator>(
-                        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(
   Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
       CI, InFile, OutputFile, std::move(OS), Buffer));
       CI, InFile, OutputFile, std::move(OS), Buffer));
 
 
@@ -172,11 +172,11 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
 
 
   Consumers.push_back(llvm::make_unique<PCHGenerator>(
   Consumers.push_back(llvm::make_unique<PCHGenerator>(
-                        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(
   Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
       CI, InFile, OutputFile, std::move(OS), Buffer));
       CI, InFile, OutputFile, std::move(OS), Buffer));
   return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
   return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
@@ -329,8 +329,8 @@ void VerifyPCHAction::ExecuteAction() {
   bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
   bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
   const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
   const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
   std::unique_ptr<ASTReader> Reader(new ASTReader(
   std::unique_ptr<ASTReader> 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(),
       Sysroot.empty() ? "" : Sysroot.c_str(),
       /*DisableValidation*/ false,
       /*DisableValidation*/ false,
       /*AllowPCHWithCompilerErrors*/ false,
       /*AllowPCHWithCompilerErrors*/ false,

+ 6 - 3
lib/Frontend/PrecompiledPreamble.cpp

@@ -157,9 +157,12 @@ private:
 class PrecompilePreambleConsumer : public PCHGenerator {
 class PrecompilePreambleConsumer : public PCHGenerator {
 public:
 public:
   PrecompilePreambleConsumer(PrecompilePreambleAction &Action,
   PrecompilePreambleConsumer(PrecompilePreambleAction &Action,
-                             const Preprocessor &PP, StringRef isysroot,
+                             const Preprocessor &PP,
+                             InMemoryModuleCache &ModuleCache,
+                             StringRef isysroot,
                              std::unique_ptr<raw_ostream> Out)
                              std::unique_ptr<raw_ostream> Out)
-      : PCHGenerator(PP, "", isysroot, std::make_shared<PCHBuffer>(),
+      : PCHGenerator(PP, ModuleCache, "", isysroot,
+                     std::make_shared<PCHBuffer>(),
                      ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
                      ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
                      /*AllowASTWithErrors=*/true),
                      /*AllowASTWithErrors=*/true),
         Action(Action), Out(std::move(Out)) {}
         Action(Action), Out(std::move(Out)) {}
@@ -211,7 +214,7 @@ PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
     Sysroot.clear();
     Sysroot.clear();
 
 
   return llvm::make_unique<PrecompilePreambleConsumer>(
   return llvm::make_unique<PrecompilePreambleConsumer>(
-      *this, CI.getPreprocessor(), Sysroot, std::move(OS));
+      *this, CI.getPreprocessor(), CI.getModuleCache(), Sysroot, std::move(OS));
 }
 }
 
 
 template <class T> bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
 template <class T> bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {

+ 1 - 1
lib/Frontend/Rewrite/FrontendActions.cpp

@@ -237,7 +237,7 @@ public:
 
 
     // Rewrite the contents of the module in a separate compiler instance.
     // Rewrite the contents of the module in a separate compiler instance.
     CompilerInstance Instance(CI.getPCHContainerOperations(),
     CompilerInstance Instance(CI.getPCHContainerOperations(),
-                              &CI.getPreprocessor().getPCMCache());
+                              &CI.getModuleCache());
     Instance.setInvocation(
     Instance.setInvocation(
         std::make_shared<CompilerInvocation>(CI.getInvocation()));
         std::make_shared<CompilerInvocation>(CI.getInvocation()));
     Instance.createDiagnostics(
     Instance.createDiagnostics(

+ 3 - 3
lib/Lex/Preprocessor.cpp

@@ -77,12 +77,12 @@ ExternalPreprocessorSource::~ExternalPreprocessorSource() = default;
 
 
 Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
 Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
                            DiagnosticsEngine &diags, LangOptions &opts,
                            DiagnosticsEngine &diags, LangOptions &opts,
-                           SourceManager &SM, MemoryBufferCache &PCMCache,
-                           HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
+                           SourceManager &SM, HeaderSearch &Headers,
+                           ModuleLoader &TheModuleLoader,
                            IdentifierInfoLookup *IILookup, bool OwnsHeaders,
                            IdentifierInfoLookup *IILookup, bool OwnsHeaders,
                            TranslationUnitKind TUKind)
                            TranslationUnitKind TUKind)
     : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts),
     : 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),
       ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers),
       TheModuleLoader(TheModuleLoader), ExternalSource(nullptr),
       TheModuleLoader(TheModuleLoader), ExternalSource(nullptr),
       // As the language options may have not been loaded yet (when
       // As the language options may have not been loaded yet (when

+ 8 - 9
lib/Serialization/ASTReader.cpp

@@ -46,7 +46,6 @@
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/OperatorKinds.h"
@@ -76,6 +75,7 @@
 #include "clang/Serialization/ASTDeserializationListener.h"
 #include "clang/Serialization/ASTDeserializationListener.h"
 #include "clang/Serialization/ContinuousRangeMap.h"
 #include "clang/Serialization/ContinuousRangeMap.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
 #include "clang/Serialization/Module.h"
 #include "clang/Serialization/Module.h"
 #include "clang/Serialization/ModuleFileExtension.h"
 #include "clang/Serialization/ModuleFileExtension.h"
 #include "clang/Serialization/ModuleManager.h"
 #include "clang/Serialization/ModuleManager.h"
@@ -4291,7 +4291,7 @@ ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
   }
   }
 
 
   if (Result == OutOfDate && F.Kind == MK_ImplicitModule) {
   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.
     // 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
     // This can happen when a module is imported in two contexts: in one, as a
@@ -4309,7 +4309,7 @@ ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
     // validation will fail during the as-system import since the PCM on disk
     // validation will fail during the as-system import since the PCM on disk
     // doesn't guarantee that -Werror was respected.  However, the -Werror
     // doesn't guarantee that -Werror was respected.  However, the -Werror
     // flags were checked during the initial as-user import.
     // 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;
       Diag(diag::warn_module_system_bit_conflict) << F.FileName;
       return Success;
       return Success;
     }
     }
@@ -11606,7 +11606,8 @@ void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
   }
   }
 }
 }
 
 
-ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
+ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
+                     ASTContext *Context,
                      const PCHContainerReader &PCHContainerRdr,
                      const PCHContainerReader &PCHContainerRdr,
                      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
                      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
                      StringRef isysroot, bool DisableValidation,
                      StringRef isysroot, bool DisableValidation,
@@ -11619,11 +11620,9 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
                    : cast<ASTReaderListener>(new PCHValidator(PP, *this))),
                    : cast<ASTReaderListener>(new PCHValidator(PP, *this))),
       SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
       SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
       PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP),
       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),
       DisableValidation(DisableValidation),
       AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
       AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
       AllowConfigurationMismatch(AllowConfigurationMismatch),
       AllowConfigurationMismatch(AllowConfigurationMismatch),

+ 7 - 6
lib/Serialization/ASTWriter.cpp

@@ -41,7 +41,6 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/Lambda.h"
 #include "clang/Basic/Lambda.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/OpenCLOptions.h"
 #include "clang/Basic/OpenCLOptions.h"
@@ -65,6 +64,7 @@
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/Weak.h"
 #include "clang/Sema/Weak.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/ASTReader.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
 #include "clang/Serialization/Module.h"
 #include "clang/Serialization/Module.h"
 #include "clang/Serialization/ModuleFileExtension.h"
 #include "clang/Serialization/ModuleFileExtension.h"
 #include "clang/Serialization/SerializationDiagnostic.h"
 #include "clang/Serialization/SerializationDiagnostic.h"
@@ -4568,10 +4568,11 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
 }
 }
 
 
 ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
 ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
-                     SmallVectorImpl<char> &Buffer, MemoryBufferCache &PCMCache,
+                     SmallVectorImpl<char> &Buffer,
+                     InMemoryModuleCache &ModuleCache,
                      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
                      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
                      bool IncludeTimestamps)
                      bool IncludeTimestamps)
-    : Stream(Stream), Buffer(Buffer), PCMCache(PCMCache),
+    : Stream(Stream), Buffer(Buffer), ModuleCache(ModuleCache),
       IncludeTimestamps(IncludeTimestamps) {
       IncludeTimestamps(IncludeTimestamps) {
   for (const auto &Ext : Extensions) {
   for (const auto &Ext : Extensions) {
     if (auto Writer = Ext->createExtensionWriter(*this))
     if (auto Writer = Ext->createExtensionWriter(*this))
@@ -4621,9 +4622,9 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
   WritingAST = false;
   WritingAST = false;
   if (SemaRef.Context.getLangOpts().ImplicitModules && WritingModule) {
   if (SemaRef.Context.getLangOpts().ImplicitModules && WritingModule) {
     // Construct MemoryBuffer and update buffer manager.
     // 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;
   return Signature;
 }
 }

+ 1 - 0
lib/Serialization/CMakeLists.txt

@@ -14,6 +14,7 @@ add_clang_library(clangSerialization
   ASTWriterStmt.cpp
   ASTWriterStmt.cpp
   GeneratePCH.cpp
   GeneratePCH.cpp
   GlobalModuleIndex.cpp
   GlobalModuleIndex.cpp
+  InMemoryModuleCache.cpp
   Module.cpp
   Module.cpp
   ModuleFileExtension.cpp
   ModuleFileExtension.cpp
   ModuleManager.cpp
   ModuleManager.cpp

+ 3 - 3
lib/Serialization/GeneratePCH.cpp

@@ -21,13 +21,13 @@
 using namespace clang;
 using namespace clang;
 
 
 PCHGenerator::PCHGenerator(
 PCHGenerator::PCHGenerator(
-    const Preprocessor &PP, StringRef OutputFile, StringRef isysroot,
-    std::shared_ptr<PCHBuffer> Buffer,
+    const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
+    StringRef OutputFile, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
     bool AllowASTWithErrors, bool IncludeTimestamps)
     bool AllowASTWithErrors, bool IncludeTimestamps)
     : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
     : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
       SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
       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),
              IncludeTimestamps),
       AllowASTWithErrors(AllowASTWithErrors) {
       AllowASTWithErrors(AllowASTWithErrors) {
   this->Buffer->IsComplete = false;
   this->Buffer->IsComplete = false;

+ 49 - 0
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<llvm::MemoryBuffer> 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;
+}

+ 15 - 13
lib/Serialization/ModuleManager.cpp

@@ -14,10 +14,10 @@
 #include "clang/Serialization/ModuleManager.h"
 #include "clang/Serialization/ModuleManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LLVM.h"
-#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/ModuleMap.h"
 #include "clang/Lex/ModuleMap.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
 #include "clang/Serialization/Module.h"
 #include "clang/Serialization/Module.h"
 #include "clang/Serialization/PCHContainerOperations.h"
 #include "clang/Serialization/PCHContainerOperations.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/STLExtras.h"
@@ -159,12 +159,13 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
   // Load the contents of the module
   // Load the contents of the module
   if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
   if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
     // The buffer was already provided for us.
     // 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
     // Since the cached buffer is reused, it is safe to close the file
     // descriptor that was opened while stat()ing the PCM in
     // descriptor that was opened while stat()ing the PCM in
     // lookupModuleFile() above, it won't be needed any longer.
     // lookupModuleFile() above, it won't be needed any longer.
     Entry->closeFile();
     Entry->closeFile();
-  } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(FileName)) {
+  } else if (llvm::MemoryBuffer *Buffer =
+                 getModuleCache().lookupBuffer(FileName)) {
     NewModule->Buffer = Buffer;
     NewModule->Buffer = Buffer;
     // As above, the file descriptor is no longer needed.
     // As above, the file descriptor is no longer needed.
     Entry->closeFile();
     Entry->closeFile();
@@ -185,7 +186,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
       return Missing;
       return Missing;
     }
     }
 
 
-    NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(*Buf));
+    NewModule->Buffer = &getModuleCache().addBuffer(FileName, std::move(*Buf));
   }
   }
 
 
   // Initialize the stream.
   // Initialize the stream.
@@ -197,7 +198,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
                                           ExpectedSignature, ErrorStr)) {
                                           ExpectedSignature, ErrorStr)) {
     // Try to remove the buffer.  If it can't be removed, then it was already
     // Try to remove the buffer.  If it can't be removed, then it was already
     // validated by this process.
     // validated by this process.
-    if (!PCMCache->tryToRemoveBuffer(NewModule->FileName))
+    if (!getModuleCache().tryToRemoveBuffer(NewModule->FileName))
       FileMgr.invalidateCache(NewModule->File);
       FileMgr.invalidateCache(NewModule->File);
     return OutOfDate;
     return OutOfDate;
   }
   }
@@ -267,11 +268,11 @@ void ModuleManager::removeModules(
     // rebuilt (or there was an error). Invalidate them so that we can load the
     // rebuilt (or there was an error). Invalidate them so that we can load the
     // new files that will be renamed over the old ones.
     // 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 &&
     if (LoadedSuccessfully.count(&*victim) == 0 &&
-        !PCMCache->tryToRemoveBuffer(victim->FileName))
+        !getModuleCache().tryToRemoveBuffer(victim->FileName))
       FileMgr.invalidateCache(victim->File);
       FileMgr.invalidateCache(victim->File);
   }
   }
 
 
@@ -327,11 +328,12 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
   ModulesInCommonWithGlobalIndex.push_back(MF);
   ModulesInCommonWithGlobalIndex.push_back(MF);
 }
 }
 
 
-ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
+ModuleManager::ModuleManager(FileManager &FileMgr,
+                             InMemoryModuleCache &ModuleCache,
                              const PCHContainerReader &PCHContainerRdr,
                              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; }
 ModuleManager::~ModuleManager() { delete FirstVisitState; }
 
 

+ 1 - 1
test/Modules/outofdate-rebuild.m

@@ -11,5 +11,5 @@
 // RUN:   -fsyntax-only
 // RUN:   -fsyntax-only
 
 
 // This testcase reproduces a use-after-free in when ModuleManager removes an
 // 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;
 @import Cocoa;

+ 0 - 1
unittests/Basic/CMakeLists.txt

@@ -7,7 +7,6 @@ add_clang_unittest(BasicTests
   DiagnosticTest.cpp
   DiagnosticTest.cpp
   FileManagerTest.cpp
   FileManagerTest.cpp
   FixedPointTest.cpp
   FixedPointTest.cpp
-  MemoryBufferCacheTest.cpp
   SourceManagerTest.cpp
   SourceManagerTest.cpp
   )
   )
 
 

+ 3 - 7
unittests/Basic/SourceManagerTest.cpp

@@ -11,7 +11,6 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/HeaderSearch.h"
@@ -60,11 +59,10 @@ TEST_F(SourceManagerTest, isBeforeInTranslationUnit) {
   SourceMgr.setMainFileID(mainFileID);
   SourceMgr.setMainFileID(mainFileID);
 
 
   TrivialModuleLoader ModLoader;
   TrivialModuleLoader ModLoader;
-  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, &*Target);
                           Diags, LangOpts, &*Target);
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                  SourceMgr, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
   PP.Initialize(*Target);
@@ -229,11 +227,10 @@ TEST_F(SourceManagerTest, getMacroArgExpandedLocation) {
   SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
   SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
 
 
   TrivialModuleLoader ModLoader;
   TrivialModuleLoader ModLoader;
-  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, &*Target);
                           Diags, LangOpts, &*Target);
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                  SourceMgr, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
   PP.Initialize(*Target);
@@ -348,11 +345,10 @@ TEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) {
   SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
   SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
 
 
   TrivialModuleLoader ModLoader;
   TrivialModuleLoader ModLoader;
-  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, &*Target);
                           Diags, LangOpts, &*Target);
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                  SourceMgr, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
   PP.Initialize(*Target);

+ 1 - 0
unittests/CMakeLists.txt

@@ -32,3 +32,4 @@ if(NOT WIN32 AND CLANG_TOOL_LIBCLANG_BUILD)
 endif()
 endif()
 add_subdirectory(Rename)
 add_subdirectory(Rename)
 add_subdirectory(Index)
 add_subdirectory(Index)
+add_subdirectory(Serialization)

+ 1 - 1
unittests/Lex/HeaderSearchTest.cpp

@@ -11,12 +11,12 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
 #include "gtest/gtest.h"
 #include "gtest/gtest.h"
 
 
 namespace clang {
 namespace clang {

+ 1 - 3
unittests/Lex/LexerTest.cpp

@@ -11,7 +11,6 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/TargetOptions.h"
@@ -48,12 +47,11 @@ protected:
         llvm::MemoryBuffer::getMemBuffer(Source);
         llvm::MemoryBuffer::getMemBuffer(Source);
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
 
-    MemoryBufferCache PCMCache;
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, LangOpts, Target.get());
                             Diags, LangOpts, Target.get());
     std::unique_ptr<Preprocessor> PP = llvm::make_unique<Preprocessor>(
     std::unique_ptr<Preprocessor> PP = llvm::make_unique<Preprocessor>(
         std::make_shared<PreprocessorOptions>(), Diags, LangOpts, SourceMgr,
         std::make_shared<PreprocessorOptions>(), Diags, LangOpts, SourceMgr,
-        PCMCache, HeaderInfo, ModLoader,
+        HeaderInfo, ModLoader,
         /*IILookup =*/nullptr,
         /*IILookup =*/nullptr,
         /*OwnsHeaderSearch =*/false);
         /*OwnsHeaderSearch =*/false);
     PP->Initialize(*Target);
     PP->Initialize(*Target);

+ 4 - 9
unittests/Lex/PPCallbacksTest.cpp

@@ -13,7 +13,6 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/TargetOptions.h"
@@ -178,14 +177,13 @@ protected:
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
 
     TrivialModuleLoader ModLoader;
     TrivialModuleLoader ModLoader;
-    MemoryBufferCache PCMCache;
 
 
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, LangOpts, Target.get());
                             Diags, LangOpts, Target.get());
     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
 
 
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                    SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                    SourceMgr, HeaderInfo, ModLoader,
                     /*IILookup =*/nullptr,
                     /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
                     /*OwnsHeaderSearch =*/false);
     return InclusionDirectiveCallback(PP)->FilenameRange;
     return InclusionDirectiveCallback(PP)->FilenameRange;
@@ -198,14 +196,13 @@ protected:
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
 
     TrivialModuleLoader ModLoader;
     TrivialModuleLoader ModLoader;
-    MemoryBufferCache PCMCache;
 
 
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, LangOpts, Target.get());
                             Diags, LangOpts, Target.get());
     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
 
 
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                    SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                    SourceMgr, HeaderInfo, ModLoader,
                     /*IILookup =*/nullptr,
                     /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
                     /*OwnsHeaderSearch =*/false);
     return InclusionDirectiveCallback(PP)->FileType;
     return InclusionDirectiveCallback(PP)->FileType;
@@ -233,14 +230,13 @@ protected:
   std::vector<CondDirectiveCallbacks::Result>
   std::vector<CondDirectiveCallbacks::Result>
   DirectiveExprRange(StringRef SourceText) {
   DirectiveExprRange(StringRef SourceText) {
     TrivialModuleLoader ModLoader;
     TrivialModuleLoader ModLoader;
-    MemoryBufferCache PCMCache;
     std::unique_ptr<llvm::MemoryBuffer> Buf =
     std::unique_ptr<llvm::MemoryBuffer> Buf =
         llvm::MemoryBuffer::getMemBuffer(SourceText);
         llvm::MemoryBuffer::getMemBuffer(SourceText);
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, LangOpts, Target.get());
                             Diags, LangOpts, Target.get());
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                    SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                    SourceMgr, HeaderInfo, ModLoader,
                     /*IILookup =*/nullptr,
                     /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
     PP.Initialize(*Target);
@@ -270,12 +266,11 @@ protected:
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf)));
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf)));
 
 
     TrivialModuleLoader ModLoader;
     TrivialModuleLoader ModLoader;
-    MemoryBufferCache PCMCache;
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, OpenCLLangOpts, Target.get());
                             Diags, OpenCLLangOpts, Target.get());
 
 
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags,
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags,
-                    OpenCLLangOpts, SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                    OpenCLLangOpts, SourceMgr, HeaderInfo, ModLoader,
                     /*IILookup =*/nullptr,
                     /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
     PP.Initialize(*Target);

+ 1 - 3
unittests/Lex/PPConditionalDirectiveRecordTest.cpp

@@ -11,7 +11,6 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/TargetOptions.h"
@@ -75,11 +74,10 @@ TEST_F(PPConditionalDirectiveRecordTest, PPRecAPI) {
   SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
   SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
 
   TrivialModuleLoader ModLoader;
   TrivialModuleLoader ModLoader;
-  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, Target.get());
                           Diags, LangOpts, Target.get());
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                  SourceMgr, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
   PP.Initialize(*Target);

+ 17 - 0
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
+  )

+ 6 - 6
unittests/Basic/MemoryBufferCacheTest.cpp → 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.
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
 // 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 "llvm/Support/MemoryBuffer.h"
 #include "gtest/gtest.h"
 #include "gtest/gtest.h"
 
 
@@ -22,7 +22,7 @@ std::unique_ptr<MemoryBuffer> getBuffer(int I) {
                                     /* RequiresNullTerminator = */ false);
                                     /* RequiresNullTerminator = */ false);
 }
 }
 
 
-TEST(MemoryBufferCacheTest, addBuffer) {
+TEST(InMemoryModuleCacheTest, addBuffer) {
   auto B1 = getBuffer(1);
   auto B1 = getBuffer(1);
   auto B2 = getBuffer(2);
   auto B2 = getBuffer(2);
   auto B3 = getBuffer(3);
   auto B3 = getBuffer(3);
@@ -31,7 +31,7 @@ TEST(MemoryBufferCacheTest, addBuffer) {
   auto *RawB3 = B3.get();
   auto *RawB3 = B3.get();
 
 
   // Add a few buffers.
   // Add a few buffers.
-  MemoryBufferCache Cache;
+  InMemoryModuleCache Cache;
   EXPECT_EQ(RawB1, &Cache.addBuffer("1", std::move(B1)));
   EXPECT_EQ(RawB1, &Cache.addBuffer("1", std::move(B1)));
   EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2)));
   EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2)));
   EXPECT_EQ(RawB3, &Cache.addBuffer("3", std::move(B3)));
   EXPECT_EQ(RawB3, &Cache.addBuffer("3", std::move(B3)));
@@ -58,9 +58,9 @@ TEST(MemoryBufferCacheTest, addBuffer) {
   EXPECT_FALSE(Cache.isBufferFinal("3"));
   EXPECT_FALSE(Cache.isBufferFinal("3"));
 }
 }
 
 
-TEST(MemoryBufferCacheTest, finalizeCurrentBuffers) {
+TEST(InMemoryModuleCacheTest, finalizeCurrentBuffers) {
   // Add a buffer.
   // Add a buffer.
-  MemoryBufferCache Cache;
+  InMemoryModuleCache Cache;
   auto B1 = getBuffer(1);
   auto B1 = getBuffer(1);
   auto *RawB1 = B1.get();
   auto *RawB1 = B1.get();
   Cache.addBuffer("1", std::move(B1));
   Cache.addBuffer("1", std::move(B1));