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