xref: /llvm-project/clang/include/clang/Serialization/InMemoryModuleCache.h (revision a996cc217cefb9071888de38c6f05e5742d0106f)
18bef5cd4SDuncan P. N. Exon Smith //===- InMemoryModuleCache.h - In-memory cache for modules ------*- C++ -*-===//
28bef5cd4SDuncan P. N. Exon Smith //
38bef5cd4SDuncan P. N. Exon Smith // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48bef5cd4SDuncan P. N. Exon Smith // See https://llvm.org/LICENSE.txt for license information.
58bef5cd4SDuncan P. N. Exon Smith // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68bef5cd4SDuncan P. N. Exon Smith //
78bef5cd4SDuncan P. N. Exon Smith //===----------------------------------------------------------------------===//
88bef5cd4SDuncan P. N. Exon Smith 
98bef5cd4SDuncan P. N. Exon Smith #ifndef LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H
108bef5cd4SDuncan P. N. Exon Smith #define LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H
118bef5cd4SDuncan P. N. Exon Smith 
128bef5cd4SDuncan P. N. Exon Smith #include "llvm/ADT/IntrusiveRefCntPtr.h"
138bef5cd4SDuncan P. N. Exon Smith #include "llvm/ADT/StringMap.h"
149318db0fSBenjamin Kramer #include "llvm/Support/MemoryBuffer.h"
158bef5cd4SDuncan P. N. Exon Smith #include <memory>
168bef5cd4SDuncan P. N. Exon Smith 
178bef5cd4SDuncan P. N. Exon Smith namespace clang {
188bef5cd4SDuncan P. N. Exon Smith 
198bef5cd4SDuncan P. N. Exon Smith /// In-memory cache for modules.
208bef5cd4SDuncan P. N. Exon Smith ///
218bef5cd4SDuncan P. N. Exon Smith /// This is a cache for modules for use across a compilation, sharing state
228bef5cd4SDuncan P. N. Exon Smith /// between the CompilerInstances in an implicit modules build.  It must be
238bef5cd4SDuncan P. N. Exon Smith /// shared by each CompilerInstance, ASTReader, ASTWriter, and ModuleManager
248bef5cd4SDuncan P. N. Exon Smith /// that are coordinating.
258bef5cd4SDuncan P. N. Exon Smith ///
268bef5cd4SDuncan P. N. Exon Smith /// Critically, it ensures that a single process has a consistent view of each
278bef5cd4SDuncan P. N. Exon Smith /// PCM.  This is used by \a CompilerInstance when building PCMs to ensure that
288bef5cd4SDuncan P. N. Exon Smith /// each \a ModuleManager sees the same files.
298bef5cd4SDuncan P. N. Exon Smith class InMemoryModuleCache : public llvm::RefCountedBase<InMemoryModuleCache> {
308bef5cd4SDuncan P. N. Exon Smith   struct PCM {
318bef5cd4SDuncan P. N. Exon Smith     std::unique_ptr<llvm::MemoryBuffer> Buffer;
328bef5cd4SDuncan P. N. Exon Smith 
330a2be46cSDuncan P. N. Exon Smith     /// Track whether this PCM is known to be good (either built or
340a2be46cSDuncan P. N. Exon Smith     /// successfully imported by a CompilerInstance/ASTReader using this
350a2be46cSDuncan P. N. Exon Smith     /// cache).
360a2be46cSDuncan P. N. Exon Smith     bool IsFinal = false;
370a2be46cSDuncan P. N. Exon Smith 
380a2be46cSDuncan P. N. Exon Smith     PCM() = default;
PCMPCM390a2be46cSDuncan P. N. Exon Smith     PCM(std::unique_ptr<llvm::MemoryBuffer> Buffer)
400a2be46cSDuncan P. N. Exon Smith         : Buffer(std::move(Buffer)) {}
418bef5cd4SDuncan P. N. Exon Smith   };
428bef5cd4SDuncan P. N. Exon Smith 
438bef5cd4SDuncan P. N. Exon Smith   /// Cache of buffers.
448bef5cd4SDuncan P. N. Exon Smith   llvm::StringMap<PCM> PCMs;
458bef5cd4SDuncan P. N. Exon Smith 
468bef5cd4SDuncan P. N. Exon Smith public:
47*57a2eaf3SRumeet Dhindsa   /// There are four states for a PCM.  It must monotonically increase.
48*57a2eaf3SRumeet Dhindsa   ///
49*57a2eaf3SRumeet Dhindsa   ///  1. Unknown: the PCM has neither been read from disk nor built.
50*57a2eaf3SRumeet Dhindsa   ///  2. Tentative: the PCM has been read from disk but not yet imported or
51*57a2eaf3SRumeet Dhindsa   ///     built.  It might work.
52*57a2eaf3SRumeet Dhindsa   ///  3. ToBuild: the PCM read from disk did not work but a new one has not
53*57a2eaf3SRumeet Dhindsa   ///     been built yet.
54*57a2eaf3SRumeet Dhindsa   ///  4. Final: indicating that the current PCM was either built in this
55*57a2eaf3SRumeet Dhindsa   ///     process or has been successfully imported.
56*57a2eaf3SRumeet Dhindsa   enum State { Unknown, Tentative, ToBuild, Final };
57*57a2eaf3SRumeet Dhindsa 
58*57a2eaf3SRumeet Dhindsa   /// Get the state of the PCM.
59*57a2eaf3SRumeet Dhindsa   State getPCMState(llvm::StringRef Filename) const;
60*57a2eaf3SRumeet Dhindsa 
610a2be46cSDuncan P. N. Exon Smith   /// Store the PCM under the Filename.
620a2be46cSDuncan P. N. Exon Smith   ///
63*57a2eaf3SRumeet Dhindsa   /// \pre state is Unknown
64*57a2eaf3SRumeet Dhindsa   /// \post state is Tentative
658bef5cd4SDuncan P. N. Exon Smith   /// \return a reference to the buffer as a convenience.
660a2be46cSDuncan P. N. Exon Smith   llvm::MemoryBuffer &addPCM(llvm::StringRef Filename,
678bef5cd4SDuncan P. N. Exon Smith                              std::unique_ptr<llvm::MemoryBuffer> Buffer);
688bef5cd4SDuncan P. N. Exon Smith 
69*57a2eaf3SRumeet Dhindsa   /// Store a just-built PCM under the Filename.
708bef5cd4SDuncan P. N. Exon Smith   ///
71*57a2eaf3SRumeet Dhindsa   /// \pre state is Unknown or ToBuild.
72*57a2eaf3SRumeet Dhindsa   /// \pre state is not Tentative.
730a2be46cSDuncan P. N. Exon Smith   /// \return a reference to the buffer as a convenience.
74*57a2eaf3SRumeet Dhindsa   llvm::MemoryBuffer &addBuiltPCM(llvm::StringRef Filename,
750a2be46cSDuncan P. N. Exon Smith                                   std::unique_ptr<llvm::MemoryBuffer> Buffer);
768bef5cd4SDuncan P. N. Exon Smith 
77*57a2eaf3SRumeet Dhindsa   /// Try to remove a buffer from the cache.  No effect if state is Final.
788bef5cd4SDuncan P. N. Exon Smith   ///
79*57a2eaf3SRumeet Dhindsa   /// \pre state is Tentative/Final.
80*57a2eaf3SRumeet Dhindsa   /// \post Tentative => ToBuild or Final => Final.
81*57a2eaf3SRumeet Dhindsa   /// \return false on success, i.e. if Tentative => ToBuild.
82*57a2eaf3SRumeet Dhindsa   bool tryToDropPCM(llvm::StringRef Filename);
838bef5cd4SDuncan P. N. Exon Smith 
840a2be46cSDuncan P. N. Exon Smith   /// Mark a PCM as final.
85*57a2eaf3SRumeet Dhindsa   ///
86*57a2eaf3SRumeet Dhindsa   /// \pre state is Tentative or Final.
87*57a2eaf3SRumeet Dhindsa   /// \post state is Final.
880a2be46cSDuncan P. N. Exon Smith   void finalizePCM(llvm::StringRef Filename);
890a2be46cSDuncan P. N. Exon Smith 
90*57a2eaf3SRumeet Dhindsa   /// Get a pointer to the pCM if it exists; else nullptr.
910a2be46cSDuncan P. N. Exon Smith   llvm::MemoryBuffer *lookupPCM(llvm::StringRef Filename) const;
920a2be46cSDuncan P. N. Exon Smith 
930a2be46cSDuncan P. N. Exon Smith   /// Check whether the PCM is final and has been shown to work.
940a2be46cSDuncan P. N. Exon Smith   ///
950a2be46cSDuncan P. N. Exon Smith   /// \return true iff state is Final.
960a2be46cSDuncan P. N. Exon Smith   bool isPCMFinal(llvm::StringRef Filename) const;
97*57a2eaf3SRumeet Dhindsa 
98*57a2eaf3SRumeet Dhindsa   /// Check whether the PCM is waiting to be built.
99*57a2eaf3SRumeet Dhindsa   ///
100*57a2eaf3SRumeet Dhindsa   /// \return true iff state is ToBuild.
101*57a2eaf3SRumeet Dhindsa   bool shouldBuildPCM(llvm::StringRef Filename) const;
1028bef5cd4SDuncan P. N. Exon Smith };
1038bef5cd4SDuncan P. N. Exon Smith 
1048bef5cd4SDuncan P. N. Exon Smith } // end namespace clang
1058bef5cd4SDuncan P. N. Exon Smith 
1068bef5cd4SDuncan P. N. Exon Smith #endif // LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H
107