1 //===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief Defines the clang::FrontendAction interface and various convenience
12 /// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction,
13 /// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction)
16 //===----------------------------------------------------------------------===//
18 #ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
19 #define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
21 #include "clang/Basic/LLVM.h"
22 #include "clang/Basic/LangOptions.h"
23 #include "clang/Frontend/FrontendOptions.h"
24 #include "llvm/ADT/StringRef.h"
33 class CompilerInstance;
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;
44 ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
48 /// @name Implementation Action Interface
51 /// \brief Create the AST consumer object for this action, if supported.
53 /// This routine is called as part of BeginSourceFile(), which will
54 /// fail if the AST consumer cannot be created. This will not be called if the
55 /// action has indicated that it only uses the preprocessor.
57 /// \param CI - The current compiler instance, provided as a convenience, see
58 /// getCompilerInstance().
60 /// \param InFile - The current input file, provided as a convenience, see
63 /// \return The new AST consumer, or null on failure.
64 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
65 StringRef InFile) = 0;
67 /// \brief Callback before starting processing a single input, giving the
68 /// opportunity to modify the CompilerInvocation or do some other action
69 /// before BeginSourceFileAction is called.
71 /// \return True on success; on failure BeginSourceFileAction(),
72 /// ExecuteAction() and EndSourceFileAction() will not be called.
73 virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
75 /// \brief Callback at the start of processing a single input.
77 /// \return True on success; on failure ExecutionAction() and
78 /// EndSourceFileAction() will not be called.
79 virtual bool BeginSourceFileAction(CompilerInstance &CI,
84 /// \brief Callback to run the program action, using the initialized
85 /// compiler instance.
87 /// This is guaranteed to only be called between BeginSourceFileAction()
88 /// and EndSourceFileAction().
89 virtual void ExecuteAction() = 0;
91 /// \brief Callback at the end of processing a single input.
93 /// This is guaranteed to only be called following a successful call to
94 /// BeginSourceFileAction (and BeginSourceFile).
95 virtual void EndSourceFileAction() {}
97 /// \brief Callback at the end of processing a single input, to determine
98 /// if the output files should be erased or not.
100 /// By default it returns true if a compiler error occurred.
101 /// This is guaranteed to only be called following a successful call to
102 /// BeginSourceFileAction (and BeginSourceFile).
103 virtual bool shouldEraseOutputFiles();
109 virtual ~FrontendAction();
111 /// @name Compiler Instance Access
114 CompilerInstance &getCompilerInstance() const {
115 assert(Instance && "Compiler instance not registered!");
119 void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
122 /// @name Current File Information
125 bool isCurrentFileAST() const {
126 assert(!CurrentInput.isEmpty() && "No current file!");
127 return (bool)CurrentASTUnit;
130 const FrontendInputFile &getCurrentInput() const {
134 const StringRef getCurrentFile() const {
135 assert(!CurrentInput.isEmpty() && "No current file!");
136 return CurrentInput.getFile();
139 InputKind getCurrentFileKind() const {
140 assert(!CurrentInput.isEmpty() && "No current file!");
141 return CurrentInput.getKind();
144 ASTUnit &getCurrentASTUnit() const {
145 assert(CurrentASTUnit && "No current AST unit!");
146 return *CurrentASTUnit;
149 ASTUnit *takeCurrentASTUnit() { return CurrentASTUnit.release(); }
151 void setCurrentInput(const FrontendInputFile &CurrentInput,
152 ASTUnit *AST = nullptr);
155 /// @name Supported Modes
158 /// \brief Does this action only use the preprocessor?
160 /// If so no AST context will be created and this action will be invalid
161 /// with AST file inputs.
162 virtual bool usesPreprocessorOnly() const = 0;
164 /// \brief For AST-based actions, the kind of translation unit we're handling.
165 virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
167 /// \brief Does this action support use with PCH?
168 virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
170 /// \brief Does this action support use with AST files?
171 virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
173 /// \brief Does this action support use with IR files?
174 virtual bool hasIRSupport() const { return false; }
176 /// \brief Does this action support use with code completion?
177 virtual bool hasCodeCompletionSupport() const { return false; }
180 /// @name Public Action Interface
183 /// \brief Prepare the action for processing the input file \p Input.
185 /// This is run after the options and frontend have been initialized,
186 /// but prior to executing any per-file processing.
188 /// \param CI - The compiler instance this action is being run from. The
189 /// action may store and use this object up until the matching EndSourceFile
192 /// \param Input - The input filename and kind. Some input kinds are handled
193 /// specially, for example AST inputs, since the AST file itself contains
194 /// several objects which would normally be owned by the
195 /// CompilerInstance. When processing AST input files, these objects should
196 /// generally not be initialized in the CompilerInstance -- they will
197 /// automatically be shared with the AST file in between
198 /// BeginSourceFile() and EndSourceFile().
200 /// \return True on success; on failure the compilation of this file should
201 /// be aborted and neither Execute() nor EndSourceFile() should be called.
202 bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
204 /// \brief Set the source manager's main input file, and run the action.
207 /// \brief Perform any per-file post processing, deallocate per-file
208 /// objects, and run statistics and output file cleanup code.
209 void EndSourceFile();
214 /// \brief Abstract base class to use for AST consumer-based frontend actions.
215 class ASTFrontendAction : public FrontendAction {
217 /// \brief Implement the ExecuteAction interface by running Sema on
218 /// the already-initialized AST consumer.
220 /// This will also take care of instantiating a code completion consumer if
221 /// the user requested it and the action supports it.
222 void ExecuteAction() override;
225 bool usesPreprocessorOnly() const override { return false; }
228 class PluginASTAction : public ASTFrontendAction {
229 virtual void anchor();
231 ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
232 StringRef InFile) override = 0;
235 /// \brief Parse the given plugin command line arguments.
237 /// \param CI - The compiler instance, for use in reporting diagnostics.
238 /// \return True if the parsing succeeded; otherwise the plugin will be
239 /// destroyed and no action run. The plugin is responsible for using the
240 /// CompilerInstance's Diagnostic object to report errors.
241 virtual bool ParseArgs(const CompilerInstance &CI,
242 const std::vector<std::string> &arg) = 0;
245 /// \brief Abstract base class to use for preprocessor-based frontend actions.
246 class PreprocessorFrontendAction : public FrontendAction {
248 /// \brief Provide a default implementation which returns aborts;
249 /// this method should never be called by FrontendAction clients.
250 ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
251 StringRef InFile) override;
254 bool usesPreprocessorOnly() const override { return true; }
257 /// \brief A frontend action which simply wraps some other runtime-specified
260 /// Deriving from this class allows an action to inject custom logic around
261 /// some existing action's behavior. It implements every virtual method in
262 /// the FrontendAction interface by forwarding to the wrapped action.
263 class WrapperFrontendAction : public FrontendAction {
264 std::unique_ptr<FrontendAction> WrappedAction;
267 ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
268 StringRef InFile) override;
269 bool BeginInvocation(CompilerInstance &CI) override;
270 bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
271 void ExecuteAction() override;
272 void EndSourceFileAction() override;
275 /// Construct a WrapperFrontendAction from an existing action, taking
277 WrapperFrontendAction(FrontendAction *WrappedAction);
279 bool usesPreprocessorOnly() const override;
280 TranslationUnitKind getTranslationUnitKind() override;
281 bool hasPCHSupport() const override;
282 bool hasASTFileSupport() const override;
283 bool hasIRSupport() const override;
284 bool hasCodeCompletionSupport() const override;
287 } // end namespace clang