clang  5.0.0
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/MD5.h"
21 #include <memory>
22 #include <system_error>
23 #include <type_traits>
24 
25 namespace llvm {
26 class MemoryBuffer;
27 }
28 
29 namespace clang {
30 namespace vfs {
31 class FileSystem;
32 }
33 
34 class CompilerInstance;
35 class CompilerInvocation;
36 class DeclGroupRef;
37 class PCHContainerOperations;
38 
39 /// A size of the preamble and a flag required by
40 /// PreprocessorOptions::PrecompiledPreambleBytes.
43  : Size(Size), PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {}
44 
45  /// \brief Size of the preamble in bytes.
46  unsigned Size;
47  /// \brief Whether the preamble ends at the start of a new line.
48  ///
49  /// Used to inform the lexer as to whether it's starting at the beginning of
50  /// a line after skipping the preamble.
52 };
53 
54 /// \brief Runs lexer to compute suggested preamble bounds.
56  llvm::MemoryBuffer *Buffer,
57  unsigned MaxLines);
58 
59 class PreambleCallbacks;
60 
61 /// A class holding a PCH and all information to check whether it is valid to
62 /// reuse the PCH for the subsequent runs. Use BuildPreamble to create PCH and
63 /// CanReusePreamble + AddImplicitPreamble to make use of it.
65  class TempPCHFile;
66  struct PreambleFileHash;
67 
68 public:
69  /// \brief Try to build PrecompiledPreamble for \p Invocation. See
70  /// BuildPreambleError for possible error codes.
71  ///
72  /// \param Invocation Original CompilerInvocation with options to compile the
73  /// file.
74  ///
75  /// \param MainFileBuffer Buffer with the contents of the main file.
76  ///
77  /// \param Bounds Bounds of the preamble, result of calling
78  /// ComputePreambleBounds.
79  ///
80  /// \param Diagnostics Diagnostics engine to be used while building the
81  /// preamble.
82  ///
83  /// \param VFS An instance of vfs::FileSystem to be used for file
84  /// accesses.
85  ///
86  /// \param PCHContainerOps An instance of PCHContainerOperations.
87  ///
88  /// \param Callbacks A set of callbacks to be executed when building
89  /// the preamble.
90  static llvm::ErrorOr<PrecompiledPreamble>
91  Build(const CompilerInvocation &Invocation,
92  const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
94  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
95  PreambleCallbacks &Callbacks);
96 
99 
100  /// PreambleBounds used to build the preamble
101  PreambleBounds getBounds() const;
102 
103  /// Check whether PrecompiledPreamble can be reused for the new contents(\p
104  /// MainFileBuffer) of the main file.
105  bool CanReuse(const CompilerInvocation &Invocation,
106  const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
107  vfs::FileSystem *VFS) const;
108 
109  /// Changes options inside \p CI to use PCH from this preamble. Also remaps
110  /// main file to \p MainFileBuffer.
112  llvm::MemoryBuffer *MainFileBuffer) const;
113 
114 private:
115  PrecompiledPreamble(TempPCHFile PCHFile, std::vector<char> PreambleBytes,
116  bool PreambleEndsAtStartOfLine,
117  llvm::StringMap<PreambleFileHash> FilesInPreamble);
118 
119  /// A temp file that would be deleted on destructor call. If destructor is not
120  /// called for any reason, the file will be deleted at static objects'
121  /// destruction.
122  /// An assertion will fire if two TempPCHFiles are created with the same name,
123  /// so it's not intended to be used outside preamble-handling.
124  class TempPCHFile {
125  public:
126  // A main method used to construct TempPCHFile.
127  static llvm::ErrorOr<TempPCHFile> CreateNewPreamblePCHFile();
128 
129  /// Call llvm::sys::fs::createTemporaryFile to create a new temporary file.
130  static llvm::ErrorOr<TempPCHFile> createInSystemTempDir(const Twine &Prefix,
131  StringRef Suffix);
132  /// Create a new instance of TemporaryFile for file at \p Path. Use with
133  /// extreme caution, there's an assertion checking that there's only a
134  /// single instance of TempPCHFile alive for each path.
135  static llvm::ErrorOr<TempPCHFile> createFromCustomPath(const Twine &Path);
136 
137  private:
138  TempPCHFile(std::string FilePath);
139 
140  public:
141  TempPCHFile(TempPCHFile &&Other);
142  TempPCHFile &operator=(TempPCHFile &&Other);
143 
144  TempPCHFile(const TempPCHFile &) = delete;
145  ~TempPCHFile();
146 
147  /// A path where temporary file is stored.
148  llvm::StringRef getFilePath() const;
149 
150  private:
151  void RemoveFileIfPresent();
152 
153  private:
155  };
156 
157  /// Data used to determine if a file used in the preamble has been changed.
158  struct PreambleFileHash {
159  /// All files have size set.
160  off_t Size = 0;
161 
162  /// Modification time is set for files that are on disk. For memory
163  /// buffers it is zero.
164  time_t ModTime = 0;
165 
166  /// Memory buffers have MD5 instead of modification time. We don't
167  /// compute MD5 for on-disk files because we hope that modification time is
168  /// enough to tell if the file was changed.
169  llvm::MD5::MD5Result MD5 = {};
170 
171  static PreambleFileHash createForFile(off_t Size, time_t ModTime);
172  static PreambleFileHash
173  createForMemoryBuffer(const llvm::MemoryBuffer *Buffer);
174 
175  friend bool operator==(const PreambleFileHash &LHS,
176  const PreambleFileHash &RHS) {
177  return LHS.Size == RHS.Size && LHS.ModTime == RHS.ModTime &&
178  LHS.MD5 == RHS.MD5;
179  }
180  friend bool operator!=(const PreambleFileHash &LHS,
181  const PreambleFileHash &RHS) {
182  return !(LHS == RHS);
183  }
184  };
185 
186  /// Manages the lifetime of temporary file that stores a PCH.
187  TempPCHFile PCHFile;
188  /// Keeps track of the files that were used when computing the
189  /// preamble, with both their buffer size and their modification time.
190  ///
191  /// If any of the files have changed from one compile to the next,
192  /// the preamble must be thrown away.
193  llvm::StringMap<PreambleFileHash> FilesInPreamble;
194  /// The contents of the file that was used to precompile the preamble. Only
195  /// contains first PreambleBounds::Size bytes. Used to compare if the relevant
196  /// part of the file has not changed, so that preamble can be reused.
197  std::vector<char> PreambleBytes;
198  /// See PreambleBounds::PreambleEndsAtStartOfLine
199  bool PreambleEndsAtStartOfLine;
200 };
201 
202 /// A set of callbacks to gather useful information while building a preamble.
204 public:
205  virtual ~PreambleCallbacks() = default;
206 
207  /// Called after FrontendAction::Execute(), but before
208  /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
209  /// various CompilerInstance fields before they are destroyed.
210  virtual void AfterExecute(CompilerInstance &CI);
211  /// Called after PCH has been emitted. \p Writer may be used to retrieve
212  /// information about AST, serialized in PCH.
213  virtual void AfterPCHEmitted(ASTWriter &Writer);
214  /// Called for each TopLevelDecl.
215  /// NOTE: To allow more flexibility a custom ASTConsumer could probably be
216  /// used instead, but having only this method allows a simpler API.
217  virtual void HandleTopLevelDecl(DeclGroupRef DG);
218  /// Called for each macro defined in the Preamble.
219  /// NOTE: To allow more flexibility a custom PPCallbacks could probably be
220  /// used instead, but having only this method allows a simpler API.
221  virtual void HandleMacroDefined(const Token &MacroNameTok,
222  const MacroDirective *MD);
223 };
224 
225 enum class BuildPreambleError {
226  PreambleIsEmpty = 1,
232 };
233 
234 class BuildPreambleErrorCategory final : public std::error_category {
235 public:
236  const char *name() const noexcept override;
237  std::string message(int condition) const override;
238 };
239 
240 std::error_code make_error_code(BuildPreambleError Error);
241 } // namespace clang
242 
243 namespace std {
244 template <>
245 struct is_error_code_enum<clang::BuildPreambleError> : std::true_type {};
246 } // namespace std
247 
248 #endif
A size of the preamble and a flag required by PreprocessorOptions::PrecompiledPreambleBytes.
bool operator==(CanQual< T > x, CanQual< U > y)
std::unique_ptr< llvm::MemoryBuffer > Buffer
The virtual file system interface.
const StringRef FilePath
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
std::error_code make_error_code(BuildPreambleError Error)
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:147
virtual ~PreambleCallbacks()=default
bool PreambleEndsAtStartOfLine
Whether the preamble ends at the start of a new line.
A set of callbacks to gather useful information while building a preamble.
PreambleBounds getBounds() const
PreambleBounds used to build the preamble.
Defines the clang::Preprocessor interface.
virtual void HandleMacroDefined(const Token &MacroNameTok, const MacroDirective *MD)
Called for each macro defined in the Preamble.
PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts, llvm::MemoryBuffer *Buffer, unsigned MaxLines)
Runs lexer to compute suggested preamble bounds.
bool CanReuse(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, vfs::FileSystem *VFS) const
Check whether PrecompiledPreamble can be reused for the new contents(MainFileBuffer) of the main file...
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Definition: MacroInfo.h:286
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
PreambleBounds(unsigned Size, bool PreambleEndsAtStartOfLine)
virtual void AfterPCHEmitted(ASTWriter &Writer)
Called after PCH has been emitted.
PrecompiledPreamble(PrecompiledPreamble &&)=default
std::string message(int condition) const override
const char * name() const noexceptoverride
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.
virtual void AfterExecute(CompilerInstance &CI)
Called after FrontendAction::Execute(), but before FrontendAction::EndSourceFile().
void AddImplicitPreamble(CompilerInvocation &CI, llvm::MemoryBuffer *MainFileBuffer) const
Changes options inside CI to use PCH from this preamble.
unsigned Size
Size of the preamble in bytes.
bool operator!=(CanQual< T > x, CanQual< U > y)
Writes an AST file containing the contents of a translation unit.
Definition: ASTWriter.h:82
static llvm::ErrorOr< PrecompiledPreamble > Build(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, DiagnosticsEngine &Diagnostics, IntrusiveRefCntPtr< vfs::FileSystem > VFS, std::shared_ptr< PCHContainerOperations > PCHContainerOps, PreambleCallbacks &Callbacks)
Try to build PrecompiledPreamble for Invocation.
virtual void HandleTopLevelDecl(DeclGroupRef DG)
Called for each TopLevelDecl.
PrecompiledPreamble & operator=(PrecompiledPreamble &&)=default