xref: /openbsd-src/gnu/llvm/clang/lib/Driver/Action.cpp (revision e5dd70708596ae51455a0ffa086a00c5b29f8583)
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