xref: /freebsd/contrib/llvm-project/clang/lib/Driver/Action.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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