Execution.h revision 326941
1326941Sdim//===--- Execution.h - Executing clang frontend actions -*- C++ ---------*-===//
2326941Sdim//
3326941Sdim//                     The LLVM Compiler Infrastructure
4326941Sdim//
5326941Sdim// This file is distributed under the University of Illinois Open Source
6326941Sdim// License. See LICENSE.TXT for details.
7326941Sdim//
8326941Sdim//===----------------------------------------------------------------------===//
9326941Sdim//
10326941Sdim//  This file defines framework for executing clang frontend actions.
11326941Sdim//
12326941Sdim//  The framework can be extended to support different execution plans including
13326941Sdim//  standalone execution on the given TUs or parallel execution on all TUs in
14326941Sdim//  the codebase.
15326941Sdim//
16326941Sdim//  In order to enable multiprocessing execution, tool actions are expected to
17326941Sdim//  output result into the ToolResults provided by the executor. The
18326941Sdim//  `ToolResults` is an interface that abstracts how results are stored e.g.
19326941Sdim//  in-memory for standalone execution or on-disk for large-scale execution.
20326941Sdim//
21326941Sdim//  New executors can be registered as ToolExecutorPlugins via the
22326941Sdim//  `ToolExecutorPluginRegistry`. CLI tools can use
23326941Sdim//  `createExecutorFromCommandLineArgs` to create a specific registered executor
24326941Sdim//  according to the command-line arguments.
25326941Sdim//
26326941Sdim//===----------------------------------------------------------------------===//
27326941Sdim
28326941Sdim#ifndef LLVM_CLANG_TOOLING_EXECUTION_H
29326941Sdim#define LLVM_CLANG_TOOLING_EXECUTION_H
30326941Sdim
31326941Sdim#include "clang/Tooling/CommonOptionsParser.h"
32326941Sdim#include "clang/Tooling/Tooling.h"
33326941Sdim#include "llvm/Support/Error.h"
34326941Sdim#include "llvm/Support/Registry.h"
35326941Sdim
36326941Sdimnamespace clang {
37326941Sdimnamespace tooling {
38326941Sdim
39326941Sdim/// \brief An abstraction for the result of a tool execution. For example, the
40326941Sdim/// underlying result can be in-memory or on-disk.
41326941Sdim///
42326941Sdim/// Results should be string key-value pairs. For example, a refactoring tool
43326941Sdim/// can use source location as key and a replacement in YAML format as value.
44326941Sdimclass ToolResults {
45326941Sdimpublic:
46326941Sdim  virtual ~ToolResults() = default;
47326941Sdim  virtual void addResult(StringRef Key, StringRef Value) = 0;
48326941Sdim  virtual std::vector<std::pair<std::string, std::string>> AllKVResults() = 0;
49326941Sdim  virtual void forEachResult(
50326941Sdim      llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) = 0;
51326941Sdim};
52326941Sdim
53326941Sdimclass InMemoryToolResults : public ToolResults {
54326941Sdimpublic:
55326941Sdim  void addResult(StringRef Key, StringRef Value) override;
56326941Sdim  std::vector<std::pair<std::string, std::string>> AllKVResults() override;
57326941Sdim  void forEachResult(llvm::function_ref<void(StringRef Key, StringRef Value)>
58326941Sdim                         Callback) override;
59326941Sdim
60326941Sdimprivate:
61326941Sdim  std::vector<std::pair<std::string, std::string>> KVResults;
62326941Sdim};
63326941Sdim
64326941Sdim/// \brief The context of an execution, including the information about
65326941Sdim/// compilation and results.
66326941Sdimclass ExecutionContext {
67326941Sdimpublic:
68326941Sdim  virtual ~ExecutionContext() {}
69326941Sdim
70326941Sdim  /// \brief Initializes a context. This does not take ownership of `Results`.
71326941Sdim  explicit ExecutionContext(ToolResults *Results) : Results(Results) {}
72326941Sdim
73326941Sdim  /// \brief Adds a KV pair to the result container of this execution.
74326941Sdim  void reportResult(StringRef Key, StringRef Value);
75326941Sdim
76326941Sdim  // Returns the source control system's revision number if applicable.
77326941Sdim  // Otherwise returns an empty string.
78326941Sdim  virtual std::string getRevision() { return ""; }
79326941Sdim
80326941Sdim  // Returns the corpus being analyzed, e.g. "llvm" for the LLVM codebase, if
81326941Sdim  // applicable.
82326941Sdim  virtual std::string getCorpus() { return ""; }
83326941Sdim
84326941Sdim  // Returns the currently processed compilation unit if available.
85326941Sdim  virtual std::string getCurrentCompilationUnit() { return ""; }
86326941Sdim
87326941Sdimprivate:
88326941Sdim  ToolResults *Results;
89326941Sdim};
90326941Sdim
91326941Sdim/// \brief Interface for executing clang frontend actions.
92326941Sdim///
93326941Sdim/// This can be extended to support running tool actions in different
94326941Sdim/// execution mode, e.g. on a specific set of TUs or many TUs in parallel.
95326941Sdim///
96326941Sdim///  New executors can be registered as ToolExecutorPlugins via the
97326941Sdim///  `ToolExecutorPluginRegistry`. CLI tools can use
98326941Sdim///  `createExecutorFromCommandLineArgs` to create a specific registered
99326941Sdim///  executor according to the command-line arguments.
100326941Sdimclass ToolExecutor {
101326941Sdimpublic:
102326941Sdim  virtual ~ToolExecutor() {}
103326941Sdim
104326941Sdim  /// \brief Returns the name of a specific executor.
105326941Sdim  virtual StringRef getExecutorName() const = 0;
106326941Sdim
107326941Sdim  /// \brief Executes each action with a corresponding arguments adjuster.
108326941Sdim  virtual llvm::Error
109326941Sdim  execute(llvm::ArrayRef<
110326941Sdim          std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
111326941Sdim              Actions) = 0;
112326941Sdim
113326941Sdim  /// \brief Convenient functions for the above `execute`.
114326941Sdim  llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action);
115326941Sdim  /// Executes an action with an argument adjuster.
116326941Sdim  llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action,
117326941Sdim                      ArgumentsAdjuster Adjuster);
118326941Sdim
119326941Sdim  /// \brief Returns a reference to the execution context.
120326941Sdim  ///
121326941Sdim  /// This should be passed to tool callbacks, and tool callbacks should report
122326941Sdim  /// results via the returned context.
123326941Sdim  virtual ExecutionContext *getExecutionContext() = 0;
124326941Sdim
125326941Sdim  /// \brief Returns a reference to the result container.
126326941Sdim  ///
127326941Sdim  /// NOTE: This should only be used after the execution finishes. Tool
128326941Sdim  /// callbacks should report results via `ExecutionContext` instead.
129326941Sdim  virtual ToolResults *getToolResults() = 0;
130326941Sdim
131326941Sdim  /// \brief Map a virtual file to be used while running the tool.
132326941Sdim  ///
133326941Sdim  /// \param FilePath The path at which the content will be mapped.
134326941Sdim  /// \param Content A buffer of the file's content.
135326941Sdim  virtual void mapVirtualFile(StringRef FilePath, StringRef Content) = 0;
136326941Sdim};
137326941Sdim
138326941Sdim/// \brief Interface for factories that create specific executors. This is also
139326941Sdim/// used as a plugin to be registered into ToolExecutorPluginRegistry.
140326941Sdimclass ToolExecutorPlugin {
141326941Sdimpublic:
142326941Sdim  virtual ~ToolExecutorPlugin() {}
143326941Sdim
144326941Sdim  /// \brief Create an `ToolExecutor`.
145326941Sdim  ///
146326941Sdim  /// `OptionsParser` can be consumed (e.g. moved) if the creation succeeds.
147326941Sdim  virtual llvm::Expected<std::unique_ptr<ToolExecutor>>
148326941Sdim  create(CommonOptionsParser &OptionsParser) = 0;
149326941Sdim};
150326941Sdim
151326941Sdim/// \brief This creates a ToolExecutor that is in the global registry based on
152326941Sdim/// commandline arguments.
153326941Sdim///
154326941Sdim/// This picks the right executor based on the `--executor` option. This parses
155326941Sdim/// the commandline arguments with `CommonOptionsParser`, so caller does not
156326941Sdim/// need to parse again.
157326941Sdim///
158326941Sdim/// By default, this creates a `StandaloneToolExecutor` ("standalone") if
159326941Sdim/// `--executor` is not provided.
160326941Sdimllvm::Expected<std::unique_ptr<ToolExecutor>>
161326941SdimcreateExecutorFromCommandLineArgs(int &argc, const char **argv,
162326941Sdim                                  llvm::cl::OptionCategory &Category,
163326941Sdim                                  const char *Overview = nullptr);
164326941Sdim
165326941Sdimnamespace internal {
166326941Sdimllvm::Expected<std::unique_ptr<ToolExecutor>>
167326941SdimcreateExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
168326941Sdim                                      llvm::cl::OptionCategory &Category,
169326941Sdim                                      const char *Overview = nullptr);
170326941Sdim} // end namespace internal
171326941Sdim
172326941Sdim} // end namespace tooling
173326941Sdim} // end namespace clang
174326941Sdim
175326941Sdim#endif // LLVM_CLANG_TOOLING_EXECUTION_H
176