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