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