Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===- Tooling.h - Framework for standalone Clang tools ---------*- 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. //  This file implements functions to run clang tools standalone instead
  10. //  of running them as a plugin.
  11. //
  12. //  A ClangTool is initialized with a CompilationDatabase and a set of files
  13. //  to run over. The tool will then run a user-specified FrontendAction over
  14. //  all TUs in which the given files are compiled.
  15. //
  16. //  It is also possible to run a FrontendAction over a snippet of code by
  17. //  calling runToolOnCode, which is useful for unit testing.
  18. //
  19. //  Applications that need more fine grained control over how to run
  20. //  multiple FrontendActions over code can use ToolInvocation.
  21. //
  22. //  Example tools:
  23. //  - running clang -fsyntax-only over source code from an editor to get
  24. //    fast syntax checks
  25. //  - running match/replace tools over C++ code
  26. //
  27. //===----------------------------------------------------------------------===//
  28.  
  29. #ifndef LLVM_CLANG_TOOLING_TOOLING_H
  30. #define LLVM_CLANG_TOOLING_TOOLING_H
  31.  
  32. #include "clang/AST/ASTConsumer.h"
  33. #include "clang/Basic/FileManager.h"
  34. #include "clang/Basic/LLVM.h"
  35. #include "clang/Frontend/FrontendAction.h"
  36. #include "clang/Frontend/PCHContainerOperations.h"
  37. #include "clang/Tooling/ArgumentsAdjusters.h"
  38. #include "llvm/ADT/ArrayRef.h"
  39. #include "llvm/ADT/IntrusiveRefCntPtr.h"
  40. #include "llvm/ADT/StringMap.h"
  41. #include "llvm/ADT/StringRef.h"
  42. #include "llvm/ADT/StringSet.h"
  43. #include "llvm/ADT/Twine.h"
  44. #include "llvm/Option/Option.h"
  45. #include "llvm/Support/VirtualFileSystem.h"
  46. #include <memory>
  47. #include <string>
  48. #include <utility>
  49. #include <vector>
  50.  
  51. namespace clang {
  52.  
  53. class CompilerInstance;
  54. class CompilerInvocation;
  55. class DiagnosticConsumer;
  56. class DiagnosticsEngine;
  57.  
  58. namespace driver {
  59.  
  60. class Compilation;
  61.  
  62. } // namespace driver
  63.  
  64. namespace tooling {
  65.  
  66. class CompilationDatabase;
  67.  
  68. /// Retrieves the flags of the `-cc1` job in `Compilation` that has only source
  69. /// files as its inputs.
  70. /// Returns nullptr if there are no such jobs or multiple of them. Note that
  71. /// offloading jobs are ignored.
  72. const llvm::opt::ArgStringList *
  73. getCC1Arguments(DiagnosticsEngine *Diagnostics,
  74.                 driver::Compilation *Compilation);
  75.  
  76. /// Interface to process a clang::CompilerInvocation.
  77. ///
  78. /// If your tool is based on FrontendAction, you should be deriving from
  79. /// FrontendActionFactory instead.
  80. class ToolAction {
  81. public:
  82.   virtual ~ToolAction();
  83.  
  84.   /// Perform an action for an invocation.
  85.   virtual bool
  86.   runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
  87.                 FileManager *Files,
  88.                 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
  89.                 DiagnosticConsumer *DiagConsumer) = 0;
  90. };
  91.  
  92. /// Interface to generate clang::FrontendActions.
  93. ///
  94. /// Having a factory interface allows, for example, a new FrontendAction to be
  95. /// created for each translation unit processed by ClangTool.  This class is
  96. /// also a ToolAction which uses the FrontendActions created by create() to
  97. /// process each translation unit.
  98. class FrontendActionFactory : public ToolAction {
  99. public:
  100.   ~FrontendActionFactory() override;
  101.  
  102.   /// Invokes the compiler with a FrontendAction created by create().
  103.   bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
  104.                      FileManager *Files,
  105.                      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
  106.                      DiagnosticConsumer *DiagConsumer) override;
  107.  
  108.   /// Returns a new clang::FrontendAction.
  109.   virtual std::unique_ptr<FrontendAction> create() = 0;
  110. };
  111.  
  112. /// Returns a new FrontendActionFactory for a given type.
  113. ///
  114. /// T must derive from clang::FrontendAction.
  115. ///
  116. /// Example:
  117. /// std::unique_ptr<FrontendActionFactory> Factory =
  118. ///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
  119. template <typename T>
  120. std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
  121.  
  122. /// Callbacks called before and after each source file processed by a
  123. /// FrontendAction created by the FrontedActionFactory returned by \c
  124. /// newFrontendActionFactory.
  125. class SourceFileCallbacks {
  126. public:
  127.   virtual ~SourceFileCallbacks() = default;
  128.  
  129.   /// Called before a source file is processed by a FrontEndAction.
  130.   /// \see clang::FrontendAction::BeginSourceFileAction
  131.   virtual bool handleBeginSource(CompilerInstance &CI) {
  132.     return true;
  133.   }
  134.  
  135.   /// Called after a source file is processed by a FrontendAction.
  136.   /// \see clang::FrontendAction::EndSourceFileAction
  137.   virtual void handleEndSource() {}
  138. };
  139.  
  140. /// Returns a new FrontendActionFactory for any type that provides an
  141. /// implementation of newASTConsumer().
  142. ///
  143. /// FactoryT must implement: ASTConsumer *newASTConsumer().
  144. ///
  145. /// Example:
  146. /// struct ProvidesASTConsumers {
  147. ///   std::unique_ptr<clang::ASTConsumer> newASTConsumer();
  148. /// } Factory;
  149. /// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
  150. ///   newFrontendActionFactory(&Factory));
  151. template <typename FactoryT>
  152. inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
  153.     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
  154.  
  155. /// Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
  156. ///
  157. /// \param ToolAction The action to run over the code.
  158. /// \param Code C++ code.
  159. /// \param FileName The file name which 'Code' will be mapped as.
  160. /// \param PCHContainerOps  The PCHContainerOperations for loading and creating
  161. ///                         clang modules.
  162. ///
  163. /// \return - True if 'ToolAction' was successfully executed.
  164. bool runToolOnCode(std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
  165.                    const Twine &FileName = "input.cc",
  166.                    std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  167.                        std::make_shared<PCHContainerOperations>());
  168.  
  169. /// The first part of the pair is the filename, the second part the
  170. /// file-content.
  171. using FileContentMappings = std::vector<std::pair<std::string, std::string>>;
  172.  
  173. /// Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
  174. ///        with additional other flags.
  175. ///
  176. /// \param ToolAction The action to run over the code.
  177. /// \param Code C++ code.
  178. /// \param Args Additional flags to pass on.
  179. /// \param FileName The file name which 'Code' will be mapped as.
  180. /// \param ToolName The name of the binary running the tool. Standard library
  181. ///                 header paths will be resolved relative to this.
  182. /// \param PCHContainerOps   The PCHContainerOperations for loading and creating
  183. ///                          clang modules.
  184. ///
  185. /// \return - True if 'ToolAction' was successfully executed.
  186. bool runToolOnCodeWithArgs(
  187.     std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
  188.     const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
  189.     const Twine &ToolName = "clang-tool",
  190.     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  191.         std::make_shared<PCHContainerOperations>(),
  192.     const FileContentMappings &VirtualMappedFiles = FileContentMappings());
  193.  
  194. // Similar to the overload except this takes a VFS.
  195. bool runToolOnCodeWithArgs(
  196.     std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
  197.     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
  198.     const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
  199.     const Twine &ToolName = "clang-tool",
  200.     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  201.         std::make_shared<PCHContainerOperations>());
  202.  
  203. /// Builds an AST for 'Code'.
  204. ///
  205. /// \param Code C++ code.
  206. /// \param FileName The file name which 'Code' will be mapped as.
  207. /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  208. /// clang modules.
  209. ///
  210. /// \return The resulting AST or null if an error occurred.
  211. std::unique_ptr<ASTUnit>
  212. buildASTFromCode(StringRef Code, StringRef FileName = "input.cc",
  213.                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  214.                      std::make_shared<PCHContainerOperations>());
  215.  
  216. /// Builds an AST for 'Code' with additional flags.
  217. ///
  218. /// \param Code C++ code.
  219. /// \param Args Additional flags to pass on.
  220. /// \param FileName The file name which 'Code' will be mapped as.
  221. /// \param ToolName The name of the binary running the tool. Standard library
  222. ///                 header paths will be resolved relative to this.
  223. /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  224. /// clang modules.
  225. ///
  226. /// \param Adjuster A function to filter the command line arguments as specified.
  227. ///
  228. /// \return The resulting AST or null if an error occurred.
  229. std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
  230.     StringRef Code, const std::vector<std::string> &Args,
  231.     StringRef FileName = "input.cc", StringRef ToolName = "clang-tool",
  232.     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  233.         std::make_shared<PCHContainerOperations>(),
  234.     ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster(),
  235.     const FileContentMappings &VirtualMappedFiles = FileContentMappings(),
  236.     DiagnosticConsumer *DiagConsumer = nullptr);
  237.  
  238. /// Utility to run a FrontendAction in a single clang invocation.
  239. class ToolInvocation {
  240. public:
  241.   /// Create a tool invocation.
  242.   ///
  243.   /// \param CommandLine The command line arguments to clang. Note that clang
  244.   /// uses its binary name (CommandLine[0]) to locate its builtin headers.
  245.   /// Callers have to ensure that they are installed in a compatible location
  246.   /// (see clang driver implementation) or mapped in via mapVirtualFile.
  247.   /// \param FAction The action to be executed.
  248.   /// \param Files The FileManager used for the execution. Class does not take
  249.   /// ownership.
  250.   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  251.   /// clang modules.
  252.   ToolInvocation(std::vector<std::string> CommandLine,
  253.                  std::unique_ptr<FrontendAction> FAction, FileManager *Files,
  254.                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  255.                      std::make_shared<PCHContainerOperations>());
  256.  
  257.   /// Create a tool invocation.
  258.   ///
  259.   /// \param CommandLine The command line arguments to clang.
  260.   /// \param Action The action to be executed.
  261.   /// \param Files The FileManager used for the execution.
  262.   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  263.   /// clang modules.
  264.   ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
  265.                  FileManager *Files,
  266.                  std::shared_ptr<PCHContainerOperations> PCHContainerOps);
  267.  
  268.   ~ToolInvocation();
  269.  
  270.   /// Set a \c DiagnosticConsumer to use during driver command-line parsing and
  271.   /// the action invocation itself.
  272.   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
  273.     this->DiagConsumer = DiagConsumer;
  274.   }
  275.  
  276.   /// Set a \c DiagnosticOptions to use during driver command-line parsing.
  277.   void setDiagnosticOptions(DiagnosticOptions *DiagOpts) {
  278.     this->DiagOpts = DiagOpts;
  279.   }
  280.  
  281.   /// Run the clang invocation.
  282.   ///
  283.   /// \returns True if there were no errors during execution.
  284.   bool run();
  285.  
  286.  private:
  287.   bool runInvocation(const char *BinaryName,
  288.                      driver::Compilation *Compilation,
  289.                      std::shared_ptr<CompilerInvocation> Invocation,
  290.                      std::shared_ptr<PCHContainerOperations> PCHContainerOps);
  291.  
  292.   std::vector<std::string> CommandLine;
  293.   ToolAction *Action;
  294.   bool OwnsAction;
  295.   FileManager *Files;
  296.   std::shared_ptr<PCHContainerOperations> PCHContainerOps;
  297.   DiagnosticConsumer *DiagConsumer = nullptr;
  298.   DiagnosticOptions *DiagOpts = nullptr;
  299. };
  300.  
  301. /// Utility to run a FrontendAction over a set of files.
  302. ///
  303. /// This class is written to be usable for command line utilities.
  304. /// By default the class uses ClangSyntaxOnlyAdjuster to modify
  305. /// command line arguments before the arguments are used to run
  306. /// a frontend action. One could install an additional command line
  307. /// arguments adjuster by calling the appendArgumentsAdjuster() method.
  308. class ClangTool {
  309. public:
  310.   /// Constructs a clang tool to run over a list of files.
  311.   ///
  312.   /// \param Compilations The CompilationDatabase which contains the compile
  313.   ///        command lines for the given source paths.
  314.   /// \param SourcePaths The source files to run over. If a source files is
  315.   ///        not found in Compilations, it is skipped.
  316.   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  317.   /// clang modules.
  318.   /// \param BaseFS VFS used for all underlying file accesses when running the
  319.   /// tool.
  320.   /// \param Files The file manager to use for underlying file operations when
  321.   /// running the tool.
  322.   ClangTool(const CompilationDatabase &Compilations,
  323.             ArrayRef<std::string> SourcePaths,
  324.             std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  325.                 std::make_shared<PCHContainerOperations>(),
  326.             IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS =
  327.                 llvm::vfs::getRealFileSystem(),
  328.             IntrusiveRefCntPtr<FileManager> Files = nullptr);
  329.  
  330.   ~ClangTool();
  331.  
  332.   /// Set a \c DiagnosticConsumer to use during parsing.
  333.   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
  334.     this->DiagConsumer = DiagConsumer;
  335.   }
  336.  
  337.   /// Map a virtual file to be used while running the tool.
  338.   ///
  339.   /// \param FilePath The path at which the content will be mapped.
  340.   /// \param Content A null terminated buffer of the file's content.
  341.   void mapVirtualFile(StringRef FilePath, StringRef Content);
  342.  
  343.   /// Append a command line arguments adjuster to the adjuster chain.
  344.   ///
  345.   /// \param Adjuster An argument adjuster, which will be run on the output of
  346.   ///        previous argument adjusters.
  347.   void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
  348.  
  349.   /// Clear the command line arguments adjuster chain.
  350.   void clearArgumentsAdjusters();
  351.  
  352.   /// Runs an action over all files specified in the command line.
  353.   ///
  354.   /// \param Action Tool action.
  355.   ///
  356.   /// \returns 0 on success; 1 if any error occurred; 2 if there is no error but
  357.   /// some files are skipped due to missing compile commands.
  358.   int run(ToolAction *Action);
  359.  
  360.   /// Create an AST for each file specified in the command line and
  361.   /// append them to ASTs.
  362.   int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
  363.  
  364.   /// Sets whether working directory should be restored after calling run(). By
  365.   /// default, working directory is restored. However, it could be useful to
  366.   /// turn this off when running on multiple threads to avoid the raciness.
  367.   void setRestoreWorkingDir(bool RestoreCWD);
  368.  
  369.   /// Sets whether an error message should be printed out if an action fails. By
  370.   /// default, if an action fails, a message is printed out to stderr.
  371.   void setPrintErrorMessage(bool PrintErrorMessage);
  372.  
  373.   /// Returns the file manager used in the tool.
  374.   ///
  375.   /// The file manager is shared between all translation units.
  376.   FileManager &getFiles() { return *Files; }
  377.  
  378.   llvm::ArrayRef<std::string> getSourcePaths() const { return SourcePaths; }
  379.  
  380. private:
  381.   const CompilationDatabase &Compilations;
  382.   std::vector<std::string> SourcePaths;
  383.   std::shared_ptr<PCHContainerOperations> PCHContainerOps;
  384.  
  385.   llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem;
  386.   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
  387.   llvm::IntrusiveRefCntPtr<FileManager> Files;
  388.  
  389.   // Contains a list of pairs (<file name>, <file content>).
  390.   std::vector<std::pair<StringRef, StringRef>> MappedFileContents;
  391.  
  392.   llvm::StringSet<> SeenWorkingDirectories;
  393.  
  394.   ArgumentsAdjuster ArgsAdjuster;
  395.  
  396.   DiagnosticConsumer *DiagConsumer = nullptr;
  397.  
  398.   bool RestoreCWD = true;
  399.   bool PrintErrorMessage = true;
  400. };
  401.  
  402. template <typename T>
  403. std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
  404.   class SimpleFrontendActionFactory : public FrontendActionFactory {
  405.   public:
  406.     std::unique_ptr<FrontendAction> create() override {
  407.       return std::make_unique<T>();
  408.     }
  409.   };
  410.  
  411.   return std::unique_ptr<FrontendActionFactory>(
  412.       new SimpleFrontendActionFactory);
  413. }
  414.  
  415. template <typename FactoryT>
  416. inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
  417.     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
  418.   class FrontendActionFactoryAdapter : public FrontendActionFactory {
  419.   public:
  420.     explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
  421.                                           SourceFileCallbacks *Callbacks)
  422.         : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
  423.  
  424.     std::unique_ptr<FrontendAction> create() override {
  425.       return std::make_unique<ConsumerFactoryAdaptor>(ConsumerFactory,
  426.                                                       Callbacks);
  427.     }
  428.  
  429.   private:
  430.     class ConsumerFactoryAdaptor : public ASTFrontendAction {
  431.     public:
  432.       ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
  433.                              SourceFileCallbacks *Callbacks)
  434.           : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
  435.  
  436.       std::unique_ptr<ASTConsumer>
  437.       CreateASTConsumer(CompilerInstance &, StringRef) override {
  438.         return ConsumerFactory->newASTConsumer();
  439.       }
  440.  
  441.     protected:
  442.       bool BeginSourceFileAction(CompilerInstance &CI) override {
  443.         if (!ASTFrontendAction::BeginSourceFileAction(CI))
  444.           return false;
  445.         if (Callbacks)
  446.           return Callbacks->handleBeginSource(CI);
  447.         return true;
  448.       }
  449.  
  450.       void EndSourceFileAction() override {
  451.         if (Callbacks)
  452.           Callbacks->handleEndSource();
  453.         ASTFrontendAction::EndSourceFileAction();
  454.       }
  455.  
  456.     private:
  457.       FactoryT *ConsumerFactory;
  458.       SourceFileCallbacks *Callbacks;
  459.     };
  460.     FactoryT *ConsumerFactory;
  461.     SourceFileCallbacks *Callbacks;
  462.   };
  463.  
  464.   return std::unique_ptr<FrontendActionFactory>(
  465.       new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
  466. }
  467.  
  468. /// Returns the absolute path of \c File, by prepending it with
  469. /// the current directory if \c File is not absolute.
  470. ///
  471. /// Otherwise returns \c File.
  472. /// If 'File' starts with "./", the returned path will not contain the "./".
  473. /// Otherwise, the returned path will contain the literal path-concatenation of
  474. /// the current directory and \c File.
  475. ///
  476. /// The difference to llvm::sys::fs::make_absolute is the canonicalization this
  477. /// does by removing "./" and computing native paths.
  478. ///
  479. /// \param File Either an absolute or relative path.
  480. std::string getAbsolutePath(StringRef File);
  481.  
  482. /// An overload of getAbsolutePath that works over the provided \p FS.
  483. llvm::Expected<std::string> getAbsolutePath(llvm::vfs::FileSystem &FS,
  484.                                             StringRef File);
  485.  
  486. /// Changes CommandLine to contain implicit flags that would have been
  487. /// defined had the compiler driver been invoked through the path InvokedAs.
  488. ///
  489. /// For example, when called with \c InvokedAs set to `i686-linux-android-g++`,
  490. /// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will
  491. /// be inserted after the first argument in \c CommandLine.
  492. ///
  493. /// This function will not add new `-target` or `--driver-mode` flags if they
  494. /// are already present in `CommandLine` (even if they have different settings
  495. /// than would have been inserted).
  496. ///
  497. /// \pre `llvm::InitializeAllTargets()` has been called.
  498. ///
  499. /// \param CommandLine the command line used to invoke the compiler driver or
  500. /// Clang tool, including the path to the executable as \c CommandLine[0].
  501. /// \param InvokedAs the path to the driver used to infer implicit flags.
  502. ///
  503. /// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling
  504. /// infrastructure expects that CommandLine[0] is a tool path relative to which
  505. /// the builtin headers can be found.
  506. void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
  507.                                     StringRef InvokedAs);
  508.  
  509. /// Creates a \c CompilerInvocation.
  510. CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics,
  511.                                   ArrayRef<const char *> CC1Args,
  512.                                   const char *const BinaryName);
  513.  
  514. } // namespace tooling
  515.  
  516. } // namespace clang
  517.  
  518. #endif // LLVM_CLANG_TOOLING_TOOLING_H
  519.