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: Action(ActionClass Kind,types::ID Type)98 Action(ActionClass Kind, types::ID Type) : Action(Kind, ActionList(), Type) {} Action(ActionClass Kind,Action * Input,types::ID Type)99 Action(ActionClass Kind, Action *Input, types::ID Type) 100 : Action(Kind, ActionList({Input}), Type) {} Action(ActionClass Kind,Action * Input)101 Action(ActionClass Kind, Action *Input) 102 : Action(Kind, ActionList({Input}), Input->getType()) {} Action(ActionClass Kind,const ActionList & Inputs,types::ID Type)103 Action(ActionClass Kind, const ActionList &Inputs, types::ID Type) 104 : Kind(Kind), Type(Type), Inputs(Inputs) {} 105 106 public: 107 virtual ~Action(); 108 getClassName()109 const char *getClassName() const { return Action::getClassName(getKind()); } 110 getKind()111 ActionClass getKind() const { return Kind; } getType()112 types::ID getType() const { return Type; } 113 getInputs()114 ActionList &getInputs() { return Inputs; } getInputs()115 const ActionList &getInputs() const { return Inputs; } 116 size()117 size_type size() const { return Inputs.size(); } 118 input_begin()119 input_iterator input_begin() { return Inputs.begin(); } input_end()120 input_iterator input_end() { return Inputs.end(); } inputs()121 input_range inputs() { return input_range(input_begin(), input_end()); } input_begin()122 input_const_iterator input_begin() const { return Inputs.begin(); } input_end()123 input_const_iterator input_end() const { return Inputs.end(); } inputs()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 getInputArg()136 const llvm::opt::Arg &getInputArg() const { return Input; } 137 classof(const Action * A)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 getArchName()152 const char *getArchName() const { return ArchName; } 153 classof(const Action * A)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. getGpuArch()173 CudaArch getGpuArch() const { return GpuArch; } 174 isAtTopLevel()175 bool isAtTopLevel() const { return AtTopLevel; } 176 classof(const Action * A)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 getDeviceActions()189 const ActionList &getDeviceActions() const { return DeviceActions; } 190 classof(const Action * A)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: classof(const Action * A)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 classof(const Action * A)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 classof(const Action * A)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 classof(const Action * A)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 classof(const Action * A)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 classof(const Action * A)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 classof(const Action * A)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 classof(const Action * A)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 classof(const Action * A)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 classof(const Action * A)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 classof(const Action * A)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); classof(const Action * A)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); classof(const Action * A)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); classof(const Action * A)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