• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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).
PrepareToExecuteAction(CompilerInstance & CI)55   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.
BeginInvocation(CompilerInstance & CI)79   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.
BeginSourceFileAction(CompilerInstance & CI)85   virtual bool BeginSourceFileAction(CompilerInstance &CI) {
86     return true;
87   }
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).
EndSourceFileAction()100   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 
getCompilerInstance()119   CompilerInstance &getCompilerInstance() const {
120     assert(Instance && "Compiler instance not registered!");
121     return *Instance;
122   }
123 
setCompilerInstance(CompilerInstance * Value)124   void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
125 
126   /// @}
127   /// @name Current File Information
128   /// @{
129 
isCurrentFileAST()130   bool isCurrentFileAST() const {
131     assert(!CurrentInput.isEmpty() && "No current file!");
132     return (bool)CurrentASTUnit;
133   }
134 
getCurrentInput()135   const FrontendInputFile &getCurrentInput() const {
136     return CurrentInput;
137   }
138 
getCurrentFile()139   StringRef getCurrentFile() const {
140     assert(!CurrentInput.isEmpty() && "No current file!");
141     return CurrentInput.getFile();
142   }
143 
getCurrentFileOrBufferName()144   StringRef getCurrentFileOrBufferName() const {
145     assert(!CurrentInput.isEmpty() && "No current file!");
146     return CurrentInput.isFile()
147                ? CurrentInput.getFile()
148                : CurrentInput.getBuffer().getBufferIdentifier();
149   }
150 
getCurrentFileKind()151   InputKind getCurrentFileKind() const {
152     assert(!CurrentInput.isEmpty() && "No current file!");
153     return CurrentInput.getKind();
154   }
155 
getCurrentASTUnit()156   ASTUnit &getCurrentASTUnit() const {
157     assert(CurrentASTUnit && "No current AST unit!");
158     return *CurrentASTUnit;
159   }
160 
161   Module *getCurrentModule() const;
162 
takeCurrentASTUnit()163   std::unique_ptr<ASTUnit> takeCurrentASTUnit() {
164     return std::move(CurrentASTUnit);
165   }
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.
isModelParsingAction()179   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.
getTranslationUnitKind()188   virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
189 
190   /// Does this action support use with PCH?
hasPCHSupport()191   virtual bool hasPCHSupport() const { return true; }
192 
193   /// Does this action support use with AST files?
hasASTFileSupport()194   virtual bool hasASTFileSupport() const { return true; }
195 
196   /// Does this action support use with IR files?
hasIRSupport()197   virtual bool hasIRSupport() const { return false; }
198 
199   /// Does this action support use with code completion?
hasCodeCompletionSupport()200   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.
PrepareToExecute(CompilerInstance & CI)207   bool PrepareToExecute(CompilerInstance &CI) {
208     return PrepareToExecuteAction(CI);
209   }
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   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:
ASTFrontendAction()253   ASTFrontendAction() {}
usesPreprocessorOnly()254   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     Cmdline,             ///< Action is determined by the cc1 command-line
274     ReplaceAction,       ///< Replace the main action
275     AddBeforeMainAction, ///< Execute the action before the main action
276     AddAfterMainAction   ///< Execute the action after the main action
277   };
278   /// Get the action type for this plugin
279   ///
280   /// \return The action type. If the type is Cmdline then by default the
281   /// plugin does nothing and what it does is determined by the cc1
282   /// command-line.
getActionType()283   virtual ActionType getActionType() { return Cmdline; }
284 };
285 
286 /// Abstract base class to use for preprocessor-based frontend actions.
287 class PreprocessorFrontendAction : public FrontendAction {
288 protected:
289   /// Provide a default implementation which returns aborts;
290   /// this method should never be called by FrontendAction clients.
291   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
292                                                  StringRef InFile) override;
293 
294 public:
usesPreprocessorOnly()295   bool usesPreprocessorOnly() const override { return true; }
296 };
297 
298 /// A frontend action which simply wraps some other runtime-specified
299 /// frontend action.
300 ///
301 /// Deriving from this class allows an action to inject custom logic around
302 /// some existing action's behavior. It implements every virtual method in
303 /// the FrontendAction interface by forwarding to the wrapped action.
304 class WrapperFrontendAction : public FrontendAction {
305   std::unique_ptr<FrontendAction> WrappedAction;
306 
307 protected:
308   bool PrepareToExecuteAction(CompilerInstance &CI) override;
309   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
310                                                  StringRef InFile) override;
311   bool BeginInvocation(CompilerInstance &CI) override;
312   bool BeginSourceFileAction(CompilerInstance &CI) override;
313   void ExecuteAction() override;
314   void EndSourceFileAction() override;
315   bool shouldEraseOutputFiles() override;
316 
317 public:
318   /// Construct a WrapperFrontendAction from an existing action, taking
319   /// ownership of it.
320   WrapperFrontendAction(std::unique_ptr<FrontendAction> WrappedAction);
321 
322   bool usesPreprocessorOnly() const override;
323   TranslationUnitKind getTranslationUnitKind() override;
324   bool hasPCHSupport() const override;
325   bool hasASTFileSupport() const override;
326   bool hasIRSupport() const override;
327   bool hasCodeCompletionSupport() const override;
328 };
329 
330 }  // end namespace clang
331 
332 #endif
333