clang  6.0.0svn
PrecompiledPreamble.h
Go to the documentation of this file.
1 //===--- PrecompiledPreamble.h - Build precompiled preambles ----*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Helper class to build precompiled preamble.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_FRONTEND_PRECOMPILED_PREAMBLE_H
15 #define LLVM_CLANG_FRONTEND_PRECOMPILED_PREAMBLE_H
16 
17 #include "clang/Lex/Lexer.h"
18 #include "clang/Lex/Preprocessor.h"
19 #include "llvm/ADT/IntrusiveRefCntPtr.h"
20 #include "llvm/Support/AlignOf.h"
21 #include "llvm/Support/MD5.h"
22 #include <memory>
23 #include <system_error>
24 #include <type_traits>
25 
26 namespace llvm {
27 class MemoryBuffer;
28 }
29 
30 namespace clang {
31 namespace vfs {
32 class FileSystem;
33 }
34 
35 class CompilerInstance;
36 class CompilerInvocation;
37 class DeclGroupRef;
38 class PCHContainerOperations;
39 
40 /// \brief Runs lexer to compute suggested preamble bounds.
41 PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts,
42  llvm::MemoryBuffer *Buffer,
43  unsigned MaxLines);
44 
45 class PreambleCallbacks;
46 
47 /// A class holding a PCH and all information to check whether it is valid to
48 /// reuse the PCH for the subsequent runs. Use BuildPreamble to create PCH and
49 /// CanReusePreamble + AddImplicitPreamble to make use of it.
51  class PCHStorage;
52  struct PreambleFileHash;
53 
54 public:
55  /// \brief Try to build PrecompiledPreamble for \p Invocation. See
56  /// BuildPreambleError for possible error codes.
57  ///
58  /// \param Invocation Original CompilerInvocation with options to compile the
59  /// file.
60  ///
61  /// \param MainFileBuffer Buffer with the contents of the main file.
62  ///
63  /// \param Bounds Bounds of the preamble, result of calling
64  /// ComputePreambleBounds.
65  ///
66  /// \param Diagnostics Diagnostics engine to be used while building the
67  /// preamble.
68  ///
69  /// \param VFS An instance of vfs::FileSystem to be used for file
70  /// accesses.
71  ///
72  /// \param PCHContainerOps An instance of PCHContainerOperations.
73  ///
74  /// \param StoreInMemory Store PCH in memory. If false, PCH will be stored in
75  /// a temporary file.
76  ///
77  /// \param Callbacks A set of callbacks to be executed when building
78  /// the preamble.
79  static llvm::ErrorOr<PrecompiledPreamble>
80  Build(const CompilerInvocation &Invocation,
81  const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
83  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
84  bool StoreInMemory, PreambleCallbacks &Callbacks);
85 
87  PrecompiledPreamble &operator=(PrecompiledPreamble &&) = default;
88 
89  /// PreambleBounds used to build the preamble.
90  PreambleBounds getBounds() const;
91 
92  /// Check whether PrecompiledPreamble can be reused for the new contents(\p
93  /// MainFileBuffer) of the main file.
94  bool CanReuse(const CompilerInvocation &Invocation,
95  const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
96  vfs::FileSystem *VFS) const;
97 
98  /// Changes options inside \p CI to use PCH from this preamble. Also remaps
99  /// main file to \p MainFileBuffer and updates \p VFS to ensure the preamble
100  /// is accessible.
101  /// For in-memory preambles, PrecompiledPreamble instance continues to own
102  /// the MemoryBuffer with the Preamble after this method returns. The caller
103  /// is reponsible for making sure the PrecompiledPreamble instance outlives
104  /// the compiler run and the AST that will be using the PCH.
105  void AddImplicitPreamble(CompilerInvocation &CI,
107  llvm::MemoryBuffer *MainFileBuffer) const;
108 
109 private:
110  PrecompiledPreamble(PCHStorage Storage, std::vector<char> PreambleBytes,
111  bool PreambleEndsAtStartOfLine,
112  llvm::StringMap<PreambleFileHash> FilesInPreamble);
113 
114  /// A temp file that would be deleted on destructor call. If destructor is not
115  /// called for any reason, the file will be deleted at static objects'
116  /// destruction.
117  /// An assertion will fire if two TempPCHFiles are created with the same name,
118  /// so it's not intended to be used outside preamble-handling.
119  class TempPCHFile {
120  public:
121  // A main method used to construct TempPCHFile.
122  static llvm::ErrorOr<TempPCHFile> CreateNewPreamblePCHFile();
123 
124  /// Call llvm::sys::fs::createTemporaryFile to create a new temporary file.
125  static llvm::ErrorOr<TempPCHFile> createInSystemTempDir(const Twine &Prefix,
126  StringRef Suffix);
127  /// Create a new instance of TemporaryFile for file at \p Path. Use with
128  /// extreme caution, there's an assertion checking that there's only a
129  /// single instance of TempPCHFile alive for each path.
130  static llvm::ErrorOr<TempPCHFile> createFromCustomPath(const Twine &Path);
131 
132  private:
133  TempPCHFile(std::string FilePath);
134 
135  public:
136  TempPCHFile(TempPCHFile &&Other);
137  TempPCHFile &operator=(TempPCHFile &&Other);
138 
139  TempPCHFile(const TempPCHFile &) = delete;
140  ~TempPCHFile();
141 
142  /// A path where temporary file is stored.
143  llvm::StringRef getFilePath() const;
144 
145  private:
146  void RemoveFileIfPresent();
147 
148  private:
150  };
151 
152  class InMemoryPreamble {
153  public:
154  std::string Data;
155  };
156 
157  class PCHStorage {
158  public:
159  enum class Kind { Empty, InMemory, TempFile };
160 
161  PCHStorage() = default;
162  PCHStorage(TempPCHFile File);
163  PCHStorage(InMemoryPreamble Memory);
164 
165  PCHStorage(const PCHStorage &) = delete;
166  PCHStorage &operator=(const PCHStorage &) = delete;
167 
168  PCHStorage(PCHStorage &&Other);
169  PCHStorage &operator=(PCHStorage &&Other);
170 
171  ~PCHStorage();
172 
173  Kind getKind() const;
174 
175  TempPCHFile &asFile();
176  const TempPCHFile &asFile() const;
177 
178  InMemoryPreamble &asMemory();
179  const InMemoryPreamble &asMemory() const;
180 
181  private:
182  void destroy();
183  void setEmpty();
184 
185  private:
186  Kind StorageKind = Kind::Empty;
187  llvm::AlignedCharArrayUnion<TempPCHFile, InMemoryPreamble> Storage = {};
188  };
189 
190  /// Data used to determine if a file used in the preamble has been changed.
191  struct PreambleFileHash {
192  /// All files have size set.
193  off_t Size = 0;
194 
195  /// Modification time is set for files that are on disk. For memory
196  /// buffers it is zero.
197  time_t ModTime = 0;
198 
199  /// Memory buffers have MD5 instead of modification time. We don't
200  /// compute MD5 for on-disk files because we hope that modification time is
201  /// enough to tell if the file was changed.
202  llvm::MD5::MD5Result MD5 = {};
203 
204  static PreambleFileHash createForFile(off_t Size, time_t ModTime);
205  static PreambleFileHash
206  createForMemoryBuffer(const llvm::MemoryBuffer *Buffer);
207 
208  friend bool operator==(const PreambleFileHash &LHS,
209  const PreambleFileHash &RHS) {
210  return LHS.Size == RHS.Size && LHS.ModTime == RHS.ModTime &&
211  LHS.MD5 == RHS.MD5;
212  }
213  friend bool operator!=(const PreambleFileHash &LHS,
214  const PreambleFileHash &RHS) {
215  return !(LHS == RHS);
216  }
217  };
218 
219  /// Sets up the PreprocessorOptions and changes VFS, so that PCH stored in \p
220  /// Storage is accessible to clang. This method is an implementation detail of
221  /// AddImplicitPreamble.
222  static void setupPreambleStorage(const PCHStorage &Storage,
223  PreprocessorOptions &PreprocessorOpts,
225 
226  /// Manages the memory buffer or temporary file that stores the PCH.
227  PCHStorage Storage;
228  /// Keeps track of the files that were used when computing the
229  /// preamble, with both their buffer size and their modification time.
230  ///
231  /// If any of the files have changed from one compile to the next,
232  /// the preamble must be thrown away.
233  llvm::StringMap<PreambleFileHash> FilesInPreamble;
234  /// The contents of the file that was used to precompile the preamble. Only
235  /// contains first PreambleBounds::Size bytes. Used to compare if the relevant
236  /// part of the file has not changed, so that preamble can be reused.
237  std::vector<char> PreambleBytes;
238  /// See PreambleBounds::PreambleEndsAtStartOfLine
239  bool PreambleEndsAtStartOfLine;
240 };
241 
242 /// A set of callbacks to gather useful information while building a preamble.
244 public:
245  virtual ~PreambleCallbacks() = default;
246 
247  /// Called after FrontendAction::Execute(), but before
248  /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
249  /// various CompilerInstance fields before they are destroyed.
250  virtual void AfterExecute(CompilerInstance &CI);
251  /// Called after PCH has been emitted. \p Writer may be used to retrieve
252  /// information about AST, serialized in PCH.
253  virtual void AfterPCHEmitted(ASTWriter &Writer);
254  /// Called for each TopLevelDecl.
255  /// NOTE: To allow more flexibility a custom ASTConsumer could probably be
256  /// used instead, but having only this method allows a simpler API.
257  virtual void HandleTopLevelDecl(DeclGroupRef DG);
258  /// Called for each macro defined in the Preamble.
259  /// NOTE: To allow more flexibility a custom PPCallbacks could probably be
260  /// used instead, but having only this method allows a simpler API.
261  virtual void HandleMacroDefined(const Token &MacroNameTok,
262  const MacroDirective *MD);
263 };
264 
265 enum class BuildPreambleError {
266  PreambleIsEmpty = 1,
272 };
273 
274 class BuildPreambleErrorCategory final : public std::error_category {
275 public:
276  const char *name() const noexcept override;
277  std::string message(int condition) const override;
278 };
279 
280 std::error_code make_error_code(BuildPreambleError Error);
281 } // namespace clang
282 
283 namespace std {
284 template <>
285 struct is_error_code_enum<clang::BuildPreambleError> : std::true_type {};
286 } // namespace std
287 
288 #endif
Describes the bounds (start, size) of the preamble and a flag required by PreprocessorOptions::Precom...
Definition: Lexer.h:59
bool operator==(CanQual< T > x, CanQual< U > y)
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:26
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
The virtual file system interface.
Definition: Format.h:1900
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
std::error_code make_error_code(BuildPreambleError Error)
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:147
A set of callbacks to gather useful information while building a preamble.
Defines the clang::Preprocessor interface.
PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts, llvm::MemoryBuffer *Buffer, unsigned MaxLines)
Runs lexer to compute suggested preamble bounds.
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Definition: MacroInfo.h:291
Kind
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
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...
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:104
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:915