1326941Sdim//===--- Execution.h - Executing clang frontend actions -*- C++ ---------*-===//
2326941Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6326941Sdim//
7326941Sdim//===----------------------------------------------------------------------===//
8326941Sdim//
9326941Sdim//  This file defines framework for executing clang frontend actions.
10326941Sdim//
11326941Sdim//  The framework can be extended to support different execution plans including
12326941Sdim//  standalone execution on the given TUs or parallel execution on all TUs in
13326941Sdim//  the codebase.
14326941Sdim//
15326941Sdim//  In order to enable multiprocessing execution, tool actions are expected to
16326941Sdim//  output result into the ToolResults provided by the executor. The
17326941Sdim//  `ToolResults` is an interface that abstracts how results are stored e.g.
18326941Sdim//  in-memory for standalone execution or on-disk for large-scale execution.
19326941Sdim//
20326941Sdim//  New executors can be registered as ToolExecutorPlugins via the
21326941Sdim//  `ToolExecutorPluginRegistry`. CLI tools can use
22326941Sdim//  `createExecutorFromCommandLineArgs` to create a specific registered executor
23326941Sdim//  according to the command-line arguments.
24326941Sdim//
25326941Sdim//===----------------------------------------------------------------------===//
26326941Sdim
27326941Sdim#ifndef LLVM_CLANG_TOOLING_EXECUTION_H
28326941Sdim#define LLVM_CLANG_TOOLING_EXECUTION_H
29326941Sdim
30326941Sdim#include "clang/Tooling/CommonOptionsParser.h"
31326941Sdim#include "clang/Tooling/Tooling.h"
32326941Sdim#include "llvm/Support/Error.h"
33326941Sdim#include "llvm/Support/Registry.h"
34341825Sdim#include "llvm/Support/StringSaver.h"
35326941Sdim
36326941Sdimnamespace clang {
37326941Sdimnamespace tooling {
38326941Sdim
39344779Sdimextern llvm::cl::opt<std::string> ExecutorName;
40344779Sdim
41341825Sdim/// An abstraction for the result of a tool execution. For example, the
42326941Sdim/// underlying result can be in-memory or on-disk.
43326941Sdim///
44326941Sdim/// Results should be string key-value pairs. For example, a refactoring tool
45326941Sdim/// can use source location as key and a replacement in YAML format as value.
46326941Sdimclass ToolResults {
47326941Sdimpublic:
48326941Sdim  virtual ~ToolResults() = default;
49326941Sdim  virtual void addResult(StringRef Key, StringRef Value) = 0;
50341825Sdim  virtual std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
51341825Sdim  AllKVResults() = 0;
52326941Sdim  virtual void forEachResult(
53326941Sdim      llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) = 0;
54326941Sdim};
55326941Sdim
56341825Sdim/// Stores the key-value results in memory. It maintains the lifetime of
57341825Sdim/// the result. Clang tools using this class are expected to generate a small
58341825Sdim/// set of different results, or a large set of duplicated results.
59326941Sdimclass InMemoryToolResults : public ToolResults {
60326941Sdimpublic:
61341825Sdim  InMemoryToolResults() : Strings(Arena) {}
62326941Sdim  void addResult(StringRef Key, StringRef Value) override;
63341825Sdim  std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
64341825Sdim  AllKVResults() override;
65326941Sdim  void forEachResult(llvm::function_ref<void(StringRef Key, StringRef Value)>
66326941Sdim                         Callback) override;
67326941Sdim
68326941Sdimprivate:
69341825Sdim  llvm::BumpPtrAllocator Arena;
70341825Sdim  llvm::UniqueStringSaver Strings;
71341825Sdim
72341825Sdim  std::vector<std::pair<llvm::StringRef, llvm::StringRef>> KVResults;
73326941Sdim};
74326941Sdim
75341825Sdim/// The context of an execution, including the information about
76326941Sdim/// compilation and results.
77326941Sdimclass ExecutionContext {
78326941Sdimpublic:
79326941Sdim  virtual ~ExecutionContext() {}
80326941Sdim
81341825Sdim  /// Initializes a context. This does not take ownership of `Results`.
82326941Sdim  explicit ExecutionContext(ToolResults *Results) : Results(Results) {}
83326941Sdim
84341825Sdim  /// Adds a KV pair to the result container of this execution.
85326941Sdim  void reportResult(StringRef Key, StringRef Value);
86326941Sdim
87326941Sdim  // Returns the source control system's revision number if applicable.
88326941Sdim  // Otherwise returns an empty string.
89326941Sdim  virtual std::string getRevision() { return ""; }
90326941Sdim
91326941Sdim  // Returns the corpus being analyzed, e.g. "llvm" for the LLVM codebase, if
92326941Sdim  // applicable.
93326941Sdim  virtual std::string getCorpus() { return ""; }
94326941Sdim
95326941Sdim  // Returns the currently processed compilation unit if available.
96326941Sdim  virtual std::string getCurrentCompilationUnit() { return ""; }
97326941Sdim
98326941Sdimprivate:
99326941Sdim  ToolResults *Results;
100326941Sdim};
101326941Sdim
102341825Sdim/// Interface for executing clang frontend actions.
103326941Sdim///
104326941Sdim/// This can be extended to support running tool actions in different
105326941Sdim/// execution mode, e.g. on a specific set of TUs or many TUs in parallel.
106326941Sdim///
107326941Sdim///  New executors can be registered as ToolExecutorPlugins via the
108326941Sdim///  `ToolExecutorPluginRegistry`. CLI tools can use
109326941Sdim///  `createExecutorFromCommandLineArgs` to create a specific registered
110326941Sdim///  executor according to the command-line arguments.
111326941Sdimclass ToolExecutor {
112326941Sdimpublic:
113326941Sdim  virtual ~ToolExecutor() {}
114326941Sdim
115341825Sdim  /// Returns the name of a specific executor.
116326941Sdim  virtual StringRef getExecutorName() const = 0;
117326941Sdim
118341825Sdim  /// Executes each action with a corresponding arguments adjuster.
119326941Sdim  virtual llvm::Error
120326941Sdim  execute(llvm::ArrayRef<
121326941Sdim          std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
122326941Sdim              Actions) = 0;
123326941Sdim
124341825Sdim  /// Convenient functions for the above `execute`.
125326941Sdim  llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action);
126326941Sdim  /// Executes an action with an argument adjuster.
127326941Sdim  llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action,
128326941Sdim                      ArgumentsAdjuster Adjuster);
129326941Sdim
130341825Sdim  /// Returns a reference to the execution context.
131326941Sdim  ///
132326941Sdim  /// This should be passed to tool callbacks, and tool callbacks should report
133326941Sdim  /// results via the returned context.
134326941Sdim  virtual ExecutionContext *getExecutionContext() = 0;
135326941Sdim
136341825Sdim  /// Returns a reference to the result container.
137326941Sdim  ///
138326941Sdim  /// NOTE: This should only be used after the execution finishes. Tool
139326941Sdim  /// callbacks should report results via `ExecutionContext` instead.
140326941Sdim  virtual ToolResults *getToolResults() = 0;
141326941Sdim
142341825Sdim  /// Map a virtual file to be used while running the tool.
143326941Sdim  ///
144326941Sdim  /// \param FilePath The path at which the content will be mapped.
145326941Sdim  /// \param Content A buffer of the file's content.
146326941Sdim  virtual void mapVirtualFile(StringRef FilePath, StringRef Content) = 0;
147326941Sdim};
148326941Sdim
149341825Sdim/// Interface for factories that create specific executors. This is also
150326941Sdim/// used as a plugin to be registered into ToolExecutorPluginRegistry.
151326941Sdimclass ToolExecutorPlugin {
152326941Sdimpublic:
153326941Sdim  virtual ~ToolExecutorPlugin() {}
154326941Sdim
155341825Sdim  /// Create an `ToolExecutor`.
156326941Sdim  ///
157326941Sdim  /// `OptionsParser` can be consumed (e.g. moved) if the creation succeeds.
158326941Sdim  virtual llvm::Expected<std::unique_ptr<ToolExecutor>>
159326941Sdim  create(CommonOptionsParser &OptionsParser) = 0;
160326941Sdim};
161326941Sdim
162341825Sdim/// This creates a ToolExecutor that is in the global registry based on
163326941Sdim/// commandline arguments.
164326941Sdim///
165326941Sdim/// This picks the right executor based on the `--executor` option. This parses
166326941Sdim/// the commandline arguments with `CommonOptionsParser`, so caller does not
167326941Sdim/// need to parse again.
168326941Sdim///
169326941Sdim/// By default, this creates a `StandaloneToolExecutor` ("standalone") if
170326941Sdim/// `--executor` is not provided.
171326941Sdimllvm::Expected<std::unique_ptr<ToolExecutor>>
172326941SdimcreateExecutorFromCommandLineArgs(int &argc, const char **argv,
173326941Sdim                                  llvm::cl::OptionCategory &Category,
174326941Sdim                                  const char *Overview = nullptr);
175326941Sdim
176326941Sdimnamespace internal {
177326941Sdimllvm::Expected<std::unique_ptr<ToolExecutor>>
178326941SdimcreateExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
179326941Sdim                                      llvm::cl::OptionCategory &Category,
180326941Sdim                                      const char *Overview = nullptr);
181326941Sdim} // end namespace internal
182326941Sdim
183326941Sdim} // end namespace tooling
184326941Sdim} // end namespace clang
185326941Sdim
186326941Sdim#endif // LLVM_CLANG_TOOLING_EXECUTION_H
187