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