Execution.h revision 344779
1262617Sdelphij//===--- Execution.h - Executing clang frontend actions -*- C++ ---------*-===//
2262685Sdelphij//
3262617Sdelphij//                     The LLVM Compiler Infrastructure
4262617Sdelphij//
5262617Sdelphij// This file is distributed under the University of Illinois Open Source
6262617Sdelphij// License. See LICENSE.TXT for details.
7262617Sdelphij//
8262617Sdelphij//===----------------------------------------------------------------------===//
9262617Sdelphij//
10262617Sdelphij//  This file defines framework for executing clang frontend actions.
11262617Sdelphij//
12262617Sdelphij//  The framework can be extended to support different execution plans including
13262617Sdelphij//  standalone execution on the given TUs or parallel execution on all TUs in
14262617Sdelphij//  the codebase.
15262617Sdelphij//
16262617Sdelphij//  In order to enable multiprocessing execution, tool actions are expected to
17262617Sdelphij//  output result into the ToolResults provided by the executor. The
18262617Sdelphij//  `ToolResults` is an interface that abstracts how results are stored e.g.
19262617Sdelphij//  in-memory for standalone execution or on-disk for large-scale execution.
20262617Sdelphij//
21262617Sdelphij//  New executors can be registered as ToolExecutorPlugins via the
22262617Sdelphij//  `ToolExecutorPluginRegistry`. CLI tools can use
23262617Sdelphij//  `createExecutorFromCommandLineArgs` to create a specific registered executor
24262617Sdelphij//  according to the command-line arguments.
25262617Sdelphij//
26262617Sdelphij//===----------------------------------------------------------------------===//
27262617Sdelphij
28262617Sdelphij#ifndef LLVM_CLANG_TOOLING_EXECUTION_H
29262617Sdelphij#define LLVM_CLANG_TOOLING_EXECUTION_H
30262617Sdelphij
31262617Sdelphij#include "clang/Tooling/CommonOptionsParser.h"
32262617Sdelphij#include "clang/Tooling/Tooling.h"
33262617Sdelphij#include "llvm/Support/Error.h"
34262685Sdelphij#include "llvm/Support/Registry.h"
35262617Sdelphij#include "llvm/Support/StringSaver.h"
36262617Sdelphij
37262685Sdelphijnamespace clang {
38262617Sdelphijnamespace tooling {
39262617Sdelphij
40262617Sdelphijextern llvm::cl::opt<std::string> ExecutorName;
41262617Sdelphij
42262617Sdelphij/// An abstraction for the result of a tool execution. For example, the
43262617Sdelphij/// underlying result can be in-memory or on-disk.
44262617Sdelphij///
45262617Sdelphij/// Results should be string key-value pairs. For example, a refactoring tool
46262617Sdelphij/// can use source location as key and a replacement in YAML format as value.
47262617Sdelphijclass ToolResults {
48262617Sdelphijpublic:
49262617Sdelphij  virtual ~ToolResults() = default;
50262617Sdelphij  virtual void addResult(StringRef Key, StringRef Value) = 0;
51262617Sdelphij  virtual std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
52262617Sdelphij  AllKVResults() = 0;
53262617Sdelphij  virtual void forEachResult(
54262617Sdelphij      llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) = 0;
55262617Sdelphij};
56262617Sdelphij
57262617Sdelphij/// Stores the key-value results in memory. It maintains the lifetime of
58262617Sdelphij/// the result. Clang tools using this class are expected to generate a small
59262617Sdelphij/// set of different results, or a large set of duplicated results.
60262617Sdelphijclass InMemoryToolResults : public ToolResults {
61262617Sdelphijpublic:
62262617Sdelphij  InMemoryToolResults() : Strings(Arena) {}
63262617Sdelphij  void addResult(StringRef Key, StringRef Value) override;
64262617Sdelphij  std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
65262617Sdelphij  AllKVResults() override;
66262617Sdelphij  void forEachResult(llvm::function_ref<void(StringRef Key, StringRef Value)>
67262617Sdelphij                         Callback) override;
68262617Sdelphij
69262617Sdelphijprivate:
70262617Sdelphij  llvm::BumpPtrAllocator Arena;
71262617Sdelphij  llvm::UniqueStringSaver Strings;
72262617Sdelphij
73262685Sdelphij  std::vector<std::pair<llvm::StringRef, llvm::StringRef>> KVResults;
74262685Sdelphij};
75
76/// The context of an execution, including the information about
77/// compilation and results.
78class ExecutionContext {
79public:
80  virtual ~ExecutionContext() {}
81
82  /// Initializes a context. This does not take ownership of `Results`.
83  explicit ExecutionContext(ToolResults *Results) : Results(Results) {}
84
85  /// Adds a KV pair to the result container of this execution.
86  void reportResult(StringRef Key, StringRef Value);
87
88  // Returns the source control system's revision number if applicable.
89  // Otherwise returns an empty string.
90  virtual std::string getRevision() { return ""; }
91
92  // Returns the corpus being analyzed, e.g. "llvm" for the LLVM codebase, if
93  // applicable.
94  virtual std::string getCorpus() { return ""; }
95
96  // Returns the currently processed compilation unit if available.
97  virtual std::string getCurrentCompilationUnit() { return ""; }
98
99private:
100  ToolResults *Results;
101};
102
103/// Interface for executing clang frontend actions.
104///
105/// This can be extended to support running tool actions in different
106/// execution mode, e.g. on a specific set of TUs or many TUs in parallel.
107///
108///  New executors can be registered as ToolExecutorPlugins via the
109///  `ToolExecutorPluginRegistry`. CLI tools can use
110///  `createExecutorFromCommandLineArgs` to create a specific registered
111///  executor according to the command-line arguments.
112class ToolExecutor {
113public:
114  virtual ~ToolExecutor() {}
115
116  /// Returns the name of a specific executor.
117  virtual StringRef getExecutorName() const = 0;
118
119  /// Should return true iff executor runs all actions in a single process.
120  /// Clients can use this signal to find out if they can collect results
121  /// in-memory (e.g. to avoid serialization costs of using ToolResults).
122  /// The single-process executors can still run multiple threads, but all
123  /// executions are guaranteed to share the same memory.
124  virtual bool isSingleProcess() const = 0;
125
126  /// Executes each action with a corresponding arguments adjuster.
127  virtual llvm::Error
128  execute(llvm::ArrayRef<
129          std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
130              Actions) = 0;
131
132  /// Convenient functions for the above `execute`.
133  llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action);
134  /// Executes an action with an argument adjuster.
135  llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action,
136                      ArgumentsAdjuster Adjuster);
137
138  /// Returns a reference to the execution context.
139  ///
140  /// This should be passed to tool callbacks, and tool callbacks should report
141  /// results via the returned context.
142  virtual ExecutionContext *getExecutionContext() = 0;
143
144  /// Returns a reference to the result container.
145  ///
146  /// NOTE: This should only be used after the execution finishes. Tool
147  /// callbacks should report results via `ExecutionContext` instead.
148  virtual ToolResults *getToolResults() = 0;
149
150  /// Map a virtual file to be used while running the tool.
151  ///
152  /// \param FilePath The path at which the content will be mapped.
153  /// \param Content A buffer of the file's content.
154  virtual void mapVirtualFile(StringRef FilePath, StringRef Content) = 0;
155};
156
157/// Interface for factories that create specific executors. This is also
158/// used as a plugin to be registered into ToolExecutorPluginRegistry.
159class ToolExecutorPlugin {
160public:
161  virtual ~ToolExecutorPlugin() {}
162
163  /// Create an `ToolExecutor`.
164  ///
165  /// `OptionsParser` can be consumed (e.g. moved) if the creation succeeds.
166  virtual llvm::Expected<std::unique_ptr<ToolExecutor>>
167  create(CommonOptionsParser &OptionsParser) = 0;
168};
169
170/// This creates a ToolExecutor that is in the global registry based on
171/// commandline arguments.
172///
173/// This picks the right executor based on the `--executor` option. This parses
174/// the commandline arguments with `CommonOptionsParser`, so caller does not
175/// need to parse again.
176///
177/// By default, this creates a `StandaloneToolExecutor` ("standalone") if
178/// `--executor` is not provided.
179llvm::Expected<std::unique_ptr<ToolExecutor>>
180createExecutorFromCommandLineArgs(int &argc, const char **argv,
181                                  llvm::cl::OptionCategory &Category,
182                                  const char *Overview = nullptr);
183
184namespace internal {
185llvm::Expected<std::unique_ptr<ToolExecutor>>
186createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
187                                      llvm::cl::OptionCategory &Category,
188                                      const char *Overview = nullptr);
189} // end namespace internal
190
191} // end namespace tooling
192} // end namespace clang
193
194#endif // LLVM_CLANG_TOOLING_EXECUTION_H
195