clang  11.0.0git
PrecompiledPreamble.h
Go to the documentation of this file.
1 //===--- PrecompiledPreamble.h - Build precompiled preambles ----*- 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 // Helper class to build precompiled preamble.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_FRONTEND_PRECOMPILED_PREAMBLE_H
14 #define LLVM_CLANG_FRONTEND_PRECOMPILED_PREAMBLE_H
15 
16 #include "clang/Lex/Lexer.h"
17 #include "clang/Lex/Preprocessor.h"
18 #include "llvm/ADT/IntrusiveRefCntPtr.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Support/AlignOf.h"
21 #include "llvm/Support/MD5.h"
22 #include <cstddef>
23 #include <memory>
24 #include <system_error>
25 #include <type_traits>
26 
27 namespace llvm {
28 class MemoryBuffer;
29 namespace vfs {
30 class FileSystem;
31 }
32 } // namespace llvm
33 
34 namespace clang {
35 class CompilerInstance;
36 class CompilerInvocation;
37 class Decl;
38 class DeclGroupRef;
39 class PCHContainerOperations;
40 
41 /// Runs lexer to compute suggested preamble bounds.
42 PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts,
43  const llvm::MemoryBuffer *Buffer,
44  unsigned MaxLines);
45 
46 class PreambleCallbacks;
47 
48 /// A class holding a PCH and all information to check whether it is valid to
49 /// reuse the PCH for the subsequent runs. Use BuildPreamble to create PCH and
50 /// CanReusePreamble + AddImplicitPreamble to make use of it.
52  class PCHStorage;
53  struct PreambleFileHash;
54 
55 public:
56  /// Try to build PrecompiledPreamble for \p Invocation. See
57  /// BuildPreambleError for possible error codes.
58  ///
59  /// \param Invocation Original CompilerInvocation with options to compile the
60  /// file.
61  ///
62  /// \param MainFileBuffer Buffer with the contents of the main file.
63  ///
64  /// \param Bounds Bounds of the preamble, result of calling
65  /// ComputePreambleBounds.
66  ///
67  /// \param Diagnostics Diagnostics engine to be used while building the
68  /// preamble.
69  ///
70  /// \param VFS An instance of vfs::FileSystem to be used for file
71  /// accesses.
72  ///
73  /// \param PCHContainerOps An instance of PCHContainerOperations.
74  ///
75  /// \param StoreInMemory Store PCH in memory. If false, PCH will be stored in
76  /// a temporary file.
77  ///
78  /// \param Callbacks A set of callbacks to be executed when building
79  /// the preamble.
80  static llvm::ErrorOr<PrecompiledPreamble>
81  Build(const CompilerInvocation &Invocation,
82  const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
83  DiagnosticsEngine &Diagnostics,
85  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
86  bool StoreInMemory, PreambleCallbacks &Callbacks);
87 
89  PrecompiledPreamble &operator=(PrecompiledPreamble &&) = default;
90 
91  /// PreambleBounds used to build the preamble.
92  PreambleBounds getBounds() const;
93 
94  /// Returns the size, in bytes, that preamble takes on disk or in memory.
95  /// For on-disk preambles returns 0 if filesystem operations fail. Intended to
96  /// be used for logging and debugging purposes only.
97  std::size_t getSize() const;
98 
99  /// Returned string is not null-terminated.
100  llvm::StringRef getContents() const {
101  return {PreambleBytes.data(), PreambleBytes.size()};
102  }
103 
104  /// Check whether PrecompiledPreamble can be reused for the new contents(\p
105  /// MainFileBuffer) of the main file.
106  bool CanReuse(const CompilerInvocation &Invocation,
107  const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
108  llvm::vfs::FileSystem *VFS) const;
109 
110  /// Changes options inside \p CI to use PCH from this preamble. Also remaps
111  /// main file to \p MainFileBuffer and updates \p VFS to ensure the preamble
112  /// is accessible.
113  /// Requires that CanReuse() is true.
114  /// For in-memory preambles, PrecompiledPreamble instance continues to own the
115  /// MemoryBuffer with the Preamble after this method returns. The caller is
116  /// responsible for making sure the PrecompiledPreamble instance outlives the
117  /// compiler run and the AST that will be using the PCH.
118  void AddImplicitPreamble(CompilerInvocation &CI,
120  llvm::MemoryBuffer *MainFileBuffer) const;
121 
122  /// Configure \p CI to use this preamble.
123  /// Like AddImplicitPreamble, but doesn't assume CanReuse() is true.
124  /// If this preamble does not match the file, it may parse differently.
125  void OverridePreamble(CompilerInvocation &CI,
127  llvm::MemoryBuffer *MainFileBuffer) const;
128 
129 private:
130  PrecompiledPreamble(PCHStorage Storage, std::vector<char> PreambleBytes,
131  bool PreambleEndsAtStartOfLine,
132  llvm::StringMap<PreambleFileHash> FilesInPreamble,
133  llvm::StringSet<> MissingFiles);
134 
135  /// A temp file that would be deleted on destructor call. If destructor is not
136  /// called for any reason, the file will be deleted at static objects'
137  /// destruction.
138  /// An assertion will fire if two TempPCHFiles are created with the same name,
139  /// so it's not intended to be used outside preamble-handling.
140  class TempPCHFile {
141  public:
142  // A main method used to construct TempPCHFile.
143  static llvm::ErrorOr<TempPCHFile> CreateNewPreamblePCHFile();
144 
145  private:
146  TempPCHFile(std::string FilePath);
147 
148  public:
149  TempPCHFile(TempPCHFile &&Other);
150  TempPCHFile &operator=(TempPCHFile &&Other);
151 
152  TempPCHFile(const TempPCHFile &) = delete;
153  ~TempPCHFile();
154 
155  /// A path where temporary file is stored.
156  llvm::StringRef getFilePath() const;
157 
158  private:
159  void RemoveFileIfPresent();
160 
161  private:
163  };
164 
165  class InMemoryPreamble {
166  public:
167  std::string Data;
168  };
169 
170  class PCHStorage {
171  public:
172  enum class Kind { Empty, InMemory, TempFile };
173 
174  PCHStorage() = default;
175  PCHStorage(TempPCHFile File);
176  PCHStorage(InMemoryPreamble Memory);
177 
178  PCHStorage(const PCHStorage &) = delete;
179  PCHStorage &operator=(const PCHStorage &) = delete;
180 
181  PCHStorage(PCHStorage &&Other);
182  PCHStorage &operator=(PCHStorage &&Other);
183 
184  ~PCHStorage();
185 
186  Kind getKind() const;
187 
188  TempPCHFile &asFile();
189  const TempPCHFile &asFile() const;
190 
191  InMemoryPreamble &asMemory();
192  const InMemoryPreamble &asMemory() const;
193 
194  private:
195  void destroy();
196  void setEmpty();
197 
198  private:
199  Kind StorageKind = Kind::Empty;
200  llvm::AlignedCharArrayUnion<TempPCHFile, InMemoryPreamble> Storage = {};
201  };
202 
203  /// Data used to determine if a file used in the preamble has been changed.
204  struct PreambleFileHash {
205  /// All files have size set.
206  off_t Size = 0;
207 
208  /// Modification time is set for files that are on disk. For memory
209  /// buffers it is zero.
210  time_t ModTime = 0;
211 
212  /// Memory buffers have MD5 instead of modification time. We don't
213  /// compute MD5 for on-disk files because we hope that modification time is
214  /// enough to tell if the file was changed.
215  llvm::MD5::MD5Result MD5 = {};
216 
217  static PreambleFileHash createForFile(off_t Size, time_t ModTime);
218  static PreambleFileHash
219  createForMemoryBuffer(const llvm::MemoryBuffer *Buffer);
220 
221  friend bool operator==(const PreambleFileHash &LHS,
222  const PreambleFileHash &RHS) {
223  return LHS.Size == RHS.Size && LHS.ModTime == RHS.ModTime &&
224  LHS.MD5 == RHS.MD5;
225  }
226  friend bool operator!=(const PreambleFileHash &LHS,
227  const PreambleFileHash &RHS) {
228  return !(LHS == RHS);
229  }
230  };
231 
232  /// Helper function to set up PCH for the preamble into \p CI and \p VFS to
233  /// with the specified \p Bounds.
234  void configurePreamble(PreambleBounds Bounds, CompilerInvocation &CI,
236  llvm::MemoryBuffer *MainFileBuffer) const;
237 
238  /// Sets up the PreprocessorOptions and changes VFS, so that PCH stored in \p
239  /// Storage is accessible to clang. This method is an implementation detail of
240  /// AddImplicitPreamble.
241  static void
242  setupPreambleStorage(const PCHStorage &Storage,
243  PreprocessorOptions &PreprocessorOpts,
245 
246  /// Manages the memory buffer or temporary file that stores the PCH.
247  PCHStorage Storage;
248  /// Keeps track of the files that were used when computing the
249  /// preamble, with both their buffer size and their modification time.
250  ///
251  /// If any of the files have changed from one compile to the next,
252  /// the preamble must be thrown away.
253  llvm::StringMap<PreambleFileHash> FilesInPreamble;
254  /// Files that were not found during preamble building. If any of these now
255  /// exist then the preamble should not be reused.
256  ///
257  /// Storing *all* the missing files that could invalidate the preamble would
258  /// make it too expensive to revalidate (when the include path has many
259  /// entries, each #include will miss half of them on average).
260  /// Instead, we track only files that could have satisfied an #include that
261  /// was ultimately not found.
262  llvm::StringSet<> MissingFiles;
263  /// The contents of the file that was used to precompile the preamble. Only
264  /// contains first PreambleBounds::Size bytes. Used to compare if the relevant
265  /// part of the file has not changed, so that preamble can be reused.
266  std::vector<char> PreambleBytes;
267  /// See PreambleBounds::PreambleEndsAtStartOfLine
268  bool PreambleEndsAtStartOfLine;
269 };
270 
271 /// A set of callbacks to gather useful information while building a preamble.
273 public:
274  virtual ~PreambleCallbacks() = default;
275 
276  /// Called before FrontendAction::BeginSourceFile.
277  /// Can be used to store references to various CompilerInstance fields
278  /// (e.g. SourceManager) that may be interesting to the consumers of other
279  /// callbacks.
280  virtual void BeforeExecute(CompilerInstance &CI);
281  /// Called after FrontendAction::Execute(), but before
282  /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
283  /// various CompilerInstance fields before they are destroyed.
284  virtual void AfterExecute(CompilerInstance &CI);
285  /// Called after PCH has been emitted. \p Writer may be used to retrieve
286  /// information about AST, serialized in PCH.
287  virtual void AfterPCHEmitted(ASTWriter &Writer);
288  /// Called for each TopLevelDecl.
289  /// NOTE: To allow more flexibility a custom ASTConsumer could probably be
290  /// used instead, but having only this method allows a simpler API.
291  virtual void HandleTopLevelDecl(DeclGroupRef DG);
292  /// Creates wrapper class for PPCallbacks so we can also process information
293  /// about includes that are inside of a preamble
294  virtual std::unique_ptr<PPCallbacks> createPPCallbacks();
295  /// The returned CommentHandler will be added to the preprocessor if not null.
296  virtual CommentHandler *getCommentHandler();
297  /// Determines which function bodies are parsed, by default skips everything.
298  /// Only used if FrontendOpts::SkipFunctionBodies is true.
299  /// See ASTConsumer::shouldSkipFunctionBody.
300  virtual bool shouldSkipFunctionBody(Decl *D) { return true; }
301 };
302 
303 enum class BuildPreambleError {
308  BadInputs
309 };
310 
311 class BuildPreambleErrorCategory final : public std::error_category {
312 public:
313  const char *name() const noexcept override;
314  std::string message(int condition) const override;
315 };
316 
317 std::error_code make_error_code(BuildPreambleError Error);
318 } // namespace clang
319 
320 namespace std {
321 template <>
322 struct is_error_code_enum<clang::BuildPreambleError> : std::true_type {};
323 } // namespace std
324 
325 #endif
Describes the bounds (start, size) of the preamble and a flag required by PreprocessorOptions::Precom...
Definition: Lexer.h:58
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
Definition: Dominators.h:30
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
Definition: Format.h:2679
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
Definition: opencl-c-base.h:40
std::error_code make_error_code(BuildPreambleError Error)
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
Definition: CallGraph.h:207
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:153
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr or CxxCtorInitializer) selects the name&#39;s to...
llvm::Error Error
A set of callbacks to gather useful information while building a preamble.
PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts, const llvm::MemoryBuffer *Buffer, unsigned MaxLines)
Runs lexer to compute suggested preamble bounds.
Defines the clang::Preprocessor interface.
Kind
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
llvm::StringRef getContents() const
Returned string is not null-terminated.
Dataflow Directional Tag Classes.
A class holding a PCH and all information to check whether it is valid to reuse the PCH for the subse...
virtual bool shouldSkipFunctionBody(Decl *D)
Determines which function bodies are parsed, by default skips everything.
Helper class for holding the data necessary to invoke the compiler.
bool operator!=(CanQual< T > x, CanQual< U > y)
Writes an AST file containing the contents of a translation unit.
Definition: ASTWriter.h:98
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:994
Abstract base class that describes a handler that will receive source ranges for each of the comments...