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/AST/ASTConsumer.h"
     22 #include "clang/Basic/LLVM.h"
     23 #include "clang/Basic/LangOptions.h"
     24 #include "clang/Frontend/ASTUnit.h"
     25 #include "clang/Frontend/FrontendOptions.h"
     26 #include "llvm/ADT/StringRef.h"
     27 #include <memory>
     28 #include <string>
     29 #include <vector>
     30 
     31 namespace clang {
     32 class ASTMergeAction;
     33 class CompilerInstance;
     34 
     35 /// Abstract base class for actions which can be performed by the frontend.
     36 class FrontendAction {
     37   FrontendInputFile CurrentInput;
     38   std::unique_ptr<ASTUnit> CurrentASTUnit;
     39   CompilerInstance *Instance;
     40   friend class ASTMergeAction;
     41   friend class WrapperFrontendAction;
     42 
     43 private:
     44   std::unique_ptr<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 std::unique_ptr<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     return true;
     81   }
     82 
     83   /// \brief Callback to run the program action, using the initialized
     84   /// compiler instance.
     85   ///
     86   /// This is guaranteed to only be called between BeginSourceFileAction()
     87   /// and EndSourceFileAction().
     88   virtual void ExecuteAction() = 0;
     89 
     90   /// \brief Callback at the end of processing a single input.
     91   ///
     92   /// This is guaranteed to only be called following a successful call to
     93   /// BeginSourceFileAction (and BeginSourceFile).
     94   virtual void EndSourceFileAction() {}
     95 
     96   /// \brief Callback at the end of processing a single input, to determine
     97   /// if the output files should be erased or not.
     98   ///
     99   /// By default it returns true if a compiler error occurred.
    100   /// This is guaranteed to only be called following a successful call to
    101   /// BeginSourceFileAction (and BeginSourceFile).
    102   virtual bool shouldEraseOutputFiles();
    103 
    104   /// @}
    105 
    106 public:
    107   FrontendAction();
    108   virtual ~FrontendAction();
    109 
    110   /// @name Compiler Instance Access
    111   /// @{
    112 
    113   CompilerInstance &getCompilerInstance() const {
    114     assert(Instance && "Compiler instance not registered!");
    115     return *Instance;
    116   }
    117 
    118   void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
    119 
    120   /// @}
    121   /// @name Current File Information
    122   /// @{
    123 
    124   bool isCurrentFileAST() const {
    125     assert(!CurrentInput.isEmpty() && "No current file!");
    126     return (bool)CurrentASTUnit;
    127   }
    128 
    129   const FrontendInputFile &getCurrentInput() const {
    130     return CurrentInput;
    131   }
    132 
    133   const StringRef getCurrentFile() const {
    134     assert(!CurrentInput.isEmpty() && "No current file!");
    135     return CurrentInput.getFile();
    136   }
    137 
    138   InputKind getCurrentFileKind() const {
    139     assert(!CurrentInput.isEmpty() && "No current file!");
    140     return CurrentInput.getKind();
    141   }
    142 
    143   ASTUnit &getCurrentASTUnit() const {
    144     assert(CurrentASTUnit && "No current AST unit!");
    145     return *CurrentASTUnit;
    146   }
    147 
    148   Module *getCurrentModule() const;
    149 
    150   std::unique_ptr<ASTUnit> takeCurrentASTUnit() {
    151     return std::move(CurrentASTUnit);
    152   }
    153 
    154   void setCurrentInput(const FrontendInputFile &CurrentInput,
    155                        std::unique_ptr<ASTUnit> AST = nullptr);
    156 
    157   /// @}
    158   /// @name Supported Modes
    159   /// @{
    160 
    161   /// \brief Is this action invoked on a model file?
    162   ///
    163   /// Model files are incomplete translation units that relies on type
    164   /// information from another translation unit. Check ParseModelFileAction for
    165   /// details.
    166   virtual bool isModelParsingAction() const { return false; }
    167 
    168   /// \brief Does this action only use the preprocessor?
    169   ///
    170   /// If so no AST context will be created and this action will be invalid
    171   /// with AST file inputs.
    172   virtual bool usesPreprocessorOnly() const = 0;
    173 
    174   /// \brief For AST-based actions, the kind of translation unit we're handling.
    175   virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
    176 
    177   /// \brief Does this action support use with PCH?
    178   virtual bool hasPCHSupport() const { return true; }
    179 
    180   /// \brief Does this action support use with AST files?
    181   virtual bool hasASTFileSupport() const { return true; }
    182 
    183   /// \brief Does this action support use with IR files?
    184   virtual bool hasIRSupport() const { return false; }
    185 
    186   /// \brief Does this action support use with code completion?
    187   virtual bool hasCodeCompletionSupport() const { return false; }
    188 
    189   /// @}
    190   /// @name Public Action Interface
    191   /// @{
    192 
    193   /// \brief Prepare the action for processing the input file \p Input.
    194   ///
    195   /// This is run after the options and frontend have been initialized,
    196   /// but prior to executing any per-file processing.
    197   ///
    198   /// \param CI - The compiler instance this action is being run from. The
    199   /// action may store and use this object up until the matching EndSourceFile
    200   /// action.
    201   ///
    202   /// \param Input - The input filename and kind. Some input kinds are handled
    203   /// specially, for example AST inputs, since the AST file itself contains
    204   /// several objects which would normally be owned by the
    205   /// CompilerInstance. When processing AST input files, these objects should
    206   /// generally not be initialized in the CompilerInstance -- they will
    207   /// automatically be shared with the AST file in between
    208   /// BeginSourceFile() and EndSourceFile().
    209   ///
    210   /// \return True on success; on failure the compilation of this file should
    211   /// be aborted and neither Execute() nor EndSourceFile() should be called.
    212   bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
    213 
    214   /// \brief Set the source manager's main input file, and run the action.
    215   bool Execute();
    216 
    217   /// \brief Perform any per-file post processing, deallocate per-file
    218   /// objects, and run statistics and output file cleanup code.
    219   void EndSourceFile();
    220 
    221   /// @}
    222 };
    223 
    224 /// \brief Abstract base class to use for AST consumer-based frontend actions.
    225 class ASTFrontendAction : public FrontendAction {
    226 protected:
    227   /// \brief Implement the ExecuteAction interface by running Sema on
    228   /// the already-initialized AST consumer.
    229   ///
    230   /// This will also take care of instantiating a code completion consumer if
    231   /// the user requested it and the action supports it.
    232   void ExecuteAction() override;
    233 
    234 public:
    235   ASTFrontendAction() {}
    236   bool usesPreprocessorOnly() const override { return false; }
    237 };
    238 
    239 class PluginASTAction : public ASTFrontendAction {
    240   virtual void anchor();
    241 public:
    242   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
    243                                                  StringRef InFile) override = 0;
    244 
    245   /// \brief Parse the given plugin command line arguments.
    246   ///
    247   /// \param CI - The compiler instance, for use in reporting diagnostics.
    248   /// \return True if the parsing succeeded; otherwise the plugin will be
    249   /// destroyed and no action run. The plugin is responsible for using the
    250   /// CompilerInstance's Diagnostic object to report errors.
    251   virtual bool ParseArgs(const CompilerInstance &CI,
    252                          const std::vector<std::string> &arg) = 0;
    253 
    254   enum ActionType {
    255     Cmdline,             ///< Action is determined by the cc1 command-line
    256     ReplaceAction,       ///< Replace the main action
    257     AddBeforeMainAction, ///< Execute the action before the main action
    258     AddAfterMainAction   ///< Execute the action after the main action
    259   };
    260   /// \brief Get the action type for this plugin
    261   ///
    262   /// \return The action type. If the type is Cmdline then by default the
    263   /// plugin does nothing and what it does is determined by the cc1
    264   /// command-line.
    265   virtual ActionType getActionType() { return Cmdline; }
    266 };
    267 
    268 /// \brief Abstract base class to use for preprocessor-based frontend actions.
    269 class PreprocessorFrontendAction : public FrontendAction {
    270 protected:
    271   /// \brief Provide a default implementation which returns aborts;
    272   /// this method should never be called by FrontendAction clients.
    273   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
    274                                                  StringRef InFile) override;
    275 
    276 public:
    277   bool usesPreprocessorOnly() const override { return true; }
    278 };
    279 
    280 /// \brief A frontend action which simply wraps some other runtime-specified
    281 /// frontend action.
    282 ///
    283 /// Deriving from this class allows an action to inject custom logic around
    284 /// some existing action's behavior. It implements every virtual method in
    285 /// the FrontendAction interface by forwarding to the wrapped action.
    286 class WrapperFrontendAction : public FrontendAction {
    287   std::unique_ptr<FrontendAction> WrappedAction;
    288 
    289 protected:
    290   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
    291                                                  StringRef InFile) override;
    292   bool BeginInvocation(CompilerInstance &CI) override;
    293   bool BeginSourceFileAction(CompilerInstance &CI) override;
    294   void ExecuteAction() override;
    295   void EndSourceFileAction() override;
    296 
    297 public:
    298   /// Construct a WrapperFrontendAction from an existing action, taking
    299   /// ownership of it.
    300   WrapperFrontendAction(std::unique_ptr<FrontendAction> WrappedAction);
    301 
    302   bool usesPreprocessorOnly() const override;
    303   TranslationUnitKind getTranslationUnitKind() override;
    304   bool hasPCHSupport() const override;
    305   bool hasASTFileSupport() const override;
    306   bool hasIRSupport() const override;
    307   bool hasCodeCompletionSupport() const override;
    308 };
    309 
    310 }  // end namespace clang
    311 
    312 #endif
    313