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