Home | History | Annotate | Download | only in Driver
      1 //===--- Action.h - Abstract compilation steps ------------------*- 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_DRIVER_ACTION_H
     11 #define LLVM_CLANG_DRIVER_ACTION_H
     12 
     13 #include "clang/Basic/Cuda.h"
     14 #include "clang/Driver/Types.h"
     15 #include "clang/Driver/Util.h"
     16 #include "llvm/ADT/SmallVector.h"
     17 
     18 namespace llvm {
     19 
     20 class StringRef;
     21 
     22 namespace opt {
     23   class Arg;
     24 }
     25 }
     26 
     27 namespace clang {
     28 namespace driver {
     29 
     30 /// Action - Represent an abstract compilation step to perform.
     31 ///
     32 /// An action represents an edge in the compilation graph; typically
     33 /// it is a job to transform an input using some tool.
     34 ///
     35 /// The current driver is hard wired to expect actions which produce a
     36 /// single primary output, at least in terms of controlling the
     37 /// compilation. Actions can produce auxiliary files, but can only
     38 /// produce a single output to feed into subsequent actions.
     39 ///
     40 /// Actions are usually owned by a Compilation, which creates new
     41 /// actions via MakeAction().
     42 class Action {
     43 public:
     44   typedef ActionList::size_type size_type;
     45   typedef ActionList::iterator input_iterator;
     46   typedef ActionList::const_iterator input_const_iterator;
     47   typedef llvm::iterator_range<input_iterator> input_range;
     48   typedef llvm::iterator_range<input_const_iterator> input_const_range;
     49 
     50   enum ActionClass {
     51     InputClass = 0,
     52     BindArchClass,
     53     CudaDeviceClass,
     54     CudaHostClass,
     55     PreprocessJobClass,
     56     PrecompileJobClass,
     57     AnalyzeJobClass,
     58     MigrateJobClass,
     59     CompileJobClass,
     60     BackendJobClass,
     61     AssembleJobClass,
     62     LinkJobClass,
     63     LipoJobClass,
     64     DsymutilJobClass,
     65     VerifyDebugInfoJobClass,
     66     VerifyPCHJobClass,
     67 
     68     JobClassFirst=PreprocessJobClass,
     69     JobClassLast=VerifyPCHJobClass
     70   };
     71 
     72   // The offloading kind determines if this action is binded to a particular
     73   // programming model. Each entry reserves one bit. We also have a special kind
     74   // to designate the host offloading tool chain.
     75   //
     76   // FIXME: This is currently used to indicate that tool chains are used in a
     77   // given programming, but will be used here as well once a generic offloading
     78   // action is implemented.
     79   enum OffloadKind {
     80     OFK_None = 0x00,
     81     // The host offloading tool chain.
     82     OFK_Host = 0x01,
     83     // The device offloading tool chains - one bit for each programming model.
     84     OFK_Cuda = 0x02,
     85   };
     86 
     87   static const char *getClassName(ActionClass AC);
     88 
     89 private:
     90   ActionClass Kind;
     91 
     92   /// The output type of this action.
     93   types::ID Type;
     94 
     95   ActionList Inputs;
     96 
     97 protected:
     98   Action(ActionClass Kind, types::ID Type) : Action(Kind, ActionList(), Type) {}
     99   Action(ActionClass Kind, Action *Input, types::ID Type)
    100       : Action(Kind, ActionList({Input}), Type) {}
    101   Action(ActionClass Kind, Action *Input)
    102       : Action(Kind, ActionList({Input}), Input->getType()) {}
    103   Action(ActionClass Kind, const ActionList &Inputs, types::ID Type)
    104       : Kind(Kind), Type(Type), Inputs(Inputs) {}
    105 
    106 public:
    107   virtual ~Action();
    108 
    109   const char *getClassName() const { return Action::getClassName(getKind()); }
    110 
    111   ActionClass getKind() const { return Kind; }
    112   types::ID getType() const { return Type; }
    113 
    114   ActionList &getInputs() { return Inputs; }
    115   const ActionList &getInputs() const { return Inputs; }
    116 
    117   size_type size() const { return Inputs.size(); }
    118 
    119   input_iterator input_begin() { return Inputs.begin(); }
    120   input_iterator input_end() { return Inputs.end(); }
    121   input_range inputs() { return input_range(input_begin(), input_end()); }
    122   input_const_iterator input_begin() const { return Inputs.begin(); }
    123   input_const_iterator input_end() const { return Inputs.end(); }
    124   input_const_range inputs() const {
    125     return input_const_range(input_begin(), input_end());
    126   }
    127 };
    128 
    129 class InputAction : public Action {
    130   virtual void anchor();
    131   const llvm::opt::Arg &Input;
    132 
    133 public:
    134   InputAction(const llvm::opt::Arg &Input, types::ID Type);
    135 
    136   const llvm::opt::Arg &getInputArg() const { return Input; }
    137 
    138   static bool classof(const Action *A) {
    139     return A->getKind() == InputClass;
    140   }
    141 };
    142 
    143 class BindArchAction : public Action {
    144   virtual void anchor();
    145   /// The architecture to bind, or 0 if the default architecture
    146   /// should be bound.
    147   const char *ArchName;
    148 
    149 public:
    150   BindArchAction(Action *Input, const char *ArchName);
    151 
    152   const char *getArchName() const { return ArchName; }
    153 
    154   static bool classof(const Action *A) {
    155     return A->getKind() == BindArchClass;
    156   }
    157 };
    158 
    159 class CudaDeviceAction : public Action {
    160   virtual void anchor();
    161 
    162   const CudaArch GpuArch;
    163 
    164   /// True when action results are not consumed by the host action (e.g when
    165   /// -fsyntax-only or --cuda-device-only options are used).
    166   bool AtTopLevel;
    167 
    168 public:
    169   CudaDeviceAction(Action *Input, CudaArch Arch, bool AtTopLevel);
    170 
    171   /// Get the CUDA GPU architecture to which this Action corresponds.  Returns
    172   /// UNKNOWN if this Action corresponds to multiple architectures.
    173   CudaArch getGpuArch() const { return GpuArch; }
    174 
    175   bool isAtTopLevel() const { return AtTopLevel; }
    176 
    177   static bool classof(const Action *A) {
    178     return A->getKind() == CudaDeviceClass;
    179   }
    180 };
    181 
    182 class CudaHostAction : public Action {
    183   virtual void anchor();
    184   ActionList DeviceActions;
    185 
    186 public:
    187   CudaHostAction(Action *Input, const ActionList &DeviceActions);
    188 
    189   const ActionList &getDeviceActions() const { return DeviceActions; }
    190 
    191   static bool classof(const Action *A) { return A->getKind() == CudaHostClass; }
    192 };
    193 
    194 class JobAction : public Action {
    195   virtual void anchor();
    196 protected:
    197   JobAction(ActionClass Kind, Action *Input, types::ID Type);
    198   JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
    199 
    200 public:
    201   static bool classof(const Action *A) {
    202     return (A->getKind() >= JobClassFirst &&
    203             A->getKind() <= JobClassLast);
    204   }
    205 };
    206 
    207 class PreprocessJobAction : public JobAction {
    208   void anchor() override;
    209 public:
    210   PreprocessJobAction(Action *Input, types::ID OutputType);
    211 
    212   static bool classof(const Action *A) {
    213     return A->getKind() == PreprocessJobClass;
    214   }
    215 };
    216 
    217 class PrecompileJobAction : public JobAction {
    218   void anchor() override;
    219 public:
    220   PrecompileJobAction(Action *Input, types::ID OutputType);
    221 
    222   static bool classof(const Action *A) {
    223     return A->getKind() == PrecompileJobClass;
    224   }
    225 };
    226 
    227 class AnalyzeJobAction : public JobAction {
    228   void anchor() override;
    229 public:
    230   AnalyzeJobAction(Action *Input, types::ID OutputType);
    231 
    232   static bool classof(const Action *A) {
    233     return A->getKind() == AnalyzeJobClass;
    234   }
    235 };
    236 
    237 class MigrateJobAction : public JobAction {
    238   void anchor() override;
    239 public:
    240   MigrateJobAction(Action *Input, types::ID OutputType);
    241 
    242   static bool classof(const Action *A) {
    243     return A->getKind() == MigrateJobClass;
    244   }
    245 };
    246 
    247 class CompileJobAction : public JobAction {
    248   void anchor() override;
    249 public:
    250   CompileJobAction(Action *Input, types::ID OutputType);
    251 
    252   static bool classof(const Action *A) {
    253     return A->getKind() == CompileJobClass;
    254   }
    255 };
    256 
    257 class BackendJobAction : public JobAction {
    258   void anchor() override;
    259 public:
    260   BackendJobAction(Action *Input, types::ID OutputType);
    261 
    262   static bool classof(const Action *A) {
    263     return A->getKind() == BackendJobClass;
    264   }
    265 };
    266 
    267 class AssembleJobAction : public JobAction {
    268   void anchor() override;
    269 public:
    270   AssembleJobAction(Action *Input, types::ID OutputType);
    271 
    272   static bool classof(const Action *A) {
    273     return A->getKind() == AssembleJobClass;
    274   }
    275 };
    276 
    277 class LinkJobAction : public JobAction {
    278   void anchor() override;
    279 public:
    280   LinkJobAction(ActionList &Inputs, types::ID Type);
    281 
    282   static bool classof(const Action *A) {
    283     return A->getKind() == LinkJobClass;
    284   }
    285 };
    286 
    287 class LipoJobAction : public JobAction {
    288   void anchor() override;
    289 public:
    290   LipoJobAction(ActionList &Inputs, types::ID Type);
    291 
    292   static bool classof(const Action *A) {
    293     return A->getKind() == LipoJobClass;
    294   }
    295 };
    296 
    297 class DsymutilJobAction : public JobAction {
    298   void anchor() override;
    299 public:
    300   DsymutilJobAction(ActionList &Inputs, types::ID Type);
    301 
    302   static bool classof(const Action *A) {
    303     return A->getKind() == DsymutilJobClass;
    304   }
    305 };
    306 
    307 class VerifyJobAction : public JobAction {
    308   void anchor() override;
    309 public:
    310   VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type);
    311   static bool classof(const Action *A) {
    312     return A->getKind() == VerifyDebugInfoJobClass ||
    313            A->getKind() == VerifyPCHJobClass;
    314   }
    315 };
    316 
    317 class VerifyDebugInfoJobAction : public VerifyJobAction {
    318   void anchor() override;
    319 public:
    320   VerifyDebugInfoJobAction(Action *Input, types::ID Type);
    321   static bool classof(const Action *A) {
    322     return A->getKind() == VerifyDebugInfoJobClass;
    323   }
    324 };
    325 
    326 class VerifyPCHJobAction : public VerifyJobAction {
    327   void anchor() override;
    328 public:
    329   VerifyPCHJobAction(Action *Input, types::ID Type);
    330   static bool classof(const Action *A) {
    331     return A->getKind() == VerifyPCHJobClass;
    332   }
    333 };
    334 
    335 } // end namespace driver
    336 } // end namespace clang
    337 
    338 #endif
    339