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