Home | History | Annotate | Download | only in Frontend
      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.
     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 
    107 public:
    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.
    216 class ASTFrontendAction : public FrontendAction {
    217 protected:
    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 
    225 public:
    226   virtual bool usesPreprocessorOnly() const { return false; }
    227 };
    228 
    229 class PluginASTAction : public ASTFrontendAction {
    230   virtual void anchor();
    231 protected:
    232   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
    233                                          StringRef InFile) = 0;
    234 
    235 public:
    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.
    247 class PreprocessorFrontendAction : public FrontendAction {
    248 protected:
    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 
    254 public:
    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.
    264 class WrapperFrontendAction : public FrontendAction {
    265   OwningPtr<FrontendAction> WrappedAction;
    266 
    267 protected:
    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 
    276 public:
    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