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