Clang Project

clang_source_code/include/clang/Serialization/InMemoryModuleCache.h
1//===- InMemoryModuleCache.h - In-memory cache for modules ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H
10#define LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H
11
12#include "llvm/ADT/IntrusiveRefCntPtr.h"
13#include "llvm/ADT/Optional.h"
14#include "llvm/ADT/StringMap.h"
15#include "llvm/Support/MemoryBuffer.h"
16#include <memory>
17
18namespace clang {
19
20/// In-memory cache for modules.
21///
22/// This is a cache for modules for use across a compilation, sharing state
23/// between the CompilerInstances in an implicit modules build.  It must be
24/// shared by each CompilerInstance, ASTReader, ASTWriter, and ModuleManager
25/// that are coordinating.
26///
27/// Critically, it ensures that a single process has a consistent view of each
28/// PCM.  This is used by \a CompilerInstance when building PCMs to ensure that
29/// each \a ModuleManager sees the same files.
30class InMemoryModuleCache : public llvm::RefCountedBase<InMemoryModuleCache> {
31  struct PCM {
32    std::unique_ptr<llvm::MemoryBufferBuffer;
33
34    /// Track whether this PCM is known to be good (either built or
35    /// successfully imported by a CompilerInstance/ASTReader using this
36    /// cache).
37    bool IsFinal = false;
38
39    PCM() = default;
40    PCM(std::unique_ptr<llvm::MemoryBufferBuffer)
41        : Buffer(std::move(Buffer)) {}
42  };
43
44  /// Cache of buffers.
45  llvm::StringMap<PCM> PCMs;
46
47public:
48  /// There are four states for a PCM.  It must monotonically increase.
49  ///
50  ///  1. Unknown: the PCM has neither been read from disk nor built.
51  ///  2. Tentative: the PCM has been read from disk but not yet imported or
52  ///     built.  It might work.
53  ///  3. ToBuild: the PCM read from disk did not work but a new one has not
54  ///     been built yet.
55  ///  4. Final: indicating that the current PCM was either built in this
56  ///     process or has been successfully imported.
57  enum State { UnknownTentativeToBuildFinal };
58
59  /// Get the state of the PCM.
60  State getPCMState(llvm::StringRef Filenameconst;
61
62  /// Store the PCM under the Filename.
63  ///
64  /// \pre state is Unknown
65  /// \post state is Tentative
66  /// \return a reference to the buffer as a convenience.
67  llvm::MemoryBuffer &addPCM(llvm::StringRef Filename,
68                             std::unique_ptr<llvm::MemoryBufferBuffer);
69
70  /// Store a just-built PCM under the Filename.
71  ///
72  /// \pre state is Unknown or ToBuild.
73  /// \pre state is not Tentative.
74  /// \return a reference to the buffer as a convenience.
75  llvm::MemoryBuffer &addBuiltPCM(llvm::StringRef Filename,
76                                  std::unique_ptr<llvm::MemoryBufferBuffer);
77
78  /// Try to remove a buffer from the cache.  No effect if state is Final.
79  ///
80  /// \pre state is Tentative/Final.
81  /// \post Tentative => ToBuild or Final => Final.
82  /// \return false on success, i.e. if Tentative => ToBuild.
83  bool tryToDropPCM(llvm::StringRef Filename);
84
85  /// Mark a PCM as final.
86  ///
87  /// \pre state is Tentative or Final.
88  /// \post state is Final.
89  void finalizePCM(llvm::StringRef Filename);
90
91  /// Get a pointer to the pCM if it exists; else nullptr.
92  llvm::MemoryBuffer *lookupPCM(llvm::StringRef Filenameconst;
93
94  /// Check whether the PCM is final and has been shown to work.
95  ///
96  /// \return true iff state is Final.
97  bool isPCMFinal(llvm::StringRef Filenameconst;
98
99  /// Check whether the PCM is waiting to be built.
100  ///
101  /// \return true iff state is ToBuild.
102  bool shouldBuildPCM(llvm::StringRef Filenameconst;
103};
104
105// end namespace clang
106
107#endif // LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H
108
clang::InMemoryModuleCache::PCM
clang::InMemoryModuleCache::PCM::Buffer
clang::InMemoryModuleCache::PCM::IsFinal
clang::InMemoryModuleCache::PCMs
clang::InMemoryModuleCache::State
clang::InMemoryModuleCache::getPCMState
clang::InMemoryModuleCache::addPCM
clang::InMemoryModuleCache::addBuiltPCM
clang::InMemoryModuleCache::tryToDropPCM
clang::InMemoryModuleCache::finalizePCM
clang::InMemoryModuleCache::lookupPCM
clang::InMemoryModuleCache::isPCMFinal
clang::InMemoryModuleCache::shouldBuildPCM
clang::InMemoryModuleCache::getPCMState
clang::InMemoryModuleCache::addPCM
clang::InMemoryModuleCache::addBuiltPCM
clang::InMemoryModuleCache::tryToDropPCM
clang::InMemoryModuleCache::finalizePCM
clang::InMemoryModuleCache::lookupPCM
clang::InMemoryModuleCache::isPCMFinal
clang::InMemoryModuleCache::shouldBuildPCM