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