Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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