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