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 #ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
     11 #define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
     12 
     13 #include "llvm/ADT/StringRef.h"
     14 #include "llvm/ADT/OwningPtr.h"
     15 #include <string>
     16 #include <vector>
     17 
     18 namespace llvm {
     19   class raw_ostream;
     20 }
     21 
     22 namespace clang {
     23 class ASTConsumer;
     24 class ASTMergeAction;
     25 class ASTUnit;
     26 class CompilerInstance;
     27 
     28 enum InputKind {
     29   IK_None,
     30   IK_Asm,
     31   IK_C,
     32   IK_CXX,
     33   IK_ObjC,
     34   IK_ObjCXX,
     35   IK_PreprocessedC,
     36   IK_PreprocessedCXX,
     37   IK_PreprocessedObjC,
     38   IK_PreprocessedObjCXX,
     39   IK_OpenCL,
     40   IK_CUDA,
     41   IK_AST,
     42   IK_LLVM_IR
     43 };
     44 
     45 
     46 /// FrontendAction - Abstract base class for actions which can be performed by
     47 /// the frontend.
     48 class FrontendAction {
     49   std::string CurrentFile;
     50   InputKind CurrentFileKind;
     51   llvm::OwningPtr<ASTUnit> CurrentASTUnit;
     52   CompilerInstance *Instance;
     53   friend class ASTMergeAction;
     54   friend class WrapperFrontendAction;
     55 
     56 private:
     57   ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
     58                                         llvm::StringRef InFile);
     59 
     60 protected:
     61   /// @name Implementation Action Interface
     62   /// @{
     63 
     64   /// CreateASTConsumer - Create the AST consumer object for this action, if
     65   /// supported.
     66   ///
     67   /// This routine is called as part of \see BeginSourceAction(), which will
     68   /// fail if the AST consumer cannot be created. This will not be called if the
     69   /// action has indicated that it only uses the preprocessor.
     70   ///
     71   /// \param CI - The current compiler instance, provided as a convenience, \see
     72   /// getCompilerInstance().
     73   ///
     74   /// \param InFile - The current input file, provided as a convenience, \see
     75   /// getCurrentFile().
     76   ///
     77   /// \return The new AST consumer, or 0 on failure.
     78   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
     79                                          llvm::StringRef InFile) = 0;
     80 
     81   /// \brief Callback before starting processing a single input, giving the
     82   /// opportunity to modify the CompilerInvocation or do some other action
     83   /// before BeginSourceFileAction is called.
     84   ///
     85   /// \return True on success; on failure \see BeginSourceFileAction() and
     86   /// ExecutionAction() and EndSourceFileAction() will not be called.
     87   virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
     88 
     89   /// BeginSourceFileAction - Callback at the start of processing a single
     90   /// input.
     91   ///
     92   /// \return True on success; on failure \see ExecutionAction() and
     93   /// EndSourceFileAction() will not be called.
     94   virtual bool BeginSourceFileAction(CompilerInstance &CI,
     95                                      llvm::StringRef Filename) {
     96     return true;
     97   }
     98 
     99   /// ExecuteAction - Callback to run the program action, using the initialized
    100   /// compiler instance.
    101   ///
    102   /// This routine is guaranteed to only be called between \see
    103   /// BeginSourceFileAction() and \see EndSourceFileAction().
    104   virtual void ExecuteAction() = 0;
    105 
    106   /// EndSourceFileAction - Callback at the end of processing a single input;
    107   /// this is guaranteed to only be called following a successful call to
    108   /// BeginSourceFileAction (and BeingSourceFile).
    109   virtual void EndSourceFileAction() {}
    110 
    111   /// @}
    112 
    113 public:
    114   FrontendAction();
    115   virtual ~FrontendAction();
    116 
    117   /// @name Compiler Instance Access
    118   /// @{
    119 
    120   CompilerInstance &getCompilerInstance() const {
    121     assert(Instance && "Compiler instance not registered!");
    122     return *Instance;
    123   }
    124 
    125   void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
    126 
    127   /// @}
    128   /// @name Current File Information
    129   /// @{
    130 
    131   bool isCurrentFileAST() const {
    132     assert(!CurrentFile.empty() && "No current file!");
    133     return CurrentASTUnit != 0;
    134   }
    135 
    136   const std::string &getCurrentFile() const {
    137     assert(!CurrentFile.empty() && "No current file!");
    138     return CurrentFile;
    139   }
    140 
    141   InputKind getCurrentFileKind() const {
    142     assert(!CurrentFile.empty() && "No current file!");
    143     return CurrentFileKind;
    144   }
    145 
    146   ASTUnit &getCurrentASTUnit() const {
    147     assert(CurrentASTUnit && "No current AST unit!");
    148     return *CurrentASTUnit;
    149   }
    150 
    151   ASTUnit *takeCurrentASTUnit() {
    152     return CurrentASTUnit.take();
    153   }
    154 
    155   void setCurrentFile(llvm::StringRef Value, InputKind Kind, ASTUnit *AST = 0);
    156 
    157   /// @}
    158   /// @name Supported Modes
    159   /// @{
    160 
    161   /// usesPreprocessorOnly - Does this action only use the preprocessor? If so
    162   /// no AST context will be created and this action will be invalid with AST
    163   /// file inputs.
    164   virtual bool usesPreprocessorOnly() const = 0;
    165 
    166   /// usesCompleteTranslationUnit - For AST based actions, should the
    167   /// translation unit be completed?
    168   virtual bool usesCompleteTranslationUnit() { return true; }
    169 
    170   /// hasPCHSupport - Does this action support use with PCH?
    171   virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
    172 
    173   /// hasASTFileSupport - Does this action support use with AST files?
    174   virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
    175 
    176   /// hasIRSupport - Does this action support use with IR files?
    177   virtual bool hasIRSupport() const { return false; }
    178 
    179   /// hasCodeCompletionSupport - Does this action support use with code
    180   /// completion?
    181   virtual bool hasCodeCompletionSupport() const { return false; }
    182 
    183   /// @}
    184   /// @name Public Action Interface
    185   /// @{
    186 
    187   /// BeginSourceFile - Prepare the action for processing the input file \arg
    188   /// Filename; this is run after the options and frontend have been
    189   /// initialized, but prior to executing any per-file processing.
    190   ///
    191   /// \param CI - The compiler instance this action is being run from. The
    192   /// action may store and use this object up until the matching EndSourceFile
    193   /// action.
    194   ///
    195   /// \param Filename - The input filename, which will be made available to
    196   /// clients via \see getCurrentFile().
    197   ///
    198   /// \param InputKind - The type of input. Some input kinds are handled
    199   /// specially, for example AST inputs, since the AST file itself contains
    200   /// several objects which would normally be owned by the
    201   /// CompilerInstance. When processing AST input files, these objects should
    202   /// generally not be initialized in the CompilerInstance -- they will
    203   /// automatically be shared with the AST file in between \see
    204   /// BeginSourceFile() and \see EndSourceFile().
    205   ///
    206   /// \return True on success; the compilation of this file should be aborted
    207   /// and neither Execute nor EndSourceFile should be called.
    208   bool BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename,
    209                        InputKind Kind);
    210 
    211   /// Execute - Set the source managers main input file, and run the action.
    212   void Execute();
    213 
    214   /// EndSourceFile - Perform any per-file post processing, deallocate per-file
    215   /// objects, and run statistics and output file cleanup code.
    216   void EndSourceFile();
    217 
    218   /// @}
    219 };
    220 
    221 /// ASTFrontendAction - Abstract base class to use for AST consumer based
    222 /// frontend actions.
    223 class ASTFrontendAction : public FrontendAction {
    224 protected:
    225   /// ExecuteAction - Implement the ExecuteAction interface by running Sema on
    226   /// the already initialized AST consumer.
    227   ///
    228   /// This will also take care of instantiating a code completion consumer if
    229   /// the user requested it and the action supports it.
    230   virtual void ExecuteAction();
    231 
    232 public:
    233   virtual bool usesPreprocessorOnly() const { return false; }
    234 };
    235 
    236 class PluginASTAction : public ASTFrontendAction {
    237 protected:
    238   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
    239                                          llvm::StringRef InFile) = 0;
    240 
    241 public:
    242   /// ParseArgs - Parse the given plugin command line arguments.
    243   ///
    244   /// \param CI - The compiler instance, for use in reporting diagnostics.
    245   /// \return True if the parsing succeeded; otherwise the plugin will be
    246   /// destroyed and no action run. The plugin is responsible for using the
    247   /// CompilerInstance's Diagnostic object to report errors.
    248   virtual bool ParseArgs(const CompilerInstance &CI,
    249                          const std::vector<std::string> &arg) = 0;
    250 };
    251 
    252 /// PreprocessorFrontendAction - Abstract base class to use for preprocessor
    253 /// based frontend actions.
    254 class PreprocessorFrontendAction : public FrontendAction {
    255 protected:
    256   /// CreateASTConsumer - Provide a default implementation which returns aborts,
    257   /// this method should never be called by FrontendAction clients.
    258   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
    259                                          llvm::StringRef InFile);
    260 
    261 public:
    262   virtual bool usesPreprocessorOnly() const { return true; }
    263 };
    264 
    265 /// WrapperFrontendAction - A frontend action which simply wraps some other
    266 /// runtime specified frontend action. Deriving from this class allows an
    267 /// action to inject custom logic around some existing action's behavior. It
    268 /// implements every virtual method in the FrontendAction interface by
    269 /// forwarding to the wrapped action.
    270 class WrapperFrontendAction : public FrontendAction {
    271   llvm::OwningPtr<FrontendAction> WrappedAction;
    272 
    273 protected:
    274   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
    275                                          llvm::StringRef InFile);
    276   virtual bool BeginInvocation(CompilerInstance &CI);
    277   virtual bool BeginSourceFileAction(CompilerInstance &CI,
    278                                      llvm::StringRef Filename);
    279   virtual void ExecuteAction();
    280   virtual void EndSourceFileAction();
    281 
    282 public:
    283   /// Construct a WrapperFrontendAction from an existing action, taking
    284   /// ownership of it.
    285   WrapperFrontendAction(FrontendAction *WrappedAction);
    286 
    287   virtual bool usesPreprocessorOnly() const;
    288   virtual bool usesCompleteTranslationUnit();
    289   virtual bool hasPCHSupport() const;
    290   virtual bool hasASTFileSupport() const;
    291   virtual bool hasIRSupport() const;
    292   virtual bool hasCodeCompletionSupport() const;
    293 };
    294 
    295 }  // end namespace clang
    296 
    297 #endif
    298