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