1*0b57cec5SDimitry Andric //===- Action.cpp - Abstract compilation steps ----------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "clang/Driver/Action.h" 10*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 11*0b57cec5SDimitry Andric #include <cassert> 12*0b57cec5SDimitry Andric #include <string> 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric using namespace clang; 15*0b57cec5SDimitry Andric using namespace driver; 16*0b57cec5SDimitry Andric using namespace llvm::opt; 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric Action::~Action() = default; 19*0b57cec5SDimitry Andric 20*0b57cec5SDimitry Andric const char *Action::getClassName(ActionClass AC) { 21*0b57cec5SDimitry Andric switch (AC) { 22*0b57cec5SDimitry Andric case InputClass: return "input"; 23*0b57cec5SDimitry Andric case BindArchClass: return "bind-arch"; 24*0b57cec5SDimitry Andric case OffloadClass: 25*0b57cec5SDimitry Andric return "offload"; 26*0b57cec5SDimitry Andric case PreprocessJobClass: return "preprocessor"; 27*0b57cec5SDimitry Andric case PrecompileJobClass: return "precompiler"; 28*0b57cec5SDimitry Andric case HeaderModulePrecompileJobClass: return "header-module-precompiler"; 29*0b57cec5SDimitry Andric case AnalyzeJobClass: return "analyzer"; 30*0b57cec5SDimitry Andric case MigrateJobClass: return "migrator"; 31*0b57cec5SDimitry Andric case CompileJobClass: return "compiler"; 32*0b57cec5SDimitry Andric case BackendJobClass: return "backend"; 33*0b57cec5SDimitry Andric case AssembleJobClass: return "assembler"; 34*0b57cec5SDimitry Andric case LinkJobClass: return "linker"; 35*0b57cec5SDimitry Andric case LipoJobClass: return "lipo"; 36*0b57cec5SDimitry Andric case DsymutilJobClass: return "dsymutil"; 37*0b57cec5SDimitry Andric case VerifyDebugInfoJobClass: return "verify-debug-info"; 38*0b57cec5SDimitry Andric case VerifyPCHJobClass: return "verify-pch"; 39*0b57cec5SDimitry Andric case OffloadBundlingJobClass: 40*0b57cec5SDimitry Andric return "clang-offload-bundler"; 41*0b57cec5SDimitry Andric case OffloadUnbundlingJobClass: 42*0b57cec5SDimitry Andric return "clang-offload-unbundler"; 43*0b57cec5SDimitry Andric } 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric llvm_unreachable("invalid class"); 46*0b57cec5SDimitry Andric } 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch) { 49*0b57cec5SDimitry Andric // Offload action set its own kinds on their dependences. 50*0b57cec5SDimitry Andric if (Kind == OffloadClass) 51*0b57cec5SDimitry Andric return; 52*0b57cec5SDimitry Andric // Unbundling actions use the host kinds. 53*0b57cec5SDimitry Andric if (Kind == OffloadUnbundlingJobClass) 54*0b57cec5SDimitry Andric return; 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric assert((OffloadingDeviceKind == OKind || OffloadingDeviceKind == OFK_None) && 57*0b57cec5SDimitry Andric "Setting device kind to a different device??"); 58*0b57cec5SDimitry Andric assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??"); 59*0b57cec5SDimitry Andric OffloadingDeviceKind = OKind; 60*0b57cec5SDimitry Andric OffloadingArch = OArch; 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric for (auto *A : Inputs) 63*0b57cec5SDimitry Andric A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch); 64*0b57cec5SDimitry Andric } 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric void Action::propagateHostOffloadInfo(unsigned OKinds, const char *OArch) { 67*0b57cec5SDimitry Andric // Offload action set its own kinds on their dependences. 68*0b57cec5SDimitry Andric if (Kind == OffloadClass) 69*0b57cec5SDimitry Andric return; 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric assert(OffloadingDeviceKind == OFK_None && 72*0b57cec5SDimitry Andric "Setting a host kind in a device action."); 73*0b57cec5SDimitry Andric ActiveOffloadKindMask |= OKinds; 74*0b57cec5SDimitry Andric OffloadingArch = OArch; 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andric for (auto *A : Inputs) 77*0b57cec5SDimitry Andric A->propagateHostOffloadInfo(ActiveOffloadKindMask, OArch); 78*0b57cec5SDimitry Andric } 79*0b57cec5SDimitry Andric 80*0b57cec5SDimitry Andric void Action::propagateOffloadInfo(const Action *A) { 81*0b57cec5SDimitry Andric if (unsigned HK = A->getOffloadingHostActiveKinds()) 82*0b57cec5SDimitry Andric propagateHostOffloadInfo(HK, A->getOffloadingArch()); 83*0b57cec5SDimitry Andric else 84*0b57cec5SDimitry Andric propagateDeviceOffloadInfo(A->getOffloadingDeviceKind(), 85*0b57cec5SDimitry Andric A->getOffloadingArch()); 86*0b57cec5SDimitry Andric } 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric std::string Action::getOffloadingKindPrefix() const { 89*0b57cec5SDimitry Andric switch (OffloadingDeviceKind) { 90*0b57cec5SDimitry Andric case OFK_None: 91*0b57cec5SDimitry Andric break; 92*0b57cec5SDimitry Andric case OFK_Host: 93*0b57cec5SDimitry Andric llvm_unreachable("Host kind is not an offloading device kind."); 94*0b57cec5SDimitry Andric break; 95*0b57cec5SDimitry Andric case OFK_Cuda: 96*0b57cec5SDimitry Andric return "device-cuda"; 97*0b57cec5SDimitry Andric case OFK_OpenMP: 98*0b57cec5SDimitry Andric return "device-openmp"; 99*0b57cec5SDimitry Andric case OFK_HIP: 100*0b57cec5SDimitry Andric return "device-hip"; 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric // TODO: Add other programming models here. 103*0b57cec5SDimitry Andric } 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric if (!ActiveOffloadKindMask) 106*0b57cec5SDimitry Andric return {}; 107*0b57cec5SDimitry Andric 108*0b57cec5SDimitry Andric std::string Res("host"); 109*0b57cec5SDimitry Andric assert(!((ActiveOffloadKindMask & OFK_Cuda) && 110*0b57cec5SDimitry Andric (ActiveOffloadKindMask & OFK_HIP)) && 111*0b57cec5SDimitry Andric "Cannot offload CUDA and HIP at the same time"); 112*0b57cec5SDimitry Andric if (ActiveOffloadKindMask & OFK_Cuda) 113*0b57cec5SDimitry Andric Res += "-cuda"; 114*0b57cec5SDimitry Andric if (ActiveOffloadKindMask & OFK_HIP) 115*0b57cec5SDimitry Andric Res += "-hip"; 116*0b57cec5SDimitry Andric if (ActiveOffloadKindMask & OFK_OpenMP) 117*0b57cec5SDimitry Andric Res += "-openmp"; 118*0b57cec5SDimitry Andric 119*0b57cec5SDimitry Andric // TODO: Add other programming models here. 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric return Res; 122*0b57cec5SDimitry Andric } 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric /// Return a string that can be used as prefix in order to generate unique files 125*0b57cec5SDimitry Andric /// for each offloading kind. 126*0b57cec5SDimitry Andric std::string 127*0b57cec5SDimitry Andric Action::GetOffloadingFileNamePrefix(OffloadKind Kind, 128*0b57cec5SDimitry Andric StringRef NormalizedTriple, 129*0b57cec5SDimitry Andric bool CreatePrefixForHost) { 130*0b57cec5SDimitry Andric // Don't generate prefix for host actions unless required. 131*0b57cec5SDimitry Andric if (!CreatePrefixForHost && (Kind == OFK_None || Kind == OFK_Host)) 132*0b57cec5SDimitry Andric return {}; 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric std::string Res("-"); 135*0b57cec5SDimitry Andric Res += GetOffloadKindName(Kind); 136*0b57cec5SDimitry Andric Res += "-"; 137*0b57cec5SDimitry Andric Res += NormalizedTriple; 138*0b57cec5SDimitry Andric return Res; 139*0b57cec5SDimitry Andric } 140*0b57cec5SDimitry Andric 141*0b57cec5SDimitry Andric /// Return a string with the offload kind name. If that is not defined, we 142*0b57cec5SDimitry Andric /// assume 'host'. 143*0b57cec5SDimitry Andric StringRef Action::GetOffloadKindName(OffloadKind Kind) { 144*0b57cec5SDimitry Andric switch (Kind) { 145*0b57cec5SDimitry Andric case OFK_None: 146*0b57cec5SDimitry Andric case OFK_Host: 147*0b57cec5SDimitry Andric return "host"; 148*0b57cec5SDimitry Andric case OFK_Cuda: 149*0b57cec5SDimitry Andric return "cuda"; 150*0b57cec5SDimitry Andric case OFK_OpenMP: 151*0b57cec5SDimitry Andric return "openmp"; 152*0b57cec5SDimitry Andric case OFK_HIP: 153*0b57cec5SDimitry Andric return "hip"; 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andric // TODO: Add other programming models here. 156*0b57cec5SDimitry Andric } 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric llvm_unreachable("invalid offload kind"); 159*0b57cec5SDimitry Andric } 160*0b57cec5SDimitry Andric 161*0b57cec5SDimitry Andric void InputAction::anchor() {} 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric InputAction::InputAction(const Arg &_Input, types::ID _Type) 164*0b57cec5SDimitry Andric : Action(InputClass, _Type), Input(_Input) {} 165*0b57cec5SDimitry Andric 166*0b57cec5SDimitry Andric void BindArchAction::anchor() {} 167*0b57cec5SDimitry Andric 168*0b57cec5SDimitry Andric BindArchAction::BindArchAction(Action *Input, StringRef ArchName) 169*0b57cec5SDimitry Andric : Action(BindArchClass, Input), ArchName(ArchName) {} 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andric void OffloadAction::anchor() {} 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andric OffloadAction::OffloadAction(const HostDependence &HDep) 174*0b57cec5SDimitry Andric : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()) { 175*0b57cec5SDimitry Andric OffloadingArch = HDep.getBoundArch(); 176*0b57cec5SDimitry Andric ActiveOffloadKindMask = HDep.getOffloadKinds(); 177*0b57cec5SDimitry Andric HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(), 178*0b57cec5SDimitry Andric HDep.getBoundArch()); 179*0b57cec5SDimitry Andric } 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric OffloadAction::OffloadAction(const DeviceDependences &DDeps, types::ID Ty) 182*0b57cec5SDimitry Andric : Action(OffloadClass, DDeps.getActions(), Ty), 183*0b57cec5SDimitry Andric DevToolChains(DDeps.getToolChains()) { 184*0b57cec5SDimitry Andric auto &OKinds = DDeps.getOffloadKinds(); 185*0b57cec5SDimitry Andric auto &BArchs = DDeps.getBoundArchs(); 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric // If all inputs agree on the same kind, use it also for this action. 188*0b57cec5SDimitry Andric if (llvm::all_of(OKinds, [&](OffloadKind K) { return K == OKinds.front(); })) 189*0b57cec5SDimitry Andric OffloadingDeviceKind = OKinds.front(); 190*0b57cec5SDimitry Andric 191*0b57cec5SDimitry Andric // If we have a single dependency, inherit the architecture from it. 192*0b57cec5SDimitry Andric if (OKinds.size() == 1) 193*0b57cec5SDimitry Andric OffloadingArch = BArchs.front(); 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric // Propagate info to the dependencies. 196*0b57cec5SDimitry Andric for (unsigned i = 0, e = getInputs().size(); i != e; ++i) 197*0b57cec5SDimitry Andric getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]); 198*0b57cec5SDimitry Andric } 199*0b57cec5SDimitry Andric 200*0b57cec5SDimitry Andric OffloadAction::OffloadAction(const HostDependence &HDep, 201*0b57cec5SDimitry Andric const DeviceDependences &DDeps) 202*0b57cec5SDimitry Andric : Action(OffloadClass, HDep.getAction()), HostTC(HDep.getToolChain()), 203*0b57cec5SDimitry Andric DevToolChains(DDeps.getToolChains()) { 204*0b57cec5SDimitry Andric // We use the kinds of the host dependence for this action. 205*0b57cec5SDimitry Andric OffloadingArch = HDep.getBoundArch(); 206*0b57cec5SDimitry Andric ActiveOffloadKindMask = HDep.getOffloadKinds(); 207*0b57cec5SDimitry Andric HDep.getAction()->propagateHostOffloadInfo(HDep.getOffloadKinds(), 208*0b57cec5SDimitry Andric HDep.getBoundArch()); 209*0b57cec5SDimitry Andric 210*0b57cec5SDimitry Andric // Add device inputs and propagate info to the device actions. Do work only if 211*0b57cec5SDimitry Andric // we have dependencies. 212*0b57cec5SDimitry Andric for (unsigned i = 0, e = DDeps.getActions().size(); i != e; ++i) 213*0b57cec5SDimitry Andric if (auto *A = DDeps.getActions()[i]) { 214*0b57cec5SDimitry Andric getInputs().push_back(A); 215*0b57cec5SDimitry Andric A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i], 216*0b57cec5SDimitry Andric DDeps.getBoundArchs()[i]); 217*0b57cec5SDimitry Andric } 218*0b57cec5SDimitry Andric } 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric void OffloadAction::doOnHostDependence(const OffloadActionWorkTy &Work) const { 221*0b57cec5SDimitry Andric if (!HostTC) 222*0b57cec5SDimitry Andric return; 223*0b57cec5SDimitry Andric assert(!getInputs().empty() && "No dependencies for offload action??"); 224*0b57cec5SDimitry Andric auto *A = getInputs().front(); 225*0b57cec5SDimitry Andric Work(A, HostTC, A->getOffloadingArch()); 226*0b57cec5SDimitry Andric } 227*0b57cec5SDimitry Andric 228*0b57cec5SDimitry Andric void OffloadAction::doOnEachDeviceDependence( 229*0b57cec5SDimitry Andric const OffloadActionWorkTy &Work) const { 230*0b57cec5SDimitry Andric auto I = getInputs().begin(); 231*0b57cec5SDimitry Andric auto E = getInputs().end(); 232*0b57cec5SDimitry Andric if (I == E) 233*0b57cec5SDimitry Andric return; 234*0b57cec5SDimitry Andric 235*0b57cec5SDimitry Andric // We expect to have the same number of input dependences and device tool 236*0b57cec5SDimitry Andric // chains, except if we also have a host dependence. In that case we have one 237*0b57cec5SDimitry Andric // more dependence than we have device tool chains. 238*0b57cec5SDimitry Andric assert(getInputs().size() == DevToolChains.size() + (HostTC ? 1 : 0) && 239*0b57cec5SDimitry Andric "Sizes of action dependences and toolchains are not consistent!"); 240*0b57cec5SDimitry Andric 241*0b57cec5SDimitry Andric // Skip host action 242*0b57cec5SDimitry Andric if (HostTC) 243*0b57cec5SDimitry Andric ++I; 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andric auto TI = DevToolChains.begin(); 246*0b57cec5SDimitry Andric for (; I != E; ++I, ++TI) 247*0b57cec5SDimitry Andric Work(*I, *TI, (*I)->getOffloadingArch()); 248*0b57cec5SDimitry Andric } 249*0b57cec5SDimitry Andric 250*0b57cec5SDimitry Andric void OffloadAction::doOnEachDependence(const OffloadActionWorkTy &Work) const { 251*0b57cec5SDimitry Andric doOnHostDependence(Work); 252*0b57cec5SDimitry Andric doOnEachDeviceDependence(Work); 253*0b57cec5SDimitry Andric } 254*0b57cec5SDimitry Andric 255*0b57cec5SDimitry Andric void OffloadAction::doOnEachDependence(bool IsHostDependence, 256*0b57cec5SDimitry Andric const OffloadActionWorkTy &Work) const { 257*0b57cec5SDimitry Andric if (IsHostDependence) 258*0b57cec5SDimitry Andric doOnHostDependence(Work); 259*0b57cec5SDimitry Andric else 260*0b57cec5SDimitry Andric doOnEachDeviceDependence(Work); 261*0b57cec5SDimitry Andric } 262*0b57cec5SDimitry Andric 263*0b57cec5SDimitry Andric bool OffloadAction::hasHostDependence() const { return HostTC != nullptr; } 264*0b57cec5SDimitry Andric 265*0b57cec5SDimitry Andric Action *OffloadAction::getHostDependence() const { 266*0b57cec5SDimitry Andric assert(hasHostDependence() && "Host dependence does not exist!"); 267*0b57cec5SDimitry Andric assert(!getInputs().empty() && "No dependencies for offload action??"); 268*0b57cec5SDimitry Andric return HostTC ? getInputs().front() : nullptr; 269*0b57cec5SDimitry Andric } 270*0b57cec5SDimitry Andric 271*0b57cec5SDimitry Andric bool OffloadAction::hasSingleDeviceDependence( 272*0b57cec5SDimitry Andric bool DoNotConsiderHostActions) const { 273*0b57cec5SDimitry Andric if (DoNotConsiderHostActions) 274*0b57cec5SDimitry Andric return getInputs().size() == (HostTC ? 2 : 1); 275*0b57cec5SDimitry Andric return !HostTC && getInputs().size() == 1; 276*0b57cec5SDimitry Andric } 277*0b57cec5SDimitry Andric 278*0b57cec5SDimitry Andric Action * 279*0b57cec5SDimitry Andric OffloadAction::getSingleDeviceDependence(bool DoNotConsiderHostActions) const { 280*0b57cec5SDimitry Andric assert(hasSingleDeviceDependence(DoNotConsiderHostActions) && 281*0b57cec5SDimitry Andric "Single device dependence does not exist!"); 282*0b57cec5SDimitry Andric // The previous assert ensures the number of entries in getInputs() is 283*0b57cec5SDimitry Andric // consistent with what we are doing here. 284*0b57cec5SDimitry Andric return HostTC ? getInputs()[1] : getInputs().front(); 285*0b57cec5SDimitry Andric } 286*0b57cec5SDimitry Andric 287*0b57cec5SDimitry Andric void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC, 288*0b57cec5SDimitry Andric const char *BoundArch, 289*0b57cec5SDimitry Andric OffloadKind OKind) { 290*0b57cec5SDimitry Andric DeviceActions.push_back(&A); 291*0b57cec5SDimitry Andric DeviceToolChains.push_back(&TC); 292*0b57cec5SDimitry Andric DeviceBoundArchs.push_back(BoundArch); 293*0b57cec5SDimitry Andric DeviceOffloadKinds.push_back(OKind); 294*0b57cec5SDimitry Andric } 295*0b57cec5SDimitry Andric 296*0b57cec5SDimitry Andric OffloadAction::HostDependence::HostDependence(Action &A, const ToolChain &TC, 297*0b57cec5SDimitry Andric const char *BoundArch, 298*0b57cec5SDimitry Andric const DeviceDependences &DDeps) 299*0b57cec5SDimitry Andric : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch) { 300*0b57cec5SDimitry Andric for (auto K : DDeps.getOffloadKinds()) 301*0b57cec5SDimitry Andric HostOffloadKinds |= K; 302*0b57cec5SDimitry Andric } 303*0b57cec5SDimitry Andric 304*0b57cec5SDimitry Andric void JobAction::anchor() {} 305*0b57cec5SDimitry Andric 306*0b57cec5SDimitry Andric JobAction::JobAction(ActionClass Kind, Action *Input, types::ID Type) 307*0b57cec5SDimitry Andric : Action(Kind, Input, Type) {} 308*0b57cec5SDimitry Andric 309*0b57cec5SDimitry Andric JobAction::JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type) 310*0b57cec5SDimitry Andric : Action(Kind, Inputs, Type) {} 311*0b57cec5SDimitry Andric 312*0b57cec5SDimitry Andric void PreprocessJobAction::anchor() {} 313*0b57cec5SDimitry Andric 314*0b57cec5SDimitry Andric PreprocessJobAction::PreprocessJobAction(Action *Input, types::ID OutputType) 315*0b57cec5SDimitry Andric : JobAction(PreprocessJobClass, Input, OutputType) {} 316*0b57cec5SDimitry Andric 317*0b57cec5SDimitry Andric void PrecompileJobAction::anchor() {} 318*0b57cec5SDimitry Andric 319*0b57cec5SDimitry Andric PrecompileJobAction::PrecompileJobAction(Action *Input, types::ID OutputType) 320*0b57cec5SDimitry Andric : JobAction(PrecompileJobClass, Input, OutputType) {} 321*0b57cec5SDimitry Andric 322*0b57cec5SDimitry Andric PrecompileJobAction::PrecompileJobAction(ActionClass Kind, Action *Input, 323*0b57cec5SDimitry Andric types::ID OutputType) 324*0b57cec5SDimitry Andric : JobAction(Kind, Input, OutputType) { 325*0b57cec5SDimitry Andric assert(isa<PrecompileJobAction>((Action*)this) && "invalid action kind"); 326*0b57cec5SDimitry Andric } 327*0b57cec5SDimitry Andric 328*0b57cec5SDimitry Andric void HeaderModulePrecompileJobAction::anchor() {} 329*0b57cec5SDimitry Andric 330*0b57cec5SDimitry Andric HeaderModulePrecompileJobAction::HeaderModulePrecompileJobAction( 331*0b57cec5SDimitry Andric Action *Input, types::ID OutputType, const char *ModuleName) 332*0b57cec5SDimitry Andric : PrecompileJobAction(HeaderModulePrecompileJobClass, Input, OutputType), 333*0b57cec5SDimitry Andric ModuleName(ModuleName) {} 334*0b57cec5SDimitry Andric 335*0b57cec5SDimitry Andric void AnalyzeJobAction::anchor() {} 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType) 338*0b57cec5SDimitry Andric : JobAction(AnalyzeJobClass, Input, OutputType) {} 339*0b57cec5SDimitry Andric 340*0b57cec5SDimitry Andric void MigrateJobAction::anchor() {} 341*0b57cec5SDimitry Andric 342*0b57cec5SDimitry Andric MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType) 343*0b57cec5SDimitry Andric : JobAction(MigrateJobClass, Input, OutputType) {} 344*0b57cec5SDimitry Andric 345*0b57cec5SDimitry Andric void CompileJobAction::anchor() {} 346*0b57cec5SDimitry Andric 347*0b57cec5SDimitry Andric CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType) 348*0b57cec5SDimitry Andric : JobAction(CompileJobClass, Input, OutputType) {} 349*0b57cec5SDimitry Andric 350*0b57cec5SDimitry Andric void BackendJobAction::anchor() {} 351*0b57cec5SDimitry Andric 352*0b57cec5SDimitry Andric BackendJobAction::BackendJobAction(Action *Input, types::ID OutputType) 353*0b57cec5SDimitry Andric : JobAction(BackendJobClass, Input, OutputType) {} 354*0b57cec5SDimitry Andric 355*0b57cec5SDimitry Andric void AssembleJobAction::anchor() {} 356*0b57cec5SDimitry Andric 357*0b57cec5SDimitry Andric AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType) 358*0b57cec5SDimitry Andric : JobAction(AssembleJobClass, Input, OutputType) {} 359*0b57cec5SDimitry Andric 360*0b57cec5SDimitry Andric void LinkJobAction::anchor() {} 361*0b57cec5SDimitry Andric 362*0b57cec5SDimitry Andric LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type) 363*0b57cec5SDimitry Andric : JobAction(LinkJobClass, Inputs, Type) {} 364*0b57cec5SDimitry Andric 365*0b57cec5SDimitry Andric void LipoJobAction::anchor() {} 366*0b57cec5SDimitry Andric 367*0b57cec5SDimitry Andric LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type) 368*0b57cec5SDimitry Andric : JobAction(LipoJobClass, Inputs, Type) {} 369*0b57cec5SDimitry Andric 370*0b57cec5SDimitry Andric void DsymutilJobAction::anchor() {} 371*0b57cec5SDimitry Andric 372*0b57cec5SDimitry Andric DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type) 373*0b57cec5SDimitry Andric : JobAction(DsymutilJobClass, Inputs, Type) {} 374*0b57cec5SDimitry Andric 375*0b57cec5SDimitry Andric void VerifyJobAction::anchor() {} 376*0b57cec5SDimitry Andric 377*0b57cec5SDimitry Andric VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input, 378*0b57cec5SDimitry Andric types::ID Type) 379*0b57cec5SDimitry Andric : JobAction(Kind, Input, Type) { 380*0b57cec5SDimitry Andric assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) && 381*0b57cec5SDimitry Andric "ActionClass is not a valid VerifyJobAction"); 382*0b57cec5SDimitry Andric } 383*0b57cec5SDimitry Andric 384*0b57cec5SDimitry Andric void VerifyDebugInfoJobAction::anchor() {} 385*0b57cec5SDimitry Andric 386*0b57cec5SDimitry Andric VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input, 387*0b57cec5SDimitry Andric types::ID Type) 388*0b57cec5SDimitry Andric : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {} 389*0b57cec5SDimitry Andric 390*0b57cec5SDimitry Andric void VerifyPCHJobAction::anchor() {} 391*0b57cec5SDimitry Andric 392*0b57cec5SDimitry Andric VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type) 393*0b57cec5SDimitry Andric : VerifyJobAction(VerifyPCHJobClass, Input, Type) {} 394*0b57cec5SDimitry Andric 395*0b57cec5SDimitry Andric void OffloadBundlingJobAction::anchor() {} 396*0b57cec5SDimitry Andric 397*0b57cec5SDimitry Andric OffloadBundlingJobAction::OffloadBundlingJobAction(ActionList &Inputs) 398*0b57cec5SDimitry Andric : JobAction(OffloadBundlingJobClass, Inputs, Inputs.back()->getType()) {} 399*0b57cec5SDimitry Andric 400*0b57cec5SDimitry Andric void OffloadUnbundlingJobAction::anchor() {} 401*0b57cec5SDimitry Andric 402*0b57cec5SDimitry Andric OffloadUnbundlingJobAction::OffloadUnbundlingJobAction(Action *Input) 403*0b57cec5SDimitry Andric : JobAction(OffloadUnbundlingJobClass, Input, Input->getType()) {} 404