PrecompiledPreamble.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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/AlignOf.h"
  24. #include "llvm/Support/MD5.h"
  25. #include <cstddef>
  26. #include <memory>
  27. #include <system_error>
  28. #include <type_traits>
  29. namespace llvm {
  30. class MemoryBuffer;
  31. class MemoryBufferRef;
  32. namespace vfs {
  33. class FileSystem;
  34. }
  35. } // namespace llvm
  36. namespace clang {
  37. class CompilerInstance;
  38. class CompilerInvocation;
  39. class Decl;
  40. class DeclGroupRef;
  41. class PCHContainerOperations;
  42. /// Runs lexer to compute suggested preamble bounds.
  43. PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts,
  44. const llvm::MemoryBufferRef &Buffer,
  45. unsigned MaxLines);
  46. class PreambleCallbacks;
  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.
  50. class PrecompiledPreamble {
  51. class PCHStorage;
  52. struct PreambleFileHash;
  53. public:
  54. /// Try to build PrecompiledPreamble for \p Invocation. See
  55. /// BuildPreambleError for possible error codes.
  56. ///
  57. /// \param Invocation Original CompilerInvocation with options to compile the
  58. /// file.
  59. ///
  60. /// \param MainFileBuffer Buffer with the contents of the main file.
  61. ///
  62. /// \param Bounds Bounds of the preamble, result of calling
  63. /// ComputePreambleBounds.
  64. ///
  65. /// \param Diagnostics Diagnostics engine to be used while building the
  66. /// preamble.
  67. ///
  68. /// \param VFS An instance of vfs::FileSystem to be used for file
  69. /// accesses.
  70. ///
  71. /// \param PCHContainerOps An instance of PCHContainerOperations.
  72. ///
  73. /// \param StoreInMemory Store PCH in memory. If false, PCH will be stored in
  74. /// a temporary file.
  75. ///
  76. /// \param Callbacks A set of callbacks to be executed when building
  77. /// the preamble.
  78. static llvm::ErrorOr<PrecompiledPreamble>
  79. Build(const CompilerInvocation &Invocation,
  80. const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
  81. DiagnosticsEngine &Diagnostics,
  82. IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
  83. std::shared_ptr<PCHContainerOperations> PCHContainerOps,
  84. bool StoreInMemory, PreambleCallbacks &Callbacks);
  85. PrecompiledPreamble(PrecompiledPreamble &&) = default;
  86. PrecompiledPreamble &operator=(PrecompiledPreamble &&) = default;
  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(PCHStorage Storage, std::vector<char> PreambleBytes,
  121. bool PreambleEndsAtStartOfLine,
  122. llvm::StringMap<PreambleFileHash> FilesInPreamble,
  123. llvm::StringSet<> MissingFiles);
  124. /// A temp file that would be deleted on destructor call. If destructor is not
  125. /// called for any reason, the file will be deleted at static objects'
  126. /// destruction.
  127. /// An assertion will fire if two TempPCHFiles are created with the same name,
  128. /// so it's not intended to be used outside preamble-handling.
  129. class TempPCHFile {
  130. public:
  131. // A main method used to construct TempPCHFile.
  132. static llvm::ErrorOr<TempPCHFile> CreateNewPreamblePCHFile();
  133. private:
  134. TempPCHFile(std::string FilePath);
  135. public:
  136. TempPCHFile(TempPCHFile &&Other);
  137. TempPCHFile &operator=(TempPCHFile &&Other);
  138. TempPCHFile(const TempPCHFile &) = delete;
  139. ~TempPCHFile();
  140. /// A path where temporary file is stored.
  141. llvm::StringRef getFilePath() const;
  142. private:
  143. void RemoveFileIfPresent();
  144. private:
  145. llvm::Optional<std::string> FilePath;
  146. };
  147. class InMemoryPreamble {
  148. public:
  149. std::string Data;
  150. };
  151. class PCHStorage {
  152. public:
  153. enum class Kind { Empty, InMemory, TempFile };
  154. PCHStorage() = default;
  155. PCHStorage(TempPCHFile File);
  156. PCHStorage(InMemoryPreamble Memory);
  157. PCHStorage(const PCHStorage &) = delete;
  158. PCHStorage &operator=(const PCHStorage &) = delete;
  159. PCHStorage(PCHStorage &&Other);
  160. PCHStorage &operator=(PCHStorage &&Other);
  161. ~PCHStorage();
  162. Kind getKind() const;
  163. TempPCHFile &asFile();
  164. const TempPCHFile &asFile() const;
  165. InMemoryPreamble &asMemory();
  166. const InMemoryPreamble &asMemory() const;
  167. private:
  168. void destroy();
  169. void setEmpty();
  170. private:
  171. Kind StorageKind = Kind::Empty;
  172. llvm::AlignedCharArrayUnion<TempPCHFile, InMemoryPreamble> Storage = {};
  173. };
  174. /// Data used to determine if a file used in the preamble has been changed.
  175. struct PreambleFileHash {
  176. /// All files have size set.
  177. off_t Size = 0;
  178. /// Modification time is set for files that are on disk. For memory
  179. /// buffers it is zero.
  180. time_t ModTime = 0;
  181. /// Memory buffers have MD5 instead of modification time. We don't
  182. /// compute MD5 for on-disk files because we hope that modification time is
  183. /// enough to tell if the file was changed.
  184. llvm::MD5::MD5Result MD5 = {};
  185. static PreambleFileHash createForFile(off_t Size, time_t ModTime);
  186. static PreambleFileHash
  187. createForMemoryBuffer(const llvm::MemoryBufferRef &Buffer);
  188. friend bool operator==(const PreambleFileHash &LHS,
  189. const PreambleFileHash &RHS) {
  190. return LHS.Size == RHS.Size && LHS.ModTime == RHS.ModTime &&
  191. LHS.MD5 == RHS.MD5;
  192. }
  193. friend bool operator!=(const PreambleFileHash &LHS,
  194. const PreambleFileHash &RHS) {
  195. return !(LHS == RHS);
  196. }
  197. };
  198. /// Helper function to set up PCH for the preamble into \p CI and \p VFS to
  199. /// with the specified \p Bounds.
  200. void configurePreamble(PreambleBounds Bounds, CompilerInvocation &CI,
  201. IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS,
  202. llvm::MemoryBuffer *MainFileBuffer) const;
  203. /// Sets up the PreprocessorOptions and changes VFS, so that PCH stored in \p
  204. /// Storage is accessible to clang. This method is an implementation detail of
  205. /// AddImplicitPreamble.
  206. static void
  207. setupPreambleStorage(const PCHStorage &Storage,
  208. PreprocessorOptions &PreprocessorOpts,
  209. IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS);
  210. /// Manages the memory buffer or temporary file that stores the PCH.
  211. PCHStorage Storage;
  212. /// Keeps track of the files that were used when computing the
  213. /// preamble, with both their buffer size and their modification time.
  214. ///
  215. /// If any of the files have changed from one compile to the next,
  216. /// the preamble must be thrown away.
  217. llvm::StringMap<PreambleFileHash> FilesInPreamble;
  218. /// Files that were not found during preamble building. If any of these now
  219. /// exist then the preamble should not be reused.
  220. ///
  221. /// Storing *all* the missing files that could invalidate the preamble would
  222. /// make it too expensive to revalidate (when the include path has many
  223. /// entries, each #include will miss half of them on average).
  224. /// Instead, we track only files that could have satisfied an #include that
  225. /// was ultimately not found.
  226. llvm::StringSet<> MissingFiles;
  227. /// The contents of the file that was used to precompile the preamble. Only
  228. /// contains first PreambleBounds::Size bytes. Used to compare if the relevant
  229. /// part of the file has not changed, so that preamble can be reused.
  230. std::vector<char> PreambleBytes;
  231. /// See PreambleBounds::PreambleEndsAtStartOfLine
  232. bool PreambleEndsAtStartOfLine;
  233. };
  234. /// A set of callbacks to gather useful information while building a preamble.
  235. class PreambleCallbacks {
  236. public:
  237. virtual ~PreambleCallbacks() = default;
  238. /// Called before FrontendAction::Execute.
  239. /// Can be used to store references to various CompilerInstance fields
  240. /// (e.g. SourceManager) that may be interesting to the consumers of other
  241. /// callbacks.
  242. virtual void BeforeExecute(CompilerInstance &CI);
  243. /// Called after FrontendAction::Execute(), but before
  244. /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
  245. /// various CompilerInstance fields before they are destroyed.
  246. virtual void AfterExecute(CompilerInstance &CI);
  247. /// Called after PCH has been emitted. \p Writer may be used to retrieve
  248. /// information about AST, serialized in PCH.
  249. virtual void AfterPCHEmitted(ASTWriter &Writer);
  250. /// Called for each TopLevelDecl.
  251. /// NOTE: To allow more flexibility a custom ASTConsumer could probably be
  252. /// used instead, but having only this method allows a simpler API.
  253. virtual void HandleTopLevelDecl(DeclGroupRef DG);
  254. /// Creates wrapper class for PPCallbacks so we can also process information
  255. /// about includes that are inside of a preamble. Called after BeforeExecute.
  256. virtual std::unique_ptr<PPCallbacks> createPPCallbacks();
  257. /// The returned CommentHandler will be added to the preprocessor if not null.
  258. virtual CommentHandler *getCommentHandler();
  259. /// Determines which function bodies are parsed, by default skips everything.
  260. /// Only used if FrontendOpts::SkipFunctionBodies is true.
  261. /// See ASTConsumer::shouldSkipFunctionBody.
  262. virtual bool shouldSkipFunctionBody(Decl *D) { return true; }
  263. };
  264. enum class BuildPreambleError {
  265. CouldntCreateTempFile = 1,
  266. CouldntCreateTargetInfo,
  267. BeginSourceFileFailed,
  268. CouldntEmitPCH,
  269. BadInputs
  270. };
  271. class BuildPreambleErrorCategory final : public std::error_category {
  272. public:
  273. const char *name() const noexcept override;
  274. std::string message(int condition) const override;
  275. };
  276. std::error_code make_error_code(BuildPreambleError Error);
  277. } // namespace clang
  278. namespace std {
  279. template <>
  280. struct is_error_code_enum<clang::BuildPreambleError> : std::true_type {};
  281. } // namespace std
  282. #endif
  283. #ifdef __GNUC__
  284. #pragma GCC diagnostic pop
  285. #endif