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