PrecompiledPreamble.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- PrecompiledPreamble.h - Build precompiled preambles ----*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // Helper class to build precompiled preamble.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_CLANG_FRONTEND_PRECOMPILEDPREAMBLE_H
  18. #define LLVM_CLANG_FRONTEND_PRECOMPILEDPREAMBLE_H
  19. #include "clang/Lex/Lexer.h"
  20. #include "clang/Lex/Preprocessor.h"
  21. #include "llvm/ADT/IntrusiveRefCntPtr.h"
  22. #include "llvm/ADT/StringRef.h"
  23. #include "llvm/Support/MD5.h"
  24. #include <cstddef>
  25. #include <memory>
  26. #include <system_error>
  27. #include <type_traits>
  28. namespace llvm {
  29. class MemoryBuffer;
  30. class MemoryBufferRef;
  31. namespace vfs {
  32. class FileSystem;
  33. }
  34. } // namespace llvm
  35. namespace clang {
  36. class CompilerInstance;
  37. class CompilerInvocation;
  38. class Decl;
  39. class DeclGroupRef;
  40. class PCHContainerOperations;
  41. /// Runs lexer to compute suggested preamble bounds.
  42. PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts,
  43. const llvm::MemoryBufferRef &Buffer,
  44. unsigned MaxLines);
  45. class PreambleCallbacks;
  46. /// A class holding a PCH and all information to check whether it is valid to
  47. /// reuse the PCH for the subsequent runs. Use BuildPreamble to create PCH and
  48. /// CanReusePreamble + AddImplicitPreamble to make use of it.
  49. class PrecompiledPreamble {
  50. class PCHStorage;
  51. struct PreambleFileHash;
  52. public:
  53. /// Try to build PrecompiledPreamble for \p Invocation. See
  54. /// BuildPreambleError for possible error codes.
  55. ///
  56. /// \param Invocation Original CompilerInvocation with options to compile the
  57. /// file.
  58. ///
  59. /// \param MainFileBuffer Buffer with the contents of the main file.
  60. ///
  61. /// \param Bounds Bounds of the preamble, result of calling
  62. /// ComputePreambleBounds.
  63. ///
  64. /// \param Diagnostics Diagnostics engine to be used while building the
  65. /// preamble.
  66. ///
  67. /// \param VFS An instance of vfs::FileSystem to be used for file
  68. /// accesses.
  69. ///
  70. /// \param PCHContainerOps An instance of PCHContainerOperations.
  71. ///
  72. /// \param StoreInMemory Store PCH in memory. If false, PCH will be stored in
  73. /// a temporary file.
  74. ///
  75. /// \param Callbacks A set of callbacks to be executed when building
  76. /// the preamble.
  77. static llvm::ErrorOr<PrecompiledPreamble>
  78. Build(const CompilerInvocation &Invocation,
  79. const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
  80. DiagnosticsEngine &Diagnostics,
  81. IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
  82. std::shared_ptr<PCHContainerOperations> PCHContainerOps,
  83. bool StoreInMemory, PreambleCallbacks &Callbacks);
  84. PrecompiledPreamble(PrecompiledPreamble &&);
  85. PrecompiledPreamble &operator=(PrecompiledPreamble &&);
  86. ~PrecompiledPreamble();
  87. /// PreambleBounds used to build the preamble.
  88. PreambleBounds getBounds() const;
  89. /// Returns the size, in bytes, that preamble takes on disk or in memory.
  90. /// For on-disk preambles returns 0 if filesystem operations fail. Intended to
  91. /// be used for logging and debugging purposes only.
  92. std::size_t getSize() const;
  93. /// Returned string is not null-terminated.
  94. llvm::StringRef getContents() const {
  95. return {PreambleBytes.data(), PreambleBytes.size()};
  96. }
  97. /// Check whether PrecompiledPreamble can be reused for the new contents(\p
  98. /// MainFileBuffer) of the main file.
  99. bool CanReuse(const CompilerInvocation &Invocation,
  100. const llvm::MemoryBufferRef &MainFileBuffer,
  101. PreambleBounds Bounds, llvm::vfs::FileSystem &VFS) const;
  102. /// Changes options inside \p CI to use PCH from this preamble. Also remaps
  103. /// main file to \p MainFileBuffer and updates \p VFS to ensure the preamble
  104. /// is accessible.
  105. /// Requires that CanReuse() is true.
  106. /// For in-memory preambles, PrecompiledPreamble instance continues to own the
  107. /// MemoryBuffer with the Preamble after this method returns. The caller is
  108. /// responsible for making sure the PrecompiledPreamble instance outlives the
  109. /// compiler run and the AST that will be using the PCH.
  110. void AddImplicitPreamble(CompilerInvocation &CI,
  111. IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS,
  112. llvm::MemoryBuffer *MainFileBuffer) const;
  113. /// Configure \p CI to use this preamble.
  114. /// Like AddImplicitPreamble, but doesn't assume CanReuse() is true.
  115. /// If this preamble does not match the file, it may parse differently.
  116. void OverridePreamble(CompilerInvocation &CI,
  117. IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS,
  118. llvm::MemoryBuffer *MainFileBuffer) const;
  119. private:
  120. PrecompiledPreamble(std::unique_ptr<PCHStorage> Storage,
  121. std::vector<char> PreambleBytes,
  122. bool PreambleEndsAtStartOfLine,
  123. llvm::StringMap<PreambleFileHash> FilesInPreamble,
  124. llvm::StringSet<> MissingFiles);
  125. /// Data used to determine if a file used in the preamble has been changed.
  126. struct PreambleFileHash {
  127. /// All files have size set.
  128. off_t Size = 0;
  129. /// Modification time is set for files that are on disk. For memory
  130. /// buffers it is zero.
  131. time_t ModTime = 0;
  132. /// Memory buffers have MD5 instead of modification time. We don't
  133. /// compute MD5 for on-disk files because we hope that modification time is
  134. /// enough to tell if the file was changed.
  135. llvm::MD5::MD5Result MD5 = {};
  136. static PreambleFileHash createForFile(off_t Size, time_t ModTime);
  137. static PreambleFileHash
  138. createForMemoryBuffer(const llvm::MemoryBufferRef &Buffer);
  139. friend bool operator==(const PreambleFileHash &LHS,
  140. const PreambleFileHash &RHS) {
  141. return LHS.Size == RHS.Size && LHS.ModTime == RHS.ModTime &&
  142. LHS.MD5 == RHS.MD5;
  143. }
  144. friend bool operator!=(const PreambleFileHash &LHS,
  145. const PreambleFileHash &RHS) {
  146. return !(LHS == RHS);
  147. }
  148. };
  149. /// Helper function to set up PCH for the preamble into \p CI and \p VFS to
  150. /// with the specified \p Bounds.
  151. void configurePreamble(PreambleBounds Bounds, CompilerInvocation &CI,
  152. IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS,
  153. llvm::MemoryBuffer *MainFileBuffer) const;
  154. /// Sets up the PreprocessorOptions and changes VFS, so that PCH stored in \p
  155. /// Storage is accessible to clang. This method is an implementation detail of
  156. /// AddImplicitPreamble.
  157. static void
  158. setupPreambleStorage(const PCHStorage &Storage,
  159. PreprocessorOptions &PreprocessorOpts,
  160. IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS);
  161. /// Manages the memory buffer or temporary file that stores the PCH.
  162. std::unique_ptr<PCHStorage> Storage;
  163. /// Keeps track of the files that were used when computing the
  164. /// preamble, with both their buffer size and their modification time.
  165. ///
  166. /// If any of the files have changed from one compile to the next,
  167. /// the preamble must be thrown away.
  168. llvm::StringMap<PreambleFileHash> FilesInPreamble;
  169. /// Files that were not found during preamble building. If any of these now
  170. /// exist then the preamble should not be reused.
  171. ///
  172. /// Storing *all* the missing files that could invalidate the preamble would
  173. /// make it too expensive to revalidate (when the include path has many
  174. /// entries, each #include will miss half of them on average).
  175. /// Instead, we track only files that could have satisfied an #include that
  176. /// was ultimately not found.
  177. llvm::StringSet<> MissingFiles;
  178. /// The contents of the file that was used to precompile the preamble. Only
  179. /// contains first PreambleBounds::Size bytes. Used to compare if the relevant
  180. /// part of the file has not changed, so that preamble can be reused.
  181. std::vector<char> PreambleBytes;
  182. /// See PreambleBounds::PreambleEndsAtStartOfLine
  183. bool PreambleEndsAtStartOfLine;
  184. };
  185. /// A set of callbacks to gather useful information while building a preamble.
  186. class PreambleCallbacks {
  187. public:
  188. virtual ~PreambleCallbacks() = default;
  189. /// Called before FrontendAction::Execute.
  190. /// Can be used to store references to various CompilerInstance fields
  191. /// (e.g. SourceManager) that may be interesting to the consumers of other
  192. /// callbacks.
  193. virtual void BeforeExecute(CompilerInstance &CI);
  194. /// Called after FrontendAction::Execute(), but before
  195. /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
  196. /// various CompilerInstance fields before they are destroyed.
  197. virtual void AfterExecute(CompilerInstance &CI);
  198. /// Called after PCH has been emitted. \p Writer may be used to retrieve
  199. /// information about AST, serialized in PCH.
  200. virtual void AfterPCHEmitted(ASTWriter &Writer);
  201. /// Called for each TopLevelDecl.
  202. /// NOTE: To allow more flexibility a custom ASTConsumer could probably be
  203. /// used instead, but having only this method allows a simpler API.
  204. virtual void HandleTopLevelDecl(DeclGroupRef DG);
  205. /// Creates wrapper class for PPCallbacks so we can also process information
  206. /// about includes that are inside of a preamble. Called after BeforeExecute.
  207. virtual std::unique_ptr<PPCallbacks> createPPCallbacks();
  208. /// The returned CommentHandler will be added to the preprocessor if not null.
  209. virtual CommentHandler *getCommentHandler();
  210. /// Determines which function bodies are parsed, by default skips everything.
  211. /// Only used if FrontendOpts::SkipFunctionBodies is true.
  212. /// See ASTConsumer::shouldSkipFunctionBody.
  213. virtual bool shouldSkipFunctionBody(Decl *D) { return true; }
  214. };
  215. enum class BuildPreambleError {
  216. CouldntCreateTempFile = 1,
  217. CouldntCreateTargetInfo,
  218. BeginSourceFileFailed,
  219. CouldntEmitPCH,
  220. BadInputs
  221. };
  222. class BuildPreambleErrorCategory final : public std::error_category {
  223. public:
  224. const char *name() const noexcept override;
  225. std::string message(int condition) const override;
  226. };
  227. std::error_code make_error_code(BuildPreambleError Error);
  228. } // namespace clang
  229. namespace std {
  230. template <>
  231. struct is_error_code_enum<clang::BuildPreambleError> : std::true_type {};
  232. } // namespace std
  233. #endif
  234. #ifdef __GNUC__
  235. #pragma GCC diagnostic pop
  236. #endif