Execution.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- Execution.h - Executing clang frontend actions -*- 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. // This file defines framework for executing clang frontend actions.
  15. //
  16. // The framework can be extended to support different execution plans including
  17. // standalone execution on the given TUs or parallel execution on all TUs in
  18. // the codebase.
  19. //
  20. // In order to enable multiprocessing execution, tool actions are expected to
  21. // output result into the ToolResults provided by the executor. The
  22. // `ToolResults` is an interface that abstracts how results are stored e.g.
  23. // in-memory for standalone execution or on-disk for large-scale execution.
  24. //
  25. // New executors can be registered as ToolExecutorPlugins via the
  26. // `ToolExecutorPluginRegistry`. CLI tools can use
  27. // `createExecutorFromCommandLineArgs` to create a specific registered executor
  28. // according to the command-line arguments.
  29. //
  30. //===----------------------------------------------------------------------===//
  31. #ifndef LLVM_CLANG_TOOLING_EXECUTION_H
  32. #define LLVM_CLANG_TOOLING_EXECUTION_H
  33. #include "clang/Tooling/CommonOptionsParser.h"
  34. #include "clang/Tooling/Tooling.h"
  35. #include "llvm/Support/Error.h"
  36. #include "llvm/Support/Registry.h"
  37. #include "llvm/Support/StringSaver.h"
  38. namespace clang {
  39. namespace tooling {
  40. extern llvm::cl::opt<std::string> ExecutorName;
  41. /// An abstraction for the result of a tool execution. For example, the
  42. /// underlying result can be in-memory or on-disk.
  43. ///
  44. /// Results should be string key-value pairs. For example, a refactoring tool
  45. /// can use source location as key and a replacement in YAML format as value.
  46. class ToolResults {
  47. public:
  48. virtual ~ToolResults() = default;
  49. virtual void addResult(StringRef Key, StringRef Value) = 0;
  50. virtual std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
  51. AllKVResults() = 0;
  52. virtual void forEachResult(
  53. llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) = 0;
  54. };
  55. /// Stores the key-value results in memory. It maintains the lifetime of
  56. /// the result. Clang tools using this class are expected to generate a small
  57. /// set of different results, or a large set of duplicated results.
  58. class InMemoryToolResults : public ToolResults {
  59. public:
  60. InMemoryToolResults() : Strings(Arena) {}
  61. void addResult(StringRef Key, StringRef Value) override;
  62. std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
  63. AllKVResults() override;
  64. void forEachResult(llvm::function_ref<void(StringRef Key, StringRef Value)>
  65. Callback) override;
  66. private:
  67. llvm::BumpPtrAllocator Arena;
  68. llvm::UniqueStringSaver Strings;
  69. std::vector<std::pair<llvm::StringRef, llvm::StringRef>> KVResults;
  70. };
  71. /// The context of an execution, including the information about
  72. /// compilation and results.
  73. class ExecutionContext {
  74. public:
  75. virtual ~ExecutionContext() {}
  76. /// Initializes a context. This does not take ownership of `Results`.
  77. explicit ExecutionContext(ToolResults *Results) : Results(Results) {}
  78. /// Adds a KV pair to the result container of this execution.
  79. void reportResult(StringRef Key, StringRef Value);
  80. // Returns the source control system's revision number if applicable.
  81. // Otherwise returns an empty string.
  82. virtual std::string getRevision() { return ""; }
  83. // Returns the corpus being analyzed, e.g. "llvm" for the LLVM codebase, if
  84. // applicable.
  85. virtual std::string getCorpus() { return ""; }
  86. // Returns the currently processed compilation unit if available.
  87. virtual std::string getCurrentCompilationUnit() { return ""; }
  88. private:
  89. ToolResults *Results;
  90. };
  91. /// Interface for executing clang frontend actions.
  92. ///
  93. /// This can be extended to support running tool actions in different
  94. /// execution mode, e.g. on a specific set of TUs or many TUs in parallel.
  95. ///
  96. /// New executors can be registered as ToolExecutorPlugins via the
  97. /// `ToolExecutorPluginRegistry`. CLI tools can use
  98. /// `createExecutorFromCommandLineArgs` to create a specific registered
  99. /// executor according to the command-line arguments.
  100. class ToolExecutor {
  101. public:
  102. virtual ~ToolExecutor() {}
  103. /// Returns the name of a specific executor.
  104. virtual StringRef getExecutorName() const = 0;
  105. /// Executes each action with a corresponding arguments adjuster.
  106. virtual llvm::Error
  107. execute(llvm::ArrayRef<
  108. std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
  109. Actions) = 0;
  110. /// Convenient functions for the above `execute`.
  111. llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action);
  112. /// Executes an action with an argument adjuster.
  113. llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action,
  114. ArgumentsAdjuster Adjuster);
  115. /// Returns a reference to the execution context.
  116. ///
  117. /// This should be passed to tool callbacks, and tool callbacks should report
  118. /// results via the returned context.
  119. virtual ExecutionContext *getExecutionContext() = 0;
  120. /// Returns a reference to the result container.
  121. ///
  122. /// NOTE: This should only be used after the execution finishes. Tool
  123. /// callbacks should report results via `ExecutionContext` instead.
  124. virtual ToolResults *getToolResults() = 0;
  125. /// Map a virtual file to be used while running the tool.
  126. ///
  127. /// \param FilePath The path at which the content will be mapped.
  128. /// \param Content A buffer of the file's content.
  129. virtual void mapVirtualFile(StringRef FilePath, StringRef Content) = 0;
  130. };
  131. /// Interface for factories that create specific executors. This is also
  132. /// used as a plugin to be registered into ToolExecutorPluginRegistry.
  133. class ToolExecutorPlugin {
  134. public:
  135. virtual ~ToolExecutorPlugin() {}
  136. /// Create an `ToolExecutor`.
  137. ///
  138. /// `OptionsParser` can be consumed (e.g. moved) if the creation succeeds.
  139. virtual llvm::Expected<std::unique_ptr<ToolExecutor>>
  140. create(CommonOptionsParser &OptionsParser) = 0;
  141. };
  142. /// This creates a ToolExecutor that is in the global registry based on
  143. /// commandline arguments.
  144. ///
  145. /// This picks the right executor based on the `--executor` option. This parses
  146. /// the commandline arguments with `CommonOptionsParser`, so caller does not
  147. /// need to parse again.
  148. ///
  149. /// By default, this creates a `StandaloneToolExecutor` ("standalone") if
  150. /// `--executor` is not provided.
  151. llvm::Expected<std::unique_ptr<ToolExecutor>>
  152. createExecutorFromCommandLineArgs(int &argc, const char **argv,
  153. llvm::cl::OptionCategory &Category,
  154. const char *Overview = nullptr);
  155. namespace internal {
  156. llvm::Expected<std::unique_ptr<ToolExecutor>>
  157. createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
  158. llvm::cl::OptionCategory &Category,
  159. const char *Overview = nullptr);
  160. } // end namespace internal
  161. } // end namespace tooling
  162. } // end namespace clang
  163. #endif // LLVM_CLANG_TOOLING_EXECUTION_H
  164. #ifdef __GNUC__
  165. #pragma GCC diagnostic pop
  166. #endif