• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/Basic/LLVM.h"
22 #include "clang/Basic/LangOptions.h"
23 #include "clang/Frontend/FrontendOptions.h"
24 #include "llvm/ADT/OwningPtr.h"
25 #include "llvm/ADT/StringRef.h"
26 #include <string>
27 #include <vector>
28 
29 namespace clang {
30 class ASTConsumer;
31 class ASTMergeAction;
32 class ASTUnit;
33 class CompilerInstance;
34 
35 /// Abstract base class for actions which can be performed by the frontend.
36 class FrontendAction {
37   FrontendInputFile CurrentInput;
38   OwningPtr<ASTUnit> CurrentASTUnit;
39   CompilerInstance *Instance;
40   friend class ASTMergeAction;
41   friend class WrapperFrontendAction;
42 
43 private:
44   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 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.
BeginInvocation(CompilerInstance & CI)73   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.
BeginSourceFileAction(CompilerInstance & CI,StringRef Filename)79   virtual bool BeginSourceFileAction(CompilerInstance &CI,
80                                      StringRef Filename) {
81     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).
EndSourceFileAction()95   virtual void EndSourceFileAction() {}
96 
97   /// @}
98 
99 public:
100   FrontendAction();
101   virtual ~FrontendAction();
102 
103   /// @name Compiler Instance Access
104   /// @{
105 
getCompilerInstance()106   CompilerInstance &getCompilerInstance() const {
107     assert(Instance && "Compiler instance not registered!");
108     return *Instance;
109   }
110 
setCompilerInstance(CompilerInstance * Value)111   void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
112 
113   /// @}
114   /// @name Current File Information
115   /// @{
116 
isCurrentFileAST()117   bool isCurrentFileAST() const {
118     assert(!CurrentInput.isEmpty() && "No current file!");
119     return CurrentASTUnit != 0;
120   }
121 
getCurrentInput()122   const FrontendInputFile &getCurrentInput() const {
123     return CurrentInput;
124   }
125 
getCurrentFile()126   const StringRef getCurrentFile() const {
127     assert(!CurrentInput.isEmpty() && "No current file!");
128     return CurrentInput.getFile();
129   }
130 
getCurrentFileKind()131   InputKind getCurrentFileKind() const {
132     assert(!CurrentInput.isEmpty() && "No current file!");
133     return CurrentInput.getKind();
134   }
135 
getCurrentASTUnit()136   ASTUnit &getCurrentASTUnit() const {
137     assert(CurrentASTUnit && "No current AST unit!");
138     return *CurrentASTUnit;
139   }
140 
takeCurrentASTUnit()141   ASTUnit *takeCurrentASTUnit() {
142     return CurrentASTUnit.take();
143   }
144 
145   void setCurrentInput(const FrontendInputFile &CurrentInput, ASTUnit *AST = 0);
146 
147   /// @}
148   /// @name Supported Modes
149   /// @{
150 
151   /// \brief Does this action only use the preprocessor?
152   ///
153   /// If so no AST context will be created and this action will be invalid
154   /// with AST file inputs.
155   virtual bool usesPreprocessorOnly() const = 0;
156 
157   /// \brief For AST-based actions, the kind of translation unit we're handling.
getTranslationUnitKind()158   virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
159 
160   /// \brief Does this action support use with PCH?
hasPCHSupport()161   virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
162 
163   /// \brief Does this action support use with AST files?
hasASTFileSupport()164   virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
165 
166   /// \brief Does this action support use with IR files?
hasIRSupport()167   virtual bool hasIRSupport() const { return false; }
168 
169   /// \brief Does this action support use with code completion?
hasCodeCompletionSupport()170   virtual bool hasCodeCompletionSupport() const { return false; }
171 
172   /// @}
173   /// @name Public Action Interface
174   /// @{
175 
176   /// \brief Prepare the action for processing the input file \p Input.
177   ///
178   /// This is run after the options and frontend have been initialized,
179   /// but prior to executing any per-file processing.
180   ///
181   /// \param CI - The compiler instance this action is being run from. The
182   /// action may store and use this object up until the matching EndSourceFile
183   /// action.
184   ///
185   /// \param Input - The input filename and kind. Some input kinds are handled
186   /// specially, for example AST inputs, since the AST file itself contains
187   /// several objects which would normally be owned by the
188   /// CompilerInstance. When processing AST input files, these objects should
189   /// generally not be initialized in the CompilerInstance -- they will
190   /// automatically be shared with the AST file in between
191   /// BeginSourceFile() and EndSourceFile().
192   ///
193   /// \return True on success; on failure the compilation of this file should
194   /// be aborted and neither Execute() nor EndSourceFile() should be called.
195   bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
196 
197   /// \brief Set the source manager's main input file, and run the action.
198   bool Execute();
199 
200   /// \brief Perform any per-file post processing, deallocate per-file
201   /// objects, and run statistics and output file cleanup code.
202   void EndSourceFile();
203 
204   /// @}
205 };
206 
207 /// \brief Abstract base class to use for AST consumer-based frontend actions.
208 class ASTFrontendAction : public FrontendAction {
209 protected:
210   /// \brief Implement the ExecuteAction interface by running Sema on
211   /// the already-initialized AST consumer.
212   ///
213   /// This will also take care of instantiating a code completion consumer if
214   /// the user requested it and the action supports it.
215   virtual void ExecuteAction();
216 
217 public:
usesPreprocessorOnly()218   virtual bool usesPreprocessorOnly() const { return false; }
219 };
220 
221 class PluginASTAction : public ASTFrontendAction {
222   virtual void anchor();
223 protected:
224   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
225                                          StringRef InFile) = 0;
226 
227 public:
228   /// \brief Parse the given plugin command line arguments.
229   ///
230   /// \param CI - The compiler instance, for use in reporting diagnostics.
231   /// \return True if the parsing succeeded; otherwise the plugin will be
232   /// destroyed and no action run. The plugin is responsible for using the
233   /// CompilerInstance's Diagnostic object to report errors.
234   virtual bool ParseArgs(const CompilerInstance &CI,
235                          const std::vector<std::string> &arg) = 0;
236 };
237 
238 /// \brief Abstract base class to use for preprocessor-based frontend actions.
239 class PreprocessorFrontendAction : public FrontendAction {
240 protected:
241   /// \brief Provide a default implementation which returns aborts;
242   /// this method should never be called by FrontendAction clients.
243   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
244                                          StringRef InFile);
245 
246 public:
usesPreprocessorOnly()247   virtual bool usesPreprocessorOnly() const { return true; }
248 };
249 
250 /// \brief A frontend action which simply wraps some other runtime-specified
251 /// frontend action.
252 ///
253 /// Deriving from this class allows an action to inject custom logic around
254 /// some existing action's behavior. It implements every virtual method in
255 /// the FrontendAction interface by forwarding to the wrapped action.
256 class WrapperFrontendAction : public FrontendAction {
257   OwningPtr<FrontendAction> WrappedAction;
258 
259 protected:
260   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
261                                          StringRef InFile);
262   virtual bool BeginInvocation(CompilerInstance &CI);
263   virtual bool BeginSourceFileAction(CompilerInstance &CI,
264                                      StringRef Filename);
265   virtual void ExecuteAction();
266   virtual void EndSourceFileAction();
267 
268 public:
269   /// Construct a WrapperFrontendAction from an existing action, taking
270   /// ownership of it.
271   WrapperFrontendAction(FrontendAction *WrappedAction);
272 
273   virtual bool usesPreprocessorOnly() const;
274   virtual TranslationUnitKind getTranslationUnitKind();
275   virtual bool hasPCHSupport() const;
276   virtual bool hasASTFileSupport() const;
277   virtual bool hasIRSupport() const;
278   virtual bool hasCodeCompletionSupport() const;
279 };
280 
281 }  // end namespace clang
282 
283 #endif
284