]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Frontend/PrecompiledPreamble.h
MFV r323530,r323533,r323534: 7431 ZFS Channel Programs, and followups
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Frontend / PrecompiledPreamble.h
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.
41 struct PreambleBounds {
42   PreambleBounds(unsigned Size, bool PreambleEndsAtStartOfLine)
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.
51   bool PreambleEndsAtStartOfLine;
52 };
53
54 /// \brief Runs lexer to compute suggested preamble bounds.
55 PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts,
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.
64 class PrecompiledPreamble {
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,
93         DiagnosticsEngine &Diagnostics, IntrusiveRefCntPtr<vfs::FileSystem> VFS,
94         std::shared_ptr<PCHContainerOperations> PCHContainerOps,
95         PreambleCallbacks &Callbacks);
96
97   PrecompiledPreamble(PrecompiledPreamble &&) = default;
98   PrecompiledPreamble &operator=(PrecompiledPreamble &&) = default;
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.
111   void AddImplicitPreamble(CompilerInvocation &CI,
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:
154     llvm::Optional<std::string> FilePath;
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.
203 class PreambleCallbacks {
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,
227   CouldntCreateTempFile,
228   CouldntCreateTargetInfo,
229   CouldntCreateVFSOverlay,
230   BeginSourceFileFailed,
231   CouldntEmitPCH
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