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
21namespace clang {
22class ASTConsumer;
23class ASTMergeAction;
24class ASTUnit;
25class CompilerInstance;
26
27/// FrontendAction - Abstract base class for actions which can be performed by
28/// the frontend.
29class FrontendAction {
30  FrontendInputFile CurrentInput;
31  OwningPtr<ASTUnit> CurrentASTUnit;
32  CompilerInstance *Instance;
33  friend class ASTMergeAction;
34  friend class WrapperFrontendAction;
35
36private:
37  ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
38                                        StringRef InFile);
39
40protected:
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.
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.
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).
89  virtual void EndSourceFileAction() {}
90
91  /// @}
92
93public:
94  FrontendAction();
95  virtual ~FrontendAction();
96
97  /// @name Compiler Instance Access
98  /// @{
99
100  CompilerInstance &getCompilerInstance() const {
101    assert(Instance && "Compiler instance not registered!");
102    return *Instance;
103  }
104
105  void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
106
107  /// @}
108  /// @name Current File Information
109  /// @{
110
111  bool isCurrentFileAST() const {
112    assert(!CurrentInput.File.empty() && "No current file!");
113    return CurrentASTUnit != 0;
114  }
115
116  const FrontendInputFile &getCurrentInput() const {
117    return CurrentInput;
118  }
119
120  const std::string &getCurrentFile() const {
121    assert(!CurrentInput.File.empty() && "No current file!");
122    return CurrentInput.File;
123  }
124
125  InputKind getCurrentFileKind() const {
126    assert(!CurrentInput.File.empty() && "No current file!");
127    return CurrentInput.Kind;
128  }
129
130  ASTUnit &getCurrentASTUnit() const {
131    assert(CurrentASTUnit && "No current AST unit!");
132    return *CurrentASTUnit;
133  }
134
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.
151  virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
152
153  /// hasPCHSupport - Does this action support use with PCH?
154  virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
155
156  /// hasASTFileSupport - Does this action support use with AST files?
157  virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
158
159  /// hasIRSupport - Does this action support use with IR files?
160  virtual bool hasIRSupport() const { return false; }
161
162  /// hasCodeCompletionSupport - Does this action support use with code
163  /// completion?
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  void 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.
202class ASTFrontendAction : public FrontendAction {
203protected:
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
211public:
212  virtual bool usesPreprocessorOnly() const { return false; }
213};
214
215class PluginASTAction : public ASTFrontendAction {
216  virtual void anchor();
217protected:
218  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
219                                         StringRef InFile) = 0;
220
221public:
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.
234class PreprocessorFrontendAction : public FrontendAction {
235protected:
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
241public:
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.
250class WrapperFrontendAction : public FrontendAction {
251  OwningPtr<FrontendAction> WrappedAction;
252
253protected:
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
262public:
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