Line data Source code
1 : //===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : ///
10 : /// \file
11 : /// \brief Defines the clang::FrontendAction interface and various convenience
12 : /// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction,
13 : /// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction)
14 : /// derived from it.
15 : ///
16 : //===----------------------------------------------------------------------===//
17 :
18 : #ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
19 : #define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
20 :
21 : #include "clang/AST/ASTConsumer.h"
22 : #include "clang/Basic/LLVM.h"
23 : #include "clang/Basic/LangOptions.h"
24 : #include "clang/Frontend/ASTUnit.h"
25 : #include "clang/Frontend/FrontendOptions.h"
26 : #include "llvm/ADT/StringRef.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 : /// \brief Create the AST consumer object for this action, if supported.
52 : ///
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.
56 : ///
57 : /// \param CI - The current compiler instance, provided as a convenience, see
58 : /// getCompilerInstance().
59 : ///
60 : /// \param InFile - The current input file, provided as a convenience, see
61 : /// getCurrentFile().
62 : ///
63 : /// \return The new AST consumer, or null on failure.
64 : virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
65 : StringRef InFile) = 0;
66 :
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.
70 : ///
71 : /// \return True on success; on failure BeginSourceFileAction(),
72 : /// ExecuteAction() and EndSourceFileAction() will not be called.
73 12 : virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
74 :
75 : /// \brief Callback at the start of processing a single input.
76 : ///
77 : /// \return True on success; on failure ExecutionAction() and
78 : /// EndSourceFileAction() will not be called.
79 : virtual bool BeginSourceFileAction(CompilerInstance &CI,
80 : StringRef Filename) {
81 12 : return true;
82 : }
83 :
84 : /// \brief Callback to run the program action, using the initialized
85 : /// compiler instance.
86 : ///
87 : /// This is guaranteed to only be called between BeginSourceFileAction()
88 : /// and EndSourceFileAction().
89 : virtual void ExecuteAction() = 0;
90 :
91 : /// \brief Callback at the end of processing a single input.
92 : ///
93 : /// This is guaranteed to only be called following a successful call to
94 : /// BeginSourceFileAction (and BeginSourceFile).
95 12 : virtual void EndSourceFileAction() {}
96 :
97 : /// \brief Callback at the end of processing a single input, to determine
98 : /// if the output files should be erased or not.
99 : ///
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();
104 :
105 : /// @}
106 :
107 : public:
108 : FrontendAction();
109 : virtual ~FrontendAction();
110 :
111 : /// @name Compiler Instance Access
112 : /// @{
113 :
114 : CompilerInstance &getCompilerInstance() const {
115 : assert(Instance && "Compiler instance not registered!");
116 : return *Instance;
117 : }
118 :
119 : void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
120 :
121 : /// @}
122 : /// @name Current File Information
123 : /// @{
124 :
125 : bool isCurrentFileAST() const {
126 : assert(!CurrentInput.isEmpty() && "No current file!");
127 : return (bool)CurrentASTUnit;
128 : }
129 :
130 : const FrontendInputFile &getCurrentInput() const {
131 : return CurrentInput;
132 : }
133 :
134 : const StringRef getCurrentFile() const {
135 : assert(!CurrentInput.isEmpty() && "No current file!");
136 : return CurrentInput.getFile();
137 : }
138 :
139 : InputKind getCurrentFileKind() const {
140 : assert(!CurrentInput.isEmpty() && "No current file!");
141 : return CurrentInput.getKind();
142 : }
143 :
144 : ASTUnit &getCurrentASTUnit() const {
145 : assert(CurrentASTUnit && "No current AST unit!");
146 : return *CurrentASTUnit;
147 : }
148 :
149 : std::unique_ptr<ASTUnit> takeCurrentASTUnit() {
150 : return std::move(CurrentASTUnit);
151 : }
152 :
153 : void setCurrentInput(const FrontendInputFile &CurrentInput,
154 : std::unique_ptr<ASTUnit> AST = nullptr);
155 :
156 : /// @}
157 : /// @name Supported Modes
158 : /// @{
159 :
160 : /// \brief Is this action invoked on a model file?
161 : ///
162 : /// Model files are incomplete translation units that relies on type
163 : /// information from another translation unit. Check ParseModelFileAction for
164 : /// details.
165 48 : virtual bool isModelParsingAction() const { return false; }
166 :
167 : /// \brief Does this action only use the preprocessor?
168 : ///
169 : /// If so no AST context will be created and this action will be invalid
170 : /// with AST file inputs.
171 : virtual bool usesPreprocessorOnly() const = 0;
172 :
173 : /// \brief For AST-based actions, the kind of translation unit we're handling.
174 24 : virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
175 :
176 : /// \brief Does this action support use with PCH?
177 0 : virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
178 :
179 : /// \brief Does this action support use with AST files?
180 0 : virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
181 :
182 : /// \brief Does this action support use with IR files?
183 0 : virtual bool hasIRSupport() const { return false; }
184 :
185 : /// \brief Does this action support use with code completion?
186 12 : virtual bool hasCodeCompletionSupport() const { return false; }
187 :
188 : /// @}
189 : /// @name Public Action Interface
190 : /// @{
191 :
192 : /// \brief Prepare the action for processing the input file \p Input.
193 : ///
194 : /// This is run after the options and frontend have been initialized,
195 : /// but prior to executing any per-file processing.
196 : ///
197 : /// \param CI - The compiler instance this action is being run from. The
198 : /// action may store and use this object up until the matching EndSourceFile
199 : /// action.
200 : ///
201 : /// \param Input - The input filename and kind. Some input kinds are handled
202 : /// specially, for example AST inputs, since the AST file itself contains
203 : /// several objects which would normally be owned by the
204 : /// CompilerInstance. When processing AST input files, these objects should
205 : /// generally not be initialized in the CompilerInstance -- they will
206 : /// automatically be shared with the AST file in between
207 : /// BeginSourceFile() and EndSourceFile().
208 : ///
209 : /// \return True on success; on failure the compilation of this file should
210 : /// be aborted and neither Execute() nor EndSourceFile() should be called.
211 : bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
212 :
213 : /// \brief Set the source manager's main input file, and run the action.
214 : bool Execute();
215 :
216 : /// \brief Perform any per-file post processing, deallocate per-file
217 : /// objects, and run statistics and output file cleanup code.
218 : void EndSourceFile();
219 :
220 : /// @}
221 : };
222 :
223 : /// \brief Abstract base class to use for AST consumer-based frontend actions.
224 12 : class ASTFrontendAction : public FrontendAction {
225 : protected:
226 : /// \brief Implement the ExecuteAction interface by running Sema on
227 : /// the already-initialized AST consumer.
228 : ///
229 : /// This will also take care of instantiating a code completion consumer if
230 : /// the user requested it and the action supports it.
231 : void ExecuteAction() override;
232 :
233 : public:
234 12 : ASTFrontendAction() {}
235 12 : bool usesPreprocessorOnly() const override { return false; }
236 : };
237 :
238 : class PluginASTAction : public ASTFrontendAction {
239 : virtual void anchor();
240 : public:
241 : std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
242 : StringRef InFile) override = 0;
243 :
244 : /// \brief Parse the given plugin command line arguments.
245 : ///
246 : /// \param CI - The compiler instance, for use in reporting diagnostics.
247 : /// \return True if the parsing succeeded; otherwise the plugin will be
248 : /// destroyed and no action run. The plugin is responsible for using the
249 : /// CompilerInstance's Diagnostic object to report errors.
250 : virtual bool ParseArgs(const CompilerInstance &CI,
251 : const std::vector<std::string> &arg) = 0;
252 : };
253 :
254 : /// \brief Abstract base class to use for preprocessor-based frontend actions.
255 : class PreprocessorFrontendAction : public FrontendAction {
256 : protected:
257 : /// \brief Provide a default implementation which returns aborts;
258 : /// this method should never be called by FrontendAction clients.
259 : std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
260 : StringRef InFile) override;
261 :
262 : public:
263 : bool usesPreprocessorOnly() const override { return true; }
264 : };
265 :
266 : /// \brief A frontend action which simply wraps some other runtime-specified
267 : /// frontend action.
268 : ///
269 : /// Deriving from this class allows an action to inject custom logic around
270 : /// some existing action's behavior. It implements every virtual method in
271 : /// the FrontendAction interface by forwarding to the wrapped action.
272 : class WrapperFrontendAction : public FrontendAction {
273 : std::unique_ptr<FrontendAction> WrappedAction;
274 :
275 : protected:
276 : std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
277 : StringRef InFile) override;
278 : bool BeginInvocation(CompilerInstance &CI) override;
279 : bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
280 : void ExecuteAction() override;
281 : void EndSourceFileAction() override;
282 :
283 : public:
284 : /// Construct a WrapperFrontendAction from an existing action, taking
285 : /// ownership of it.
286 : WrapperFrontendAction(FrontendAction *WrappedAction);
287 :
288 : bool usesPreprocessorOnly() const override;
289 : TranslationUnitKind getTranslationUnitKind() override;
290 : bool hasPCHSupport() const override;
291 : bool hasASTFileSupport() const override;
292 : bool hasIRSupport() const override;
293 : bool hasCodeCompletionSupport() const override;
294 : };
295 :
296 : } // end namespace clang
297 :
298 : #endif
|