1199482Srdivacky//===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===//
2199482Srdivacky//
3199482Srdivacky//                     The LLVM Compiler Infrastructure
4199482Srdivacky//
5199482Srdivacky// This file is distributed under the University of Illinois Open Source
6199482Srdivacky// License. See LICENSE.TXT for details.
7199482Srdivacky//
8199482Srdivacky//===----------------------------------------------------------------------===//
9249423Sdim///
10249423Sdim/// \file
11249423Sdim/// \brief Defines the clang::FrontendAction interface and various convenience
12249423Sdim/// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction,
13249423Sdim/// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction)
14249423Sdim/// derived from it.
15249423Sdim///
16249423Sdim//===----------------------------------------------------------------------===//
17199482Srdivacky
18199482Srdivacky#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
19199482Srdivacky#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
20199482Srdivacky
21226633Sdim#include "clang/Basic/LLVM.h"
22226633Sdim#include "clang/Basic/LangOptions.h"
23234353Sdim#include "clang/Frontend/FrontendOptions.h"
24249423Sdim#include "llvm/ADT/OwningPtr.h"
25199482Srdivacky#include "llvm/ADT/StringRef.h"
26199482Srdivacky#include <string>
27210299Sed#include <vector>
28199482Srdivacky
29199482Srdivackynamespace clang {
30210299Sedclass ASTConsumer;
31210299Sedclass ASTMergeAction;
32199482Srdivackyclass ASTUnit;
33199482Srdivackyclass CompilerInstance;
34199482Srdivacky
35249423Sdim/// Abstract base class for actions which can be performed by the frontend.
36199482Srdivackyclass FrontendAction {
37234353Sdim  FrontendInputFile CurrentInput;
38234353Sdim  OwningPtr<ASTUnit> CurrentASTUnit;
39199482Srdivacky  CompilerInstance *Instance;
40203955Srdivacky  friend class ASTMergeAction;
41224145Sdim  friend class WrapperFrontendAction;
42199482Srdivacky
43218893Sdimprivate:
44218893Sdim  ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
45226633Sdim                                        StringRef InFile);
46218893Sdim
47199482Srdivackyprotected:
48199482Srdivacky  /// @name Implementation Action Interface
49199482Srdivacky  /// @{
50199482Srdivacky
51249423Sdim  /// \brief Create the AST consumer object for this action, if supported.
52199482Srdivacky  ///
53249423Sdim  /// This routine is called as part of BeginSourceFile(), which will
54199482Srdivacky  /// fail if the AST consumer cannot be created. This will not be called if the
55199482Srdivacky  /// action has indicated that it only uses the preprocessor.
56199482Srdivacky  ///
57249423Sdim  /// \param CI - The current compiler instance, provided as a convenience, see
58199482Srdivacky  /// getCompilerInstance().
59199482Srdivacky  ///
60249423Sdim  /// \param InFile - The current input file, provided as a convenience, see
61199482Srdivacky  /// getCurrentFile().
62199482Srdivacky  ///
63249423Sdim  /// \return The new AST consumer, or null on failure.
64199482Srdivacky  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
65226633Sdim                                         StringRef InFile) = 0;
66199482Srdivacky
67224145Sdim  /// \brief Callback before starting processing a single input, giving the
68224145Sdim  /// opportunity to modify the CompilerInvocation or do some other action
69224145Sdim  /// before BeginSourceFileAction is called.
70224145Sdim  ///
71249423Sdim  /// \return True on success; on failure BeginSourceFileAction(),
72249423Sdim  /// ExecuteAction() and EndSourceFileAction() will not be called.
73224145Sdim  virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
74224145Sdim
75249423Sdim  /// \brief Callback at the start of processing a single input.
76199482Srdivacky  ///
77249423Sdim  /// \return True on success; on failure ExecutionAction() and
78199482Srdivacky  /// EndSourceFileAction() will not be called.
79199482Srdivacky  virtual bool BeginSourceFileAction(CompilerInstance &CI,
80226633Sdim                                     StringRef Filename) {
81199482Srdivacky    return true;
82199482Srdivacky  }
83199482Srdivacky
84249423Sdim  /// \brief Callback to run the program action, using the initialized
85199482Srdivacky  /// compiler instance.
86199482Srdivacky  ///
87249423Sdim  /// This is guaranteed to only be called between BeginSourceFileAction()
88249423Sdim  /// and EndSourceFileAction().
89199482Srdivacky  virtual void ExecuteAction() = 0;
90199482Srdivacky
91249423Sdim  /// \brief Callback at the end of processing a single input.
92249423Sdim  ///
93249423Sdim  /// This is guaranteed to only be called following a successful call to
94234353Sdim  /// BeginSourceFileAction (and BeginSourceFile).
95199482Srdivacky  virtual void EndSourceFileAction() {}
96199482Srdivacky
97263508Sdim  /// \brief Callback at the end of processing a single input, to determine
98263508Sdim  /// if the output files should be erased or not.
99263508Sdim  ///
100263508Sdim  /// By default it returns true if a compiler error occurred.
101263508Sdim  /// This is guaranteed to only be called following a successful call to
102263508Sdim  /// BeginSourceFileAction (and BeginSourceFile).
103263508Sdim  virtual bool shouldEraseOutputFiles();
104263508Sdim
105199482Srdivacky  /// @}
106199482Srdivacky
107199482Srdivackypublic:
108199482Srdivacky  FrontendAction();
109199482Srdivacky  virtual ~FrontendAction();
110199482Srdivacky
111199482Srdivacky  /// @name Compiler Instance Access
112199482Srdivacky  /// @{
113199482Srdivacky
114199482Srdivacky  CompilerInstance &getCompilerInstance() const {
115199482Srdivacky    assert(Instance && "Compiler instance not registered!");
116199482Srdivacky    return *Instance;
117199482Srdivacky  }
118199482Srdivacky
119199482Srdivacky  void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
120199482Srdivacky
121199482Srdivacky  /// @}
122199482Srdivacky  /// @name Current File Information
123199482Srdivacky  /// @{
124199482Srdivacky
125199482Srdivacky  bool isCurrentFileAST() const {
126243830Sdim    assert(!CurrentInput.isEmpty() && "No current file!");
127263508Sdim    return CurrentASTUnit.isValid();
128199482Srdivacky  }
129199482Srdivacky
130234353Sdim  const FrontendInputFile &getCurrentInput() const {
131234353Sdim    return CurrentInput;
132234353Sdim  }
133234353Sdim
134243830Sdim  const StringRef getCurrentFile() const {
135243830Sdim    assert(!CurrentInput.isEmpty() && "No current file!");
136243830Sdim    return CurrentInput.getFile();
137199482Srdivacky  }
138199482Srdivacky
139210299Sed  InputKind getCurrentFileKind() const {
140243830Sdim    assert(!CurrentInput.isEmpty() && "No current file!");
141243830Sdim    return CurrentInput.getKind();
142210299Sed  }
143210299Sed
144199482Srdivacky  ASTUnit &getCurrentASTUnit() const {
145218893Sdim    assert(CurrentASTUnit && "No current AST unit!");
146199482Srdivacky    return *CurrentASTUnit;
147199482Srdivacky  }
148199482Srdivacky
149203955Srdivacky  ASTUnit *takeCurrentASTUnit() {
150203955Srdivacky    return CurrentASTUnit.take();
151203955Srdivacky  }
152203955Srdivacky
153234353Sdim  void setCurrentInput(const FrontendInputFile &CurrentInput, ASTUnit *AST = 0);
154199482Srdivacky
155199482Srdivacky  /// @}
156199482Srdivacky  /// @name Supported Modes
157199482Srdivacky  /// @{
158199482Srdivacky
159249423Sdim  /// \brief Does this action only use the preprocessor?
160249423Sdim  ///
161249423Sdim  /// If so no AST context will be created and this action will be invalid
162249423Sdim  /// with AST file inputs.
163199482Srdivacky  virtual bool usesPreprocessorOnly() const = 0;
164199482Srdivacky
165226633Sdim  /// \brief For AST-based actions, the kind of translation unit we're handling.
166226633Sdim  virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
167199482Srdivacky
168249423Sdim  /// \brief Does this action support use with PCH?
169199482Srdivacky  virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
170199482Srdivacky
171249423Sdim  /// \brief Does this action support use with AST files?
172210299Sed  virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
173199482Srdivacky
174249423Sdim  /// \brief Does this action support use with IR files?
175210299Sed  virtual bool hasIRSupport() const { return false; }
176210299Sed
177249423Sdim  /// \brief Does this action support use with code completion?
178199482Srdivacky  virtual bool hasCodeCompletionSupport() const { return false; }
179199482Srdivacky
180199482Srdivacky  /// @}
181199482Srdivacky  /// @name Public Action Interface
182199482Srdivacky  /// @{
183199482Srdivacky
184249423Sdim  /// \brief Prepare the action for processing the input file \p Input.
185199482Srdivacky  ///
186249423Sdim  /// This is run after the options and frontend have been initialized,
187249423Sdim  /// but prior to executing any per-file processing.
188249423Sdim  ///
189199482Srdivacky  /// \param CI - The compiler instance this action is being run from. The
190199482Srdivacky  /// action may store and use this object up until the matching EndSourceFile
191199482Srdivacky  /// action.
192199482Srdivacky  ///
193234353Sdim  /// \param Input - The input filename and kind. Some input kinds are handled
194210299Sed  /// specially, for example AST inputs, since the AST file itself contains
195210299Sed  /// several objects which would normally be owned by the
196210299Sed  /// CompilerInstance. When processing AST input files, these objects should
197210299Sed  /// generally not be initialized in the CompilerInstance -- they will
198249423Sdim  /// automatically be shared with the AST file in between
199249423Sdim  /// BeginSourceFile() and EndSourceFile().
200199482Srdivacky  ///
201234353Sdim  /// \return True on success; on failure the compilation of this file should
202249423Sdim  /// be aborted and neither Execute() nor EndSourceFile() should be called.
203234353Sdim  bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
204199482Srdivacky
205249423Sdim  /// \brief Set the source manager's main input file, and run the action.
206239462Sdim  bool Execute();
207199482Srdivacky
208249423Sdim  /// \brief Perform any per-file post processing, deallocate per-file
209199482Srdivacky  /// objects, and run statistics and output file cleanup code.
210199482Srdivacky  void EndSourceFile();
211199482Srdivacky
212199482Srdivacky  /// @}
213199482Srdivacky};
214199482Srdivacky
215249423Sdim/// \brief Abstract base class to use for AST consumer-based frontend actions.
216199482Srdivackyclass ASTFrontendAction : public FrontendAction {
217210299Sedprotected:
218249423Sdim  /// \brief Implement the ExecuteAction interface by running Sema on
219249423Sdim  /// the already-initialized AST consumer.
220199482Srdivacky  ///
221199482Srdivacky  /// This will also take care of instantiating a code completion consumer if
222199482Srdivacky  /// the user requested it and the action supports it.
223199482Srdivacky  virtual void ExecuteAction();
224199482Srdivacky
225199482Srdivackypublic:
226199482Srdivacky  virtual bool usesPreprocessorOnly() const { return false; }
227199482Srdivacky};
228199482Srdivacky
229210299Sedclass PluginASTAction : public ASTFrontendAction {
230234353Sdim  virtual void anchor();
231210299Sedprotected:
232210299Sed  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
233226633Sdim                                         StringRef InFile) = 0;
234210299Sed
235210299Sedpublic:
236249423Sdim  /// \brief Parse the given plugin command line arguments.
237212904Sdim  ///
238212904Sdim  /// \param CI - The compiler instance, for use in reporting diagnostics.
239212904Sdim  /// \return True if the parsing succeeded; otherwise the plugin will be
240212904Sdim  /// destroyed and no action run. The plugin is responsible for using the
241212904Sdim  /// CompilerInstance's Diagnostic object to report errors.
242212904Sdim  virtual bool ParseArgs(const CompilerInstance &CI,
243212904Sdim                         const std::vector<std::string> &arg) = 0;
244210299Sed};
245210299Sed
246249423Sdim/// \brief Abstract base class to use for preprocessor-based frontend actions.
247199482Srdivackyclass PreprocessorFrontendAction : public FrontendAction {
248199482Srdivackyprotected:
249249423Sdim  /// \brief Provide a default implementation which returns aborts;
250199482Srdivacky  /// this method should never be called by FrontendAction clients.
251199482Srdivacky  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
252226633Sdim                                         StringRef InFile);
253199482Srdivacky
254199482Srdivackypublic:
255199482Srdivacky  virtual bool usesPreprocessorOnly() const { return true; }
256199482Srdivacky};
257199482Srdivacky
258249423Sdim/// \brief A frontend action which simply wraps some other runtime-specified
259249423Sdim/// frontend action.
260249423Sdim///
261249423Sdim/// Deriving from this class allows an action to inject custom logic around
262249423Sdim/// some existing action's behavior. It implements every virtual method in
263249423Sdim/// the FrontendAction interface by forwarding to the wrapped action.
264224145Sdimclass WrapperFrontendAction : public FrontendAction {
265234353Sdim  OwningPtr<FrontendAction> WrappedAction;
266224145Sdim
267224145Sdimprotected:
268224145Sdim  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
269226633Sdim                                         StringRef InFile);
270224145Sdim  virtual bool BeginInvocation(CompilerInstance &CI);
271224145Sdim  virtual bool BeginSourceFileAction(CompilerInstance &CI,
272226633Sdim                                     StringRef Filename);
273224145Sdim  virtual void ExecuteAction();
274224145Sdim  virtual void EndSourceFileAction();
275224145Sdim
276224145Sdimpublic:
277224145Sdim  /// Construct a WrapperFrontendAction from an existing action, taking
278224145Sdim  /// ownership of it.
279224145Sdim  WrapperFrontendAction(FrontendAction *WrappedAction);
280224145Sdim
281224145Sdim  virtual bool usesPreprocessorOnly() const;
282226633Sdim  virtual TranslationUnitKind getTranslationUnitKind();
283224145Sdim  virtual bool hasPCHSupport() const;
284224145Sdim  virtual bool hasASTFileSupport() const;
285224145Sdim  virtual bool hasIRSupport() const;
286224145Sdim  virtual bool hasCodeCompletionSupport() const;
287224145Sdim};
288224145Sdim
289199482Srdivacky}  // end namespace clang
290199482Srdivacky
291199482Srdivacky#endif
292