/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Frontend/FrontendAction.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- FrontendAction.h - Generic Frontend Action Interface ----*- 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 | | /// \file |
10 | | /// Defines the clang::FrontendAction interface and various convenience |
11 | | /// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction, |
12 | | /// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction) |
13 | | /// derived from it. |
14 | | /// |
15 | | //===----------------------------------------------------------------------===// |
16 | | |
17 | | #ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H |
18 | | #define LLVM_CLANG_FRONTEND_FRONTENDACTION_H |
19 | | |
20 | | #include "clang/AST/ASTConsumer.h" |
21 | | #include "clang/Basic/LLVM.h" |
22 | | #include "clang/Basic/LangOptions.h" |
23 | | #include "clang/Frontend/ASTUnit.h" |
24 | | #include "clang/Frontend/FrontendOptions.h" |
25 | | #include "llvm/ADT/StringRef.h" |
26 | | #include "llvm/Support/Error.h" |
27 | | #include <memory> |
28 | | #include <string> |
29 | | #include <vector> |
30 | | |
31 | | namespace clang { |
32 | | class ASTMergeAction; |
33 | | class CompilerInstance; |
34 | | |
35 | | /// Abstract base class for actions which can be performed by the frontend. |
36 | | class FrontendAction { |
37 | | FrontendInputFile CurrentInput; |
38 | | std::unique_ptr<ASTUnit> CurrentASTUnit; |
39 | | CompilerInstance *Instance; |
40 | | friend class ASTMergeAction; |
41 | | friend class WrapperFrontendAction; |
42 | | |
43 | | private: |
44 | | std::unique_ptr<ASTConsumer> CreateWrappedASTConsumer(CompilerInstance &CI, |
45 | | StringRef InFile); |
46 | | |
47 | | protected: |
48 | | /// @name Implementation Action Interface |
49 | | /// @{ |
50 | | |
51 | | /// Prepare to execute the action on the given CompilerInstance. |
52 | | /// |
53 | | /// This is called before executing the action on any inputs, and can modify |
54 | | /// the configuration as needed (including adjusting the input list). |
55 | 69.9k | virtual bool PrepareToExecuteAction(CompilerInstance &CI) { return true; } |
56 | | |
57 | | /// Create the AST consumer object for this action, if supported. |
58 | | /// |
59 | | /// This routine is called as part of BeginSourceFile(), which will |
60 | | /// fail if the AST consumer cannot be created. This will not be called if the |
61 | | /// action has indicated that it only uses the preprocessor. |
62 | | /// |
63 | | /// \param CI - The current compiler instance, provided as a convenience, see |
64 | | /// getCompilerInstance(). |
65 | | /// |
66 | | /// \param InFile - The current input file, provided as a convenience, see |
67 | | /// getCurrentFile(). |
68 | | /// |
69 | | /// \return The new AST consumer, or null on failure. |
70 | | virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, |
71 | | StringRef InFile) = 0; |
72 | | |
73 | | /// Callback before starting processing a single input, giving the |
74 | | /// opportunity to modify the CompilerInvocation or do some other action |
75 | | /// before BeginSourceFileAction is called. |
76 | | /// |
77 | | /// \return True on success; on failure BeginSourceFileAction(), |
78 | | /// ExecuteAction() and EndSourceFileAction() will not be called. |
79 | 81.8k | virtual bool BeginInvocation(CompilerInstance &CI) { return true; } |
80 | | |
81 | | /// Callback at the start of processing a single input. |
82 | | /// |
83 | | /// \return True on success; on failure ExecutionAction() and |
84 | | /// EndSourceFileAction() will not be called. |
85 | 78.4k | virtual bool BeginSourceFileAction(CompilerInstance &CI) { |
86 | 78.4k | return true; |
87 | 78.4k | } |
88 | | |
89 | | /// Callback to run the program action, using the initialized |
90 | | /// compiler instance. |
91 | | /// |
92 | | /// This is guaranteed to only be called between BeginSourceFileAction() |
93 | | /// and EndSourceFileAction(). |
94 | | virtual void ExecuteAction() = 0; |
95 | | |
96 | | /// Callback at the end of processing a single input. |
97 | | /// |
98 | | /// This is guaranteed to only be called following a successful call to |
99 | | /// BeginSourceFileAction (and BeginSourceFile). |
100 | 59.1k | virtual void EndSourceFileAction() {} |
101 | | |
102 | | /// Callback at the end of processing a single input, to determine |
103 | | /// if the output files should be erased or not. |
104 | | /// |
105 | | /// By default it returns true if a compiler error occurred. |
106 | | /// This is guaranteed to only be called following a successful call to |
107 | | /// BeginSourceFileAction (and BeginSourceFile). |
108 | | virtual bool shouldEraseOutputFiles(); |
109 | | |
110 | | /// @} |
111 | | |
112 | | public: |
113 | | FrontendAction(); |
114 | | virtual ~FrontendAction(); |
115 | | |
116 | | /// @name Compiler Instance Access |
117 | | /// @{ |
118 | | |
119 | 352k | CompilerInstance &getCompilerInstance() const { |
120 | 352k | assert(Instance && "Compiler instance not registered!"); |
121 | 352k | return *Instance; |
122 | 352k | } |
123 | | |
124 | 163k | void setCompilerInstance(CompilerInstance *Value) { Instance = Value; } |
125 | | |
126 | | /// @} |
127 | | /// @name Current File Information |
128 | | /// @{ |
129 | | |
130 | 80.9k | bool isCurrentFileAST() const { |
131 | 80.9k | assert(!CurrentInput.isEmpty() && "No current file!"); |
132 | 80.9k | return (bool)CurrentASTUnit; |
133 | 80.9k | } |
134 | | |
135 | 3.07k | const FrontendInputFile &getCurrentInput() const { |
136 | 3.07k | return CurrentInput; |
137 | 3.07k | } |
138 | | |
139 | 117 | StringRef getCurrentFile() const { |
140 | 117 | assert(!CurrentInput.isEmpty() && "No current file!"); |
141 | 117 | return CurrentInput.getFile(); |
142 | 117 | } |
143 | | |
144 | 81.7k | StringRef getCurrentFileOrBufferName() const { |
145 | 81.7k | assert(!CurrentInput.isEmpty() && "No current file!"); |
146 | 81.7k | return CurrentInput.isFile() |
147 | 81.7k | ? CurrentInput.getFile()81.6k |
148 | 81.7k | : CurrentInput.getBuffer().getBufferIdentifier()53 ; |
149 | 81.7k | } |
150 | | |
151 | 21.5k | InputKind getCurrentFileKind() const { |
152 | 21.5k | assert(!CurrentInput.isEmpty() && "No current file!"); |
153 | 21.5k | return CurrentInput.getKind(); |
154 | 21.5k | } |
155 | | |
156 | 51 | ASTUnit &getCurrentASTUnit() const { |
157 | 51 | assert(CurrentASTUnit && "No current AST unit!"); |
158 | 51 | return *CurrentASTUnit; |
159 | 51 | } |
160 | | |
161 | | Module *getCurrentModule() const; |
162 | | |
163 | 35 | std::unique_ptr<ASTUnit> takeCurrentASTUnit() { |
164 | 35 | return std::move(CurrentASTUnit); |
165 | 35 | } |
166 | | |
167 | | void setCurrentInput(const FrontendInputFile &CurrentInput, |
168 | | std::unique_ptr<ASTUnit> AST = nullptr); |
169 | | |
170 | | /// @} |
171 | | /// @name Supported Modes |
172 | | /// @{ |
173 | | |
174 | | /// Is this action invoked on a model file? |
175 | | /// |
176 | | /// Model files are incomplete translation units that relies on type |
177 | | /// information from another translation unit. Check ParseModelFileAction for |
178 | | /// details. |
179 | 263k | virtual bool isModelParsingAction() const { return false; } |
180 | | |
181 | | /// Does this action only use the preprocessor? |
182 | | /// |
183 | | /// If so no AST context will be created and this action will be invalid |
184 | | /// with AST file inputs. |
185 | | virtual bool usesPreprocessorOnly() const = 0; |
186 | | |
187 | | /// For AST-based actions, the kind of translation unit we're handling. |
188 | 125k | virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; } |
189 | | |
190 | | /// Does this action support use with PCH? |
191 | 14.6k | virtual bool hasPCHSupport() const { return true; } |
192 | | |
193 | | /// Does this action support use with AST files? |
194 | 70 | virtual bool hasASTFileSupport() const { return true; } |
195 | | |
196 | | /// Does this action support use with IR files? |
197 | 16 | virtual bool hasIRSupport() const { return false; } |
198 | | |
199 | | /// Does this action support use with code completion? |
200 | 52.4k | virtual bool hasCodeCompletionSupport() const { return false; } |
201 | | |
202 | | /// @} |
203 | | /// @name Public Action Interface |
204 | | /// @{ |
205 | | |
206 | | /// Prepare the action to execute on the given compiler instance. |
207 | 69.9k | bool PrepareToExecute(CompilerInstance &CI) { |
208 | 69.9k | return PrepareToExecuteAction(CI); |
209 | 69.9k | } |
210 | | |
211 | | /// Prepare the action for processing the input file \p Input. |
212 | | /// |
213 | | /// This is run after the options and frontend have been initialized, |
214 | | /// but prior to executing any per-file processing. |
215 | | /// |
216 | | /// \param CI - The compiler instance this action is being run from. The |
217 | | /// action may store and use this object up until the matching EndSourceFile |
218 | | /// action. |
219 | | /// |
220 | | /// \param Input - The input filename and kind. Some input kinds are handled |
221 | | /// specially, for example AST inputs, since the AST file itself contains |
222 | | /// several objects which would normally be owned by the |
223 | | /// CompilerInstance. When processing AST input files, these objects should |
224 | | /// generally not be initialized in the CompilerInstance -- they will |
225 | | /// automatically be shared with the AST file in between |
226 | | /// BeginSourceFile() and EndSourceFile(). |
227 | | /// |
228 | | /// \return True on success; on failure the compilation of this file should |
229 | | /// be aborted and neither Execute() nor EndSourceFile() should be called. |
230 | | bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input); |
231 | | |
232 | | /// Set the source manager's main input file, and run the action. |
233 | | llvm::Error Execute(); |
234 | | |
235 | | /// Perform any per-file post processing, deallocate per-file |
236 | | /// objects, and run statistics and output file cleanup code. |
237 | | virtual void EndSourceFile(); |
238 | | |
239 | | /// @} |
240 | | }; |
241 | | |
242 | | /// Abstract base class to use for AST consumer-based frontend actions. |
243 | | class ASTFrontendAction : public FrontendAction { |
244 | | protected: |
245 | | /// Implement the ExecuteAction interface by running Sema on |
246 | | /// the already-initialized AST consumer. |
247 | | /// |
248 | | /// This will also take care of instantiating a code completion consumer if |
249 | | /// the user requested it and the action supports it. |
250 | | void ExecuteAction() override; |
251 | | |
252 | | public: |
253 | 78.8k | ASTFrontendAction() {} |
254 | 78.7k | bool usesPreprocessorOnly() const override { return false; } |
255 | | }; |
256 | | |
257 | | class PluginASTAction : public ASTFrontendAction { |
258 | | virtual void anchor(); |
259 | | public: |
260 | | std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, |
261 | | StringRef InFile) override = 0; |
262 | | |
263 | | /// Parse the given plugin command line arguments. |
264 | | /// |
265 | | /// \param CI - The compiler instance, for use in reporting diagnostics. |
266 | | /// \return True if the parsing succeeded; otherwise the plugin will be |
267 | | /// destroyed and no action run. The plugin is responsible for using the |
268 | | /// CompilerInstance's Diagnostic object to report errors. |
269 | | virtual bool ParseArgs(const CompilerInstance &CI, |
270 | | const std::vector<std::string> &arg) = 0; |
271 | | |
272 | | enum ActionType { |
273 | | CmdlineBeforeMainAction, ///< Execute the action before the main action if |
274 | | ///< on the command line |
275 | | CmdlineAfterMainAction, ///< Execute the action after the main action if on |
276 | | ///< the command line |
277 | | ReplaceAction, ///< Replace the main action |
278 | | AddBeforeMainAction, ///< Execute the action before the main action |
279 | | AddAfterMainAction ///< Execute the action after the main action |
280 | | }; |
281 | | /// Get the action type for this plugin |
282 | | /// |
283 | | /// \return The action type. By default we use CmdlineAfterMainAction. |
284 | 0 | virtual ActionType getActionType() { return CmdlineAfterMainAction; } |
285 | | }; |
286 | | |
287 | | /// Abstract base class to use for preprocessor-based frontend actions. |
288 | | class PreprocessorFrontendAction : public FrontendAction { |
289 | | protected: |
290 | | /// Provide a default implementation which returns aborts; |
291 | | /// this method should never be called by FrontendAction clients. |
292 | | std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, |
293 | | StringRef InFile) override; |
294 | | |
295 | | public: |
296 | 3.10k | bool usesPreprocessorOnly() const override { return true; } |
297 | | }; |
298 | | |
299 | | /// A frontend action which simply wraps some other runtime-specified |
300 | | /// frontend action. |
301 | | /// |
302 | | /// Deriving from this class allows an action to inject custom logic around |
303 | | /// some existing action's behavior. It implements every virtual method in |
304 | | /// the FrontendAction interface by forwarding to the wrapped action. |
305 | | class WrapperFrontendAction : public FrontendAction { |
306 | | protected: |
307 | | std::unique_ptr<FrontendAction> WrappedAction; |
308 | | |
309 | | bool PrepareToExecuteAction(CompilerInstance &CI) override; |
310 | | std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, |
311 | | StringRef InFile) override; |
312 | | bool BeginInvocation(CompilerInstance &CI) override; |
313 | | bool BeginSourceFileAction(CompilerInstance &CI) override; |
314 | | void ExecuteAction() override; |
315 | | void EndSourceFile() override; |
316 | | void EndSourceFileAction() override; |
317 | | bool shouldEraseOutputFiles() override; |
318 | | |
319 | | public: |
320 | | /// Construct a WrapperFrontendAction from an existing action, taking |
321 | | /// ownership of it. |
322 | | WrapperFrontendAction(std::unique_ptr<FrontendAction> WrappedAction); |
323 | | |
324 | | bool usesPreprocessorOnly() const override; |
325 | | TranslationUnitKind getTranslationUnitKind() override; |
326 | | bool hasPCHSupport() const override; |
327 | | bool hasASTFileSupport() const override; |
328 | | bool hasIRSupport() const override; |
329 | | bool hasCodeCompletionSupport() const override; |
330 | | }; |
331 | | |
332 | | } // end namespace clang |
333 | | |
334 | | #endif |