clang 22.0.0git
HLSL.cpp
Go to the documentation of this file.
1//===--- HLSL.cpp - HLSL ToolChain Implementations --------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "HLSL.h"
12#include "clang/Driver/Job.h"
13#include "llvm/ADT/StringSwitch.h"
14#include "llvm/TargetParser/Triple.h"
15#include <regex>
16
17using namespace clang::driver;
18using namespace clang::driver::tools;
19using namespace clang::driver::toolchains;
20using namespace clang;
21using namespace llvm::opt;
22using namespace llvm;
23
24namespace {
25
26const unsigned OfflineLibMinor = 0xF;
27
28bool isLegalShaderModel(Triple &T) {
29 if (T.getOS() != Triple::OSType::ShaderModel)
30 return false;
31
32 auto Version = T.getOSVersion();
33 if (Version.getBuild())
34 return false;
35 if (Version.getSubminor())
36 return false;
37
38 auto Kind = T.getEnvironment();
39
40 switch (Kind) {
41 default:
42 return false;
43 case Triple::EnvironmentType::Vertex:
44 case Triple::EnvironmentType::Hull:
45 case Triple::EnvironmentType::Domain:
46 case Triple::EnvironmentType::Geometry:
47 case Triple::EnvironmentType::Pixel:
48 case Triple::EnvironmentType::Compute: {
49 VersionTuple MinVer(4, 0);
50 return MinVer <= Version;
51 } break;
52 case Triple::EnvironmentType::Library: {
53 VersionTuple SM6x(6, OfflineLibMinor);
54 if (Version == SM6x)
55 return true;
56
57 VersionTuple MinVer(6, 3);
58 return MinVer <= Version;
59 } break;
60 case Triple::EnvironmentType::Amplification:
61 case Triple::EnvironmentType::Mesh: {
62 VersionTuple MinVer(6, 5);
63 return MinVer <= Version;
64 } break;
65 case Triple::EnvironmentType::RootSignature:
66 VersionTuple MinVer(1, 0);
67 VersionTuple MaxVer(1, 1);
68 return MinVer <= Version && Version <= MaxVer;
69 }
70 return false;
71}
72
73std::optional<llvm::Triple> tryParseTriple(StringRef Profile) {
74 // [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
76 Profile.split(Parts, "_");
77 if (Parts.size() != 3)
78 return std::nullopt;
79
80 Triple::EnvironmentType Kind =
81 StringSwitch<Triple::EnvironmentType>(Parts[0])
82 .Case("ps", Triple::EnvironmentType::Pixel)
83 .Case("vs", Triple::EnvironmentType::Vertex)
84 .Case("gs", Triple::EnvironmentType::Geometry)
85 .Case("hs", Triple::EnvironmentType::Hull)
86 .Case("ds", Triple::EnvironmentType::Domain)
87 .Case("cs", Triple::EnvironmentType::Compute)
88 .Case("lib", Triple::EnvironmentType::Library)
89 .Case("ms", Triple::EnvironmentType::Mesh)
90 .Case("as", Triple::EnvironmentType::Amplification)
91 .Case("rootsig", Triple::EnvironmentType::RootSignature)
92 .Default(Triple::EnvironmentType::UnknownEnvironment);
93 if (Kind == Triple::EnvironmentType::UnknownEnvironment)
94 return std::nullopt;
95
96 unsigned long long Major = 0;
97 if (llvm::getAsUnsignedInteger(Parts[1], 0, Major))
98 return std::nullopt;
99
100 unsigned long long Minor = 0;
101 if (Parts[2] == "x" && Kind == Triple::EnvironmentType::Library)
102 Minor = OfflineLibMinor;
103 else if (llvm::getAsUnsignedInteger(Parts[2], 0, Minor))
104 return std::nullopt;
105
106 // Determine DXIL version using the minor version number of Shader
107 // Model version specified in target profile. Prior to decoupling DXIL version
108 // numbering from that of Shader Model DXIL version 1.Y corresponds to SM 6.Y.
109 // E.g., dxilv1.Y-unknown-shadermodelX.Y-hull
110 llvm::Triple T;
111 Triple::SubArchType SubArch = llvm::Triple::NoSubArch;
112 switch (Minor) {
113 case 0:
114 SubArch = llvm::Triple::DXILSubArch_v1_0;
115 break;
116 case 1:
117 SubArch = llvm::Triple::DXILSubArch_v1_1;
118 break;
119 case 2:
120 SubArch = llvm::Triple::DXILSubArch_v1_2;
121 break;
122 case 3:
123 SubArch = llvm::Triple::DXILSubArch_v1_3;
124 break;
125 case 4:
126 SubArch = llvm::Triple::DXILSubArch_v1_4;
127 break;
128 case 5:
129 SubArch = llvm::Triple::DXILSubArch_v1_5;
130 break;
131 case 6:
132 SubArch = llvm::Triple::DXILSubArch_v1_6;
133 break;
134 case 7:
135 SubArch = llvm::Triple::DXILSubArch_v1_7;
136 break;
137 case 8:
138 SubArch = llvm::Triple::DXILSubArch_v1_8;
139 break;
140 case 9:
141 SubArch = llvm::Triple::DXILSubArch_v1_9;
142 break;
143 case OfflineLibMinor:
144 // Always consider minor version x as the latest supported DXIL version
145 SubArch = llvm::Triple::LatestDXILSubArch;
146 break;
147 default:
148 // No DXIL Version corresponding to specified Shader Model version found
149 return std::nullopt;
150 }
151 T.setArch(Triple::ArchType::dxil, SubArch);
152 T.setOSName(Triple::getOSTypeName(Triple::OSType::ShaderModel).str() +
153 VersionTuple(Major, Minor).getAsString());
154 T.setEnvironment(Kind);
155
156 return T;
157}
158
159std::optional<std::string> tryParseProfile(StringRef Profile) {
160 std::optional<llvm::Triple> MaybeT = tryParseTriple(Profile);
161 if (MaybeT && isLegalShaderModel(*MaybeT))
162 return MaybeT->getTriple();
163 else
164 return std::nullopt;
165}
166
167bool isLegalValidatorVersion(StringRef ValVersionStr, const Driver &D) {
168 VersionTuple Version;
169 if (Version.tryParse(ValVersionStr) || Version.getBuild() ||
170 Version.getSubminor() || !Version.getMinor()) {
171 D.Diag(diag::err_drv_invalid_format_dxil_validator_version)
172 << ValVersionStr;
173 return false;
174 }
175
176 uint64_t Major = Version.getMajor();
177 uint64_t Minor = *Version.getMinor();
178 if (Major == 0 && Minor != 0) {
179 D.Diag(diag::err_drv_invalid_empty_dxil_validator_version) << ValVersionStr;
180 return false;
181 }
182 VersionTuple MinVer(1, 0);
183 if (Version < MinVer) {
184 D.Diag(diag::err_drv_invalid_range_dxil_validator_version) << ValVersionStr;
185 return false;
186 }
187 return true;
188}
189
190void getSpirvExtOperand(StringRef SpvExtensionArg, raw_ostream &out) {
191 // The extensions that are commented out are supported in DXC, but the SPIR-V
192 // backend does not know about them yet.
193 static const std::vector<StringRef> DxcSupportedExtensions = {
194 "SPV_KHR_16bit_storage", "SPV_KHR_device_group",
195 "SPV_KHR_fragment_shading_rate", "SPV_KHR_multiview",
196 "SPV_KHR_post_depth_coverage", "SPV_KHR_non_semantic_info",
197 "SPV_KHR_shader_draw_parameters", "SPV_KHR_ray_tracing",
198 "SPV_KHR_shader_clock", "SPV_EXT_demote_to_helper_invocation",
199 "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered",
200 "SPV_EXT_fragment_invocation_density",
201 "SPV_EXT_fragment_shader_interlock", "SPV_EXT_mesh_shader",
202 "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer",
203 // "SPV_AMD_shader_early_and_late_fragment_tests",
204 "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type",
205 "SPV_KHR_ray_query", "SPV_EXT_shader_image_int64",
206 "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_physical_storage_buffer",
207 "SPV_KHR_vulkan_memory_model",
208 // "SPV_KHR_compute_shader_derivatives",
209 // "SPV_KHR_maximal_reconvergence",
210 "SPV_KHR_float_controls", "SPV_NV_shader_subgroup_partitioned",
211 // "SPV_KHR_quad_control"
212 };
213
214 if (SpvExtensionArg.starts_with("SPV_")) {
215 out << "+" << SpvExtensionArg;
216 return;
217 }
218
219 if (SpvExtensionArg.compare_insensitive("DXC") == 0) {
220 bool first = true;
221 std::string Operand;
222 for (StringRef E : DxcSupportedExtensions) {
223 if (!first)
224 out << ",";
225 else
226 first = false;
227 out << "+" << E;
228 }
229 return;
230 }
231 out << SpvExtensionArg;
232}
233
234SmallString<1024> getSpirvExtArg(ArrayRef<std::string> SpvExtensionArgs) {
235 if (SpvExtensionArgs.empty()) {
236 return StringRef("-spirv-ext=all");
237 }
238
239 llvm::SmallString<1024> LlvmOption;
240 raw_svector_ostream out(LlvmOption);
241
242 out << "-spirv-ext=";
243 getSpirvExtOperand(SpvExtensionArgs[0], out);
244
245 SpvExtensionArgs = SpvExtensionArgs.slice(1);
246 for (StringRef Extension : SpvExtensionArgs) {
247 out << ",";
248 getSpirvExtOperand(Extension, out);
249 }
250 return LlvmOption;
251}
252
253bool isValidSPIRVExtensionName(const std::string &str) {
254 std::regex pattern("dxc|DXC|khr|KHR|SPV_[a-zA-Z0-9_]+");
255 return std::regex_match(str, pattern);
256}
257
258// SPIRV extension names are of the form `SPV_[a-zA-Z0-9_]+`. We want to
259// disallow obviously invalid names to avoid issues when parsing `spirv-ext`.
260bool checkExtensionArgsAreValid(ArrayRef<std::string> SpvExtensionArgs,
261 const Driver &Driver) {
262 bool AllValid = true;
263 for (auto Extension : SpvExtensionArgs) {
264 if (!isValidSPIRVExtensionName(Extension)) {
265 Driver.Diag(diag::err_drv_invalid_value)
266 << "-fspv-extension" << Extension;
267 AllValid = false;
268 }
269 }
270 return AllValid;
271}
272
273bool isRootSignatureTarget(StringRef Profile) {
274 if (std::optional<llvm::Triple> T = tryParseTriple(Profile))
275 return T->getEnvironment() == Triple::EnvironmentType::RootSignature;
276 return false;
277}
278
279bool isRootSignatureTarget(DerivedArgList &Args) {
280 if (const Arg *A = Args.getLastArg(options::OPT_target_profile))
281 return isRootSignatureTarget(A->getValue());
282 return false;
283}
284
285} // namespace
286
288 const InputInfo &Output,
289 const InputInfoList &Inputs,
290 const ArgList &Args,
291 const char *LinkingOutput) const {
292 std::string DxvPath = getToolChain().GetProgramPath("dxv");
293 assert(DxvPath != "dxv" && "cannot find dxv");
294
295 ArgStringList CmdArgs;
296 assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
297 const InputInfo &Input = Inputs[0];
298 CmdArgs.push_back(Input.getFilename());
299 CmdArgs.push_back("-o");
300 CmdArgs.push_back(Output.getFilename());
301
302 const char *Exec = Args.MakeArgString(DxvPath);
303 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
304 Exec, CmdArgs, Inputs, Input));
305}
306
308 Compilation &C, const JobAction &JA, const InputInfo &Output,
309 const InputInfoList &Inputs, const ArgList &Args,
310 const char *LinkingOutput) const {
311 std::string MSCPath = getToolChain().GetProgramPath("metal-shaderconverter");
312 ArgStringList CmdArgs;
313 assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
314 const InputInfo &Input = Inputs[0];
315 CmdArgs.push_back(Input.getFilename());
316 CmdArgs.push_back("-o");
317 CmdArgs.push_back(Output.getFilename());
318
319 const char *Exec = Args.MakeArgString(MSCPath);
320 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
321 Exec, CmdArgs, Inputs, Input));
322}
323
325 const InputInfo &Output,
326 const InputInfoList &Inputs,
327 const ArgList &Args,
328 const char *LinkingOutput) const {
329
330 std::string ObjcopyPath = getToolChain().GetProgramPath("llvm-objcopy");
331 const char *Exec = Args.MakeArgString(ObjcopyPath);
332
333 ArgStringList CmdArgs;
334 assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
335 const InputInfo &Input = Inputs[0];
336 CmdArgs.push_back(Input.getFilename());
337 CmdArgs.push_back(Output.getFilename());
338
339 if (Args.hasArg(options::OPT_dxc_strip_rootsignature)) {
340 const char *StripRS = Args.MakeArgString("--remove-section=RTS0");
341 CmdArgs.push_back(StripRS);
342 }
343
344 if (Arg *Arg = Args.getLastArg(options::OPT_dxc_Frs)) {
345 const char *Frs =
346 Args.MakeArgString("--extract-section=RTS0=" + Twine(Arg->getValue()));
347 CmdArgs.push_back(Frs);
348 }
349
350 if (const Arg *A = Args.getLastArg(options::OPT_target_profile))
351 if (isRootSignatureTarget(A->getValue())) {
352 const char *Fos = Args.MakeArgString("--only-section=RTS0");
353 CmdArgs.push_back(Fos);
354 }
355
356 assert(CmdArgs.size() > 2 && "Unnecessary invocation of objcopy.");
357
358 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
359 Exec, CmdArgs, Inputs, Input));
360}
361
362/// DirectX Toolchain
363HLSLToolChain::HLSLToolChain(const Driver &D, const llvm::Triple &Triple,
364 const ArgList &Args)
365 : ToolChain(D, Triple, Args) {
366 if (Args.hasArg(options::OPT_dxc_validator_path_EQ))
367 getProgramPaths().push_back(
368 Args.getLastArgValue(options::OPT_dxc_validator_path_EQ).str());
369}
370
372 Action::ActionClass AC) const {
373 switch (AC) {
375 if (!Validator)
376 Validator.reset(new tools::hlsl::Validator(*this));
377 return Validator.get();
379 if (!MetalConverter)
380 MetalConverter.reset(new tools::hlsl::MetalConverter(*this));
381 return MetalConverter.get();
383 if (!LLVMObjcopy)
384 LLVMObjcopy.reset(new tools::hlsl::LLVMObjcopy(*this));
385 return LLVMObjcopy.get();
386 default:
387 return ToolChain::getTool(AC);
388 }
389}
390
391std::optional<std::string>
393 StringRef TargetProfile) {
394 return tryParseProfile(TargetProfile);
395}
396
397DerivedArgList *
398HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
399 Action::OffloadKind DeviceOffloadKind) const {
400 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
401
402 const OptTable &Opts = getDriver().getOpts();
403
404 for (Arg *A : Args) {
405 if (A->getOption().getID() == options::OPT_dxil_validator_version) {
406 StringRef ValVerStr = A->getValue();
407 if (!isLegalValidatorVersion(ValVerStr, getDriver()))
408 continue;
409 }
410 if (A->getOption().getID() == options::OPT_dxc_entrypoint) {
411 DAL->AddSeparateArg(nullptr, Opts.getOption(options::OPT_hlsl_entrypoint),
412 A->getValue());
413 A->claim();
414 continue;
415 }
416 if (A->getOption().getID() == options::OPT_dxc_rootsig_ver) {
417 DAL->AddJoinedArg(nullptr,
418 Opts.getOption(options::OPT_fdx_rootsignature_version),
419 A->getValue());
420 A->claim();
421 continue;
422 }
423 if (A->getOption().getID() == options::OPT_dxc_rootsig_define) {
424 DAL->AddJoinedArg(nullptr,
425 Opts.getOption(options::OPT_fdx_rootsignature_define),
426 A->getValue());
427 A->claim();
428 continue;
429 }
430 if (A->getOption().getID() == options::OPT__SLASH_O) {
431 StringRef OStr = A->getValue();
432 if (OStr == "d") {
433 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_O0));
434 A->claim();
435 continue;
436 } else {
437 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O), OStr);
438 A->claim();
439 continue;
440 }
441 }
442 if (A->getOption().getID() == options::OPT_emit_pristine_llvm) {
443 // Translate -fcgl into -emit-llvm and -disable-llvm-passes.
444 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_emit_llvm));
445 DAL->AddFlagArg(nullptr,
446 Opts.getOption(options::OPT_disable_llvm_passes));
447 A->claim();
448 continue;
449 }
450 if (A->getOption().getID() == options::OPT_dxc_hlsl_version) {
451 // Translate -HV into -std for llvm
452 // depending on the value given
453 LangStandard::Kind LangStd = LangStandard::getHLSLLangKind(A->getValue());
454 if (LangStd != LangStandard::lang_unspecified) {
456 DAL->AddSeparateArg(nullptr, Opts.getOption(options::OPT_std_EQ),
457 l.getName());
458 } else {
459 getDriver().Diag(diag::err_drv_invalid_value) << "HV" << A->getValue();
460 }
461
462 A->claim();
463 continue;
464 }
465 if (A->getOption().getID() == options::OPT_dxc_gis) {
466 // Translate -Gis into -ffp_model_EQ=strict
467 DAL->AddSeparateArg(nullptr, Opts.getOption(options::OPT_ffp_model_EQ),
468 "strict");
469 A->claim();
470 continue;
471 }
472 if (A->getOption().getID() == options::OPT_fvk_use_dx_layout) {
473 // This is the only implemented layout so far.
474 A->claim();
475 continue;
476 }
477
478 if (A->getOption().getID() == options::OPT_fvk_use_scalar_layout) {
479 getDriver().Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
480 A->claim();
481 continue;
482 }
483
484 if (A->getOption().getID() == options::OPT_fvk_use_gl_layout) {
485 getDriver().Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
486 A->claim();
487 continue;
488 }
489
490 DAL->append(A);
491 }
492
493 if (getArch() == llvm::Triple::spirv) {
494 std::vector<std::string> SpvExtensionArgs =
495 Args.getAllArgValues(options::OPT_fspv_extension_EQ);
496 if (checkExtensionArgsAreValid(SpvExtensionArgs, getDriver())) {
497 SmallString<1024> LlvmOption = getSpirvExtArg(SpvExtensionArgs);
498 DAL->AddSeparateArg(nullptr, Opts.getOption(options::OPT_mllvm),
499 LlvmOption);
500 }
501 Args.claimAllArgs(options::OPT_fspv_extension_EQ);
502 }
503
504 if (!DAL->hasArg(options::OPT_O_Group)) {
505 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O), "3");
506 }
507
508 return DAL;
509}
510
511bool HLSLToolChain::requiresValidation(DerivedArgList &Args) const {
512 if (!Args.hasArg(options::OPT_dxc_Fo))
513 return false;
514
515 if (Args.getLastArg(options::OPT_dxc_disable_validation))
516 return false;
517
518 std::string DxvPath = GetProgramPath("dxv");
519 if (DxvPath != "dxv")
520 return true;
521
522 getDriver().Diag(diag::warn_drv_dxc_missing_dxv);
523 return false;
524}
525
526bool HLSLToolChain::requiresBinaryTranslation(DerivedArgList &Args) const {
527 return Args.hasArg(options::OPT_metal) && Args.hasArg(options::OPT_dxc_Fo);
528}
529
530bool HLSLToolChain::requiresObjcopy(DerivedArgList &Args) const {
531 return Args.hasArg(options::OPT_dxc_Fo) &&
532 (Args.hasArg(options::OPT_dxc_strip_rootsignature) ||
533 Args.hasArg(options::OPT_dxc_Frs) || isRootSignatureTarget(Args));
534}
535
536bool HLSLToolChain::isLastJob(DerivedArgList &Args,
537 Action::ActionClass AC) const {
538 // Note: we check in the reverse order of execution
540 return AC == Action::Action::BinaryTranslatorJobClass;
541 if (requiresValidation(Args))
542 return AC == Action::Action::BinaryAnalyzeJobClass;
543 if (requiresObjcopy(Args))
544 return AC == Action::Action::ObjcopyJobClass;
545
546 // No translation, validation, or objcopy are required, so this action must
547 // output to the result file.
548 return true;
549}
Compilation - A set of tasks to perform for a single driver invocation.
Definition Compilation.h:45
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition Driver.h:99
DiagnosticBuilder Diag(unsigned DiagID) const
Definition Driver.h:169
const llvm::opt::OptTable & getOpts() const
Definition Driver.h:428
InputInfo - Wrapper for information about an input source.
Definition InputInfo.h:22
const char * getFilename() const
Definition InputInfo.h:83
llvm::Triple::ArchType getArch() const
Definition ToolChain.h:269
const Driver & getDriver() const
Definition ToolChain.h:253
ToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args)
Definition ToolChain.cpp:89
path_list & getProgramPaths()
Definition ToolChain.h:298
std::string GetProgramPath(const char *Name) const
virtual Tool * getTool(Action::ActionClass AC) const
Tool - Information on a specific compilation tool.
Definition Tool.h:32
const ToolChain & getToolChain() const
Definition Tool.h:52
bool requiresBinaryTranslation(llvm::opt::DerivedArgList &Args) const
Definition HLSL.cpp:526
bool isLastJob(llvm::opt::DerivedArgList &Args, Action::ActionClass AC) const
If we are targeting DXIL then the last job should output the DXContainer to the specified output file...
Definition HLSL.cpp:536
Tool * getTool(Action::ActionClass AC) const override
Definition HLSL.cpp:371
HLSLToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
DirectX Toolchain.
Definition HLSL.cpp:363
bool requiresObjcopy(llvm::opt::DerivedArgList &Args) const
Definition HLSL.cpp:530
llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, Action::OffloadKind DeviceOffloadKind) const override
TranslateArgs - Create a new derived argument list for any argument translations this ToolChain may w...
Definition HLSL.cpp:398
bool requiresValidation(llvm::opt::DerivedArgList &Args) const
Definition HLSL.cpp:511
static std::optional< std::string > parseTargetProfile(StringRef TargetProfile)
Definition HLSL.cpp:392
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition HLSL.cpp:324
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition HLSL.cpp:307
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition HLSL.cpp:287
SmallVector< InputInfo, 4 > InputInfoList
Definition Driver.h:50
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
llvm::StringRef getAsString(SyncScope S)
Definition SyncScope.h:60
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
LangStandard - Information about the properties of a particular language standard.
static Kind getHLSLLangKind(StringRef Name)
static const LangStandard & getLangStandardForKind(Kind K)
const char * getName() const
getName - Get the name of this standard.
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.
Definition Job.h:78