55 #include "clang/Config/config.h"
67 #include "llvm/ADT/ArrayRef.h"
68 #include "llvm/ADT/MapVector.h"
69 #include "llvm/ADT/STLExtras.h"
70 #include "llvm/ADT/StringExtras.h"
71 #include "llvm/ADT/StringRef.h"
72 #include "llvm/ADT/StringSet.h"
73 #include "llvm/ADT/StringSwitch.h"
74 #include "llvm/BinaryFormat/Magic.h"
75 #include "llvm/Config/llvm-config.h"
76 #include "llvm/MC/TargetRegistry.h"
77 #include "llvm/Option/Arg.h"
78 #include "llvm/Option/ArgList.h"
79 #include "llvm/Option/OptSpecifier.h"
80 #include "llvm/Option/OptTable.h"
81 #include "llvm/Option/Option.h"
82 #include "llvm/SYCLLowerIR/DeviceConfigFile.hpp"
83 #include "llvm/Support/CommandLine.h"
84 #include "llvm/Support/ErrorHandling.h"
85 #include "llvm/Support/ExitCodes.h"
86 #include "llvm/Support/FileSystem.h"
87 #include "llvm/Support/FileUtilities.h"
88 #include "llvm/Support/FormatVariadic.h"
89 #include "llvm/Support/LineIterator.h"
90 #include "llvm/Support/MD5.h"
91 #include "llvm/Support/Path.h"
92 #include "llvm/Support/PrettyStackTrace.h"
93 #include "llvm/Support/Process.h"
94 #include "llvm/Support/Program.h"
95 #include "llvm/Support/Regex.h"
96 #include "llvm/Support/StringSaver.h"
97 #include "llvm/Support/VirtualFileSystem.h"
98 #include "llvm/Support/raw_ostream.h"
99 #include "llvm/TargetParser/Host.h"
100 #include "llvm/TargetParser/RISCVISAInfo.h"
114 using namespace clang;
118 const ArgList &Args) {
119 auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
123 switch (OffloadTargets.size()) {
125 D.
Diag(diag::err_drv_only_one_offload_target_supported);
128 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) <<
"";
133 return llvm::Triple(OffloadTargets[0]);
136 static std::optional<llvm::Triple>
138 const llvm::Triple &HostTriple) {
139 if (!Args.hasArg(options::OPT_offload_EQ)) {
140 return llvm::Triple(HostTriple.isArch64Bit() ?
"nvptx64-nvidia-cuda"
141 :
"nvptx-nvidia-cuda");
144 if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
145 TT->getArch() == llvm::Triple::spirv64)) {
146 if (Args.hasArg(options::OPT_emit_llvm))
148 D.
Diag(diag::err_drv_cuda_offload_only_emit_bc);
151 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
154 static std::optional<llvm::Triple>
156 if (!Args.hasArg(options::OPT_offload_EQ)) {
157 return llvm::Triple(
"amdgcn-amd-amdhsa");
162 if (TT->getArch() == llvm::Triple::amdgcn &&
163 TT->getVendor() == llvm::Triple::AMD &&
164 TT->getOS() == llvm::Triple::AMDHSA)
166 if (TT->getArch() == llvm::Triple::spirv64)
168 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
174 StringRef CustomResourceDir) {
180 std::string Dir = std::string(llvm::sys::path::parent_path(BinaryPath));
183 if (CustomResourceDir !=
"") {
184 llvm::sys::path::append(
P, CustomResourceDir);
191 P = llvm::sys::path::parent_path(Dir);
194 llvm::sys::path::append(
P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
195 CLANG_VERSION_MAJOR_STRING);
198 return std::string(
P);
204 : Diags(Diags), VFS(
std::move(VFS)), DumpDeviceCode(
false), Mode(GCCMode),
205 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
208 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
209 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
210 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
211 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
212 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
213 CheckInputsExist(
true), ProbePrecompiled(
true),
214 SuppressMissingInputWarning(
false) {
217 this->VFS = llvm::vfs::getRealFileSystem();
222 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
225 llvm::sys::path::append(
P,
SysRoot);
229 #if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
232 #if defined(CLANG_CONFIG_FILE_USER_DIR)
235 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
241 void Driver::setDriverMode(StringRef
Value) {
242 static StringRef OptName =
243 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
244 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
245 .Case(
"gcc", GCCMode)
246 .Case(
"g++", GXXMode)
247 .Case(
"cpp", CPPMode)
249 .Case(
"flang", FlangMode)
250 .Case(
"dxc", DXCMode)
254 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
257 void Driver::setResourceDirectory() {
276 bool UseDriverMode,
bool &ContainsError) {
277 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
278 ContainsError =
false;
281 unsigned MissingArgIndex, MissingArgCount;
282 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
283 MissingArgCount, VisibilityMask);
286 if (MissingArgCount) {
287 Diag(diag::err_drv_missing_argument)
288 << Args.getArgString(MissingArgIndex) << MissingArgCount;
295 for (
const Arg *A : Args) {
297 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
309 while (
Used->getAlias())
312 Diag(diag::warn_drv_deprecated_option_release) <<
Used->getAsString(Args);
314 diag::warn_drv_deprecated_option_release,
319 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
320 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
322 diag::warn_drv_empty_joined_argument,
327 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
329 auto ArgString = A->getAsString(Args);
331 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
333 getOpts().findExact(ArgString, Nearest,
335 DiagID = diag::err_drv_unknown_argument_with_suggestion;
336 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
338 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
339 : diag::err_drv_unknown_argument;
340 Diags.
Report(DiagID) << ArgString;
344 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
345 : diag::err_drv_unknown_argument_with_suggestion;
346 Diags.
Report(DiagID) << ArgString << Nearest;
352 for (
const Arg *A : Args.filtered(options::OPT_o)) {
353 if (ArgStrings[A->getIndex()] == A->getSpelling())
357 std::string ArgString = ArgStrings[A->getIndex()];
359 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
360 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
361 << A->getAsString(Args) << Nearest;
371 Arg **FinalPhaseArg)
const {
372 Arg *PhaseArg =
nullptr;
376 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
377 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
378 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
379 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
386 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
387 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
388 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
389 options::OPT_fmodule_header_EQ))) {
392 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
393 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
394 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
395 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
396 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
397 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
398 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
399 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
400 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
401 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
405 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S)) ||
406 (PhaseArg = DAL.getLastArg(options::OPT_fsycl_device_only))) {
410 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
413 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
421 *FinalPhaseArg = PhaseArg;
427 StringRef
Value,
bool Claim =
true) {
428 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
429 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
430 Args.AddSynthesizedArg(A);
436 DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
437 const llvm::opt::OptTable &Opts =
getOpts();
438 DerivedArgList *DAL =
new DerivedArgList(Args);
440 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
441 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
442 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
443 bool IgnoreUnused =
false;
444 for (Arg *A : Args) {
448 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
452 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
453 IgnoreUnused =
false;
463 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
464 A->getOption().matches(options::OPT_Xlinker)) &&
465 A->containsValue(
"--no-demangle")) {
467 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
470 for (StringRef Val : A->getValues())
471 if (Val !=
"--no-demangle")
472 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
480 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
481 (A->getValue(0) == StringRef(
"-MD") ||
482 A->getValue(0) == StringRef(
"-MMD"))) {
484 if (A->getValue(0) == StringRef(
"-MD"))
485 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
487 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
488 if (A->getNumValues() == 2)
489 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
494 if (A->getOption().matches(options::OPT_l)) {
495 StringRef
Value = A->getValue();
498 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
500 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
505 if (
Value ==
"cc_kext") {
506 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
512 if (A->getOption().matches(options::OPT__DASH_DASH)) {
514 for (StringRef Val : A->getValues())
519 if (A->getOption().matches(options::OPT_offload_lib_Group)) {
520 if (!A->getNumValues()) {
521 Diag(clang::diag::warn_drv_unused_argument) << A->getSpelling();
530 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
531 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
534 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
535 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
538 if (Args.hasArg(options::OPT_fintelfpga)) {
539 if (!Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false))
540 DAL->AddFlagArg(0, Opts.getOption(options::OPT_fsycl));
542 if (Arg *A = Args.getLastArg(options::OPT_gN_Group))
545 DAL->AddFlagArg(0, Opts.getOption(options::OPT_g_Flag));
550 #if defined(HOST_LINK_VERSION)
551 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
552 strlen(HOST_LINK_VERSION) > 0) {
553 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
555 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
567 StringRef TargetTriple,
569 StringRef DarwinArchName =
"") {
571 if (
const Arg *A = Args.getLastArg(options::OPT_target))
572 TargetTriple = A->getValue();
579 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
583 if (
Target.isOSBinFormatMachO()) {
585 if (!DarwinArchName.empty()) {
592 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
593 StringRef ArchName = A->getValue();
600 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
601 options::OPT_mbig_endian)) {
602 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
603 ?
Target.getLittleEndianArchVariant()
604 :
Target.getBigEndianArchVariant();
605 if (
T.getArch() != llvm::Triple::UnknownArch) {
607 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
612 if (
Target.getArch() == llvm::Triple::tce)
617 if (std::optional<std::string> ObjectModeValue =
618 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
619 StringRef ObjectMode = *ObjectModeValue;
620 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
622 if (ObjectMode ==
"64") {
623 AT =
Target.get64BitArchVariant().getArch();
624 }
else if (ObjectMode ==
"32") {
625 AT =
Target.get32BitArchVariant().getArch();
627 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
630 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
636 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
638 D.
Diag(diag::err_drv_unsupported_opt_for_target)
639 << A->getAsString(Args) <<
Target.str();
642 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
643 options::OPT_m32, options::OPT_m16,
644 options::OPT_maix32, options::OPT_maix64);
646 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
648 if (A->getOption().matches(options::OPT_m64) ||
649 A->getOption().matches(options::OPT_maix64)) {
650 AT =
Target.get64BitArchVariant().getArch();
651 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
652 Target.setEnvironment(llvm::Triple::GNU);
653 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
654 Target.setEnvironment(llvm::Triple::Musl);
655 }
else if (A->getOption().matches(options::OPT_mx32) &&
656 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
657 AT = llvm::Triple::x86_64;
658 if (
Target.getEnvironment() == llvm::Triple::Musl)
659 Target.setEnvironment(llvm::Triple::MuslX32);
661 Target.setEnvironment(llvm::Triple::GNUX32);
662 }
else if (A->getOption().matches(options::OPT_m32) ||
663 A->getOption().matches(options::OPT_maix32)) {
664 AT =
Target.get32BitArchVariant().getArch();
665 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
666 Target.setEnvironment(llvm::Triple::GNU);
667 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
668 Target.setEnvironment(llvm::Triple::Musl);
669 }
else if (A->getOption().matches(options::OPT_m16) &&
670 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
671 AT = llvm::Triple::x86;
672 Target.setEnvironment(llvm::Triple::CODE16);
675 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
677 if (
Target.isWindowsGNUEnvironment())
683 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
684 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
685 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
688 if (A && !A->getOption().matches(options::OPT_m32))
689 D.
Diag(diag::err_drv_argument_not_allowed_with)
690 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
692 Target.setArch(llvm::Triple::x86);
693 Target.setArchName(
"i586");
694 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
695 Target.setEnvironmentName(
"");
696 Target.setOS(llvm::Triple::ELFIAMCU);
697 Target.setVendor(llvm::Triple::UnknownVendor);
698 Target.setVendorName(
"intel");
704 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
705 StringRef ABIName = A->getValue();
706 if (ABIName ==
"32") {
708 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
709 Target.getEnvironment() == llvm::Triple::GNUABIN32)
710 Target.setEnvironment(llvm::Triple::GNU);
711 }
else if (ABIName ==
"n32") {
713 if (
Target.getEnvironment() == llvm::Triple::GNU ||
714 Target.getEnvironment() == llvm::Triple::GNUABI64)
715 Target.setEnvironment(llvm::Triple::GNUABIN32);
716 }
else if (ABIName ==
"64") {
718 if (
Target.getEnvironment() == llvm::Triple::GNU ||
719 Target.getEnvironment() == llvm::Triple::GNUABIN32)
720 Target.setEnvironment(llvm::Triple::GNUABI64);
728 if (Args.hasArg(options::OPT_march_EQ) ||
729 Args.hasArg(options::OPT_mcpu_EQ)) {
731 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
733 if (!llvm::errorToBool(ISAInfo.takeError())) {
734 unsigned XLen = (*ISAInfo)->getXLen();
736 Target.setArch(llvm::Triple::riscv32);
738 Target.setArch(llvm::Triple::riscv64);
750 OptSpecifier OptEq, OptSpecifier OptNeg) {
751 if (!Args.hasFlag(OptEq, OptNeg,
false))
754 const Arg *A = Args.getLastArg(OptEq);
755 StringRef LTOName = A->getValue();
763 D.
Diag(diag::err_drv_unsupported_option_argument)
764 << A->getSpelling() << A->getValue();
771 void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
773 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
775 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
776 options::OPT_fno_offload_lto);
779 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
780 options::OPT_fno_openmp_target_jit,
false)) {
781 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
782 options::OPT_fno_offload_lto))
784 Diag(diag::err_drv_incompatible_options)
785 << A->getSpelling() <<
"-fopenmp-target-jit";
792 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
794 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
796 RuntimeName = A->getValue();
798 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
806 Diag(diag::err_drv_unsupported_option_argument)
807 << A->getSpelling() << A->getValue();
810 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
827 if (!
T.isSPIROrSPIRV())
830 StringRef A(
T.getArchName());
831 if (
T.getSubArch() == llvm::Triple::NoSubArch &&
832 ((
T.getArch() == llvm::Triple::spir && A !=
"spir") ||
833 (
T.getArch() == llvm::Triple::spir64 && A !=
"spir64")))
839 if (C.getDefaultToolChain().getTriple().getArch() == llvm::Triple::x86)
847 if (!C.getDriver().isSYCLDefaultTripleImplied())
849 if (C.getInputArgs().hasArg(options::OPT_fsycl_force_target_EQ))
851 for (
const auto &SYCLTriple : SYCLTriples) {
852 if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
853 SYCLTriple.isSPIROrSPIRV())
856 if (SYCLTriple.isNVPTX() || SYCLTriple.isAMDGCN())
860 llvm::Triple DefaultTriple =
862 SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple);
874 using namespace tools::SYCL;
876 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
881 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
884 C.getInputArgs().hasArg(options::OPT_hip_link) ||
885 C.getInputArgs().hasArg(options::OPT_hipstdpar);
886 if (IsCuda && IsHIP) {
887 Diag(clang::diag::err_drv_mix_cuda_hip);
892 const llvm::Triple &HostTriple = HostTC->
getTriple();
900 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
902 CudaTC = std::make_unique<toolchains::CudaToolChain>(
903 *
this, *CudaTriple, *HostTC, C.getInputArgs(), OFK);
908 if (CudaInstallation.
isValid())
911 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
913 if (
auto *OMPTargetArg =
914 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
915 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
916 << OMPTargetArg->getSpelling() <<
"HIP";
924 auto *HIPTC = &getOffloadingDeviceToolChain(C.getInputArgs(), *HIPTriple,
926 assert(HIPTC &&
"Could not create offloading device tool chain.");
927 C.addOffloadDeviceToolChain(HIPTC, OFK);
935 bool IsOpenMPOffloading =
936 C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
937 options::OPT_fno_openmp,
false) &&
938 (C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
939 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ));
940 if (IsOpenMPOffloading) {
946 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
950 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
951 llvm::StringMap<StringRef> FoundNormalizedTriples;
952 std::multiset<StringRef> OpenMPTriples;
957 if (Arg *OpenMPTargets =
958 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
959 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
960 Diag(clang::diag::warn_drv_empty_joined_argument)
961 << OpenMPTargets->getAsString(C.getInputArgs());
964 for (StringRef
T : OpenMPTargets->getValues())
965 OpenMPTriples.insert(
T);
966 }
else if (C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
979 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
986 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
987 *
this, *AMDTriple, *HostTC, C.getInputArgs());
992 if (!AMDTriple && !NVPTXTriple) {
993 for (StringRef Arch :
998 for (StringRef Arch : Archs) {
1001 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
1002 }
else if (AMDTriple &&
1005 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
1007 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
1013 if (Archs.empty()) {
1014 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1019 for (
const auto &TripleAndArchs : DerivedArchs)
1020 OpenMPTriples.insert(TripleAndArchs.first());
1023 for (StringRef Val : OpenMPTriples) {
1025 std::string NormalizedName = TT.normalize();
1028 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
1029 if (Duplicate != FoundNormalizedTriples.end()) {
1030 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1031 << Val << Duplicate->second;
1037 FoundNormalizedTriples[NormalizedName] = Val;
1040 if (TT.getArch() == llvm::Triple::UnknownArch)
1041 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
1046 if (TT.isNVPTX() || TT.isAMDGCN()) {
1049 assert(HostTC &&
"Host toolchain should be always defined.");
1051 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
1054 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
1056 else if (TT.isAMDGCN())
1057 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
1058 *
this, TT, *HostTC, C.getInputArgs());
1060 assert(DeviceTC &&
"Device toolchain not defined.");
1063 TC = DeviceTC.get();
1065 TC = &getToolChain(C.getInputArgs(), TT);
1067 if (DerivedArchs.contains(TT.getTriple()))
1068 KnownArchs[TC] = DerivedArchs[TT.getTriple()];
1071 }
else if (C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
1072 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1083 bool HasValidSYCLRuntime =
1084 C.getInputArgs().hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
1086 C.getInputArgs().hasArg(options::OPT_fsycl_device_only);
1088 Arg *SYCLfpga = C.getInputArgs().getLastArg(options::OPT_fintelfpga);
1091 if (SYCLfpga && !HasValidSYCLRuntime)
1092 HasValidSYCLRuntime =
true;
1096 auto getArgRequiringSYCLRuntime = [&](OptSpecifier OptId) -> Arg * {
1097 Arg *SYCLArg = C.getInputArgs().getLastArg(OptId);
1098 if (SYCLArg && !HasValidSYCLRuntime) {
1099 Diag(clang::diag::err_drv_expecting_fsycl_with_sycl_opt)
1102 << SYCLArg->getSpelling().split(
'=').first;
1108 Arg *SYCLTargets = getArgRequiringSYCLRuntime(options::OPT_fsycl_targets_EQ);
1109 Arg *SYCLLink = getArgRequiringSYCLRuntime(options::OPT_fsycl_link_EQ);
1112 Arg *SYCLHostCompiler =
1113 getArgRequiringSYCLRuntime(options::OPT_fsycl_host_compiler_EQ);
1114 Arg *SYCLHostCompilerOptions =
1115 getArgRequiringSYCLRuntime(options::OPT_fsycl_host_compiler_options_EQ);
1118 if (SYCLTargets && SYCLfpga)
1119 Diag(clang::diag::err_drv_option_conflict)
1120 << SYCLTargets->getSpelling() << SYCLfpga->getSpelling();
1122 if (SYCLHostCompilerOptions && !SYCLHostCompiler)
1123 Diag(clang::diag::warn_drv_opt_requires_opt)
1124 << SYCLHostCompilerOptions->getSpelling().split(
'=').first
1125 <<
"-fsycl-host-compiler";
1127 auto argSYCLIncompatible = [&](OptSpecifier OptId) {
1128 if (!HasValidSYCLRuntime)
1130 if (Arg *IncompatArg = C.getInputArgs().getLastArg(OptId))
1131 Diag(clang::diag::err_drv_fsycl_unsupported_with_opt)
1132 << IncompatArg->getSpelling();
1135 argSYCLIncompatible(options::OPT_static_libstdcxx);
1137 argSYCLIncompatible(options::OPT_ffreestanding);
1146 auto checkSingleArgValidity = [&](Arg *A,
1150 const char *ArgValue = A->getValue();
1151 for (
const StringRef AllowedValue : AllowedValues)
1152 if (AllowedValue == ArgValue)
1154 Diag(clang::diag::err_drv_invalid_argument_to_option)
1155 << ArgValue << A->getOption().getName();
1157 Arg *DeviceCodeSplit =
1158 C.getInputArgs().getLastArg(options::OPT_fsycl_device_code_split_EQ);
1159 checkSingleArgValidity(SYCLLink, {
"early",
"image"});
1160 checkSingleArgValidity(DeviceCodeSplit,
1161 {
"per_kernel",
"per_source",
"auto",
"off"});
1163 Arg *RangeRoundingPreference =
1164 C.getInputArgs().getLastArg(options::OPT_fsycl_range_rounding_EQ);
1165 checkSingleArgValidity(RangeRoundingPreference, {
"disable",
"force",
"on"});
1167 Arg *SYCLForceTarget =
1168 getArgRequiringSYCLRuntime(options::OPT_fsycl_force_target_EQ);
1169 if (SYCLForceTarget) {
1170 StringRef Val(SYCLForceTarget->getValue());
1173 Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1175 bool HasSYCLTargetsOption = SYCLTargets;
1177 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
1178 llvm::StringMap<StringRef> FoundNormalizedTriples;
1180 if (HasSYCLTargetsOption) {
1183 Arg *SYCLTargetsValues = SYCLTargets;
1184 if (SYCLTargetsValues) {
1185 llvm::StringSet<> SYCLTriples;
1186 if (SYCLTargetsValues->getNumValues()) {
1191 if (SYCLForceTarget && SYCLTargetsValues->getNumValues() > 1)
1192 Diag(clang::diag::err_drv_multiple_target_with_forced_target)
1193 << SYCLTargetsValues->getAsString(C.getInputArgs())
1194 << SYCLForceTarget->getAsString(C.getInputArgs());
1196 for (StringRef Val : SYCLTargetsValues->getValues()) {
1198 StringRef UserTargetName(Val);
1199 if (
auto Device = gen::isGPUTarget<gen::IntelGPU>(Val)) {
1201 Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1205 UserTargetName =
"spir64_gen";
1206 }
else if (
auto Device = gen::isGPUTarget<gen::NvidiaGPU>(Val)) {
1208 Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1212 UserTargetName =
"nvptx64-nvidia-cuda";
1213 }
else if (
auto Device = gen::isGPUTarget<gen::AmdGPU>(Val)) {
1215 Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1219 UserTargetName =
"amdgcn-amd-amdhsa";
1220 }
else if (Val ==
"native_cpu") {
1223 llvm::Triple HostTriple = HostTC->
getTriple();
1224 SYCLTriples.insert(HostTriple.normalize());
1230 Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1237 if (DeviceTriple.isSPIRAOT() && Arch.empty() &&
1238 DeviceTriple.getSubArch() == llvm::Triple::SPIRSubArch_gen) {
1241 auto DeviceTC = std::make_unique<toolchains::SYCLToolChain>(
1242 *
this, DeviceTriple, *HostTC, C.getInputArgs());
1243 assert(DeviceTC &&
"Device toolchain not defined.");
1244 ArgStringList TargetArgs;
1245 DeviceTC->TranslateBackendTargetArgs(DeviceTC->getTriple(),
1246 C.getInputArgs(), TargetArgs);
1250 for (
int i = TargetArgs.size() - 2; i >= 0; --i) {
1251 if (StringRef(TargetArgs[i]) ==
"-device") {
1252 Arch = TargetArgs[i + 1];
1260 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
1261 if (Duplicate != FoundNormalizedTriples.end()) {
1262 Diag(clang::diag::warn_drv_sycl_offload_target_duplicate)
1263 << Val << Duplicate->second;
1269 FoundNormalizedTriples[NormalizedName] = Val;
1270 SYCLTriples.insert(DeviceTriple.normalize());
1272 DerivedArchs[DeviceTriple.getTriple()].insert(Arch);
1274 if (!SYCLTriples.empty()) {
1275 for (
const auto &SYCLTriple : SYCLTriples) {
1276 llvm::Triple Triple(SYCLTriple.getKey());
1277 UniqueSYCLTriplesVec.push_back(Triple);
1282 Diag(clang::diag::warn_drv_empty_joined_argument)
1283 << SYCLTargetsValues->getAsString(C.getInputArgs());
1289 if (HasValidSYCLRuntime) {
1293 SYCLTargetArch =
"spir64_fpga";
1301 if (C.getInputArgs().hasArg(options::OPT_fno_sycl_libspirv)) {
1302 for (
auto &TT : UniqueSYCLTriplesVec) {
1303 if (TT.isNVPTX() || TT.isAMDGCN()) {
1304 Diag(diag::warn_flag_no_sycl_libspirv) << TT.getTriple();
1306 Diag(diag::warn_drv_unsupported_option_for_target)
1307 <<
"-fno-sycl-libspirv" << TT.getTriple();
1313 if (C.getInputArgs().hasArg(options::OPT_fsycl_fp64_conv_emu)) {
1314 bool HasIntelGPUAOTTarget =
false;
1315 for (
auto &TT : UniqueSYCLTriplesVec) {
1316 if (TT.isSPIRAOT() && TT.getSubArch() == llvm::Triple::SPIRSubArch_gen) {
1317 HasIntelGPUAOTTarget =
true;
1321 if (!HasIntelGPUAOTTarget)
1322 Diag(diag::warn_unsupported_fsycl_fp64_conv_emu_use);
1329 for (
auto &TT : UniqueSYCLTriplesVec) {
1330 auto SYCLTC = &getOffloadingDeviceToolChain(C.getInputArgs(), TT, *HostTC,
1333 if (DerivedArchs.contains(TT.getTriple()))
1334 KnownArchs[SYCLTC] = DerivedArchs[TT.getTriple()];
1343 const Arg *BaseArg) {
1347 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1348 Arg *
Copy =
new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index),
1350 Copy->getValues() = Opt->getValues();
1351 if (Opt->isClaimed())
1353 Copy->setOwnsValues(Opt->getOwnsValues());
1354 Opt->setOwnsValues(
false);
1358 bool Driver::readConfigFile(StringRef FileName,
1359 llvm::cl::ExpansionContext &ExpCtx) {
1361 auto Status =
getVFS().status(FileName);
1363 Diag(diag::err_drv_cannot_open_config_file)
1364 <<
FileName << Status.getError().message();
1367 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1368 Diag(diag::err_drv_cannot_open_config_file)
1369 <<
FileName <<
"not a regular file";
1375 if (llvm::Error Err = ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
1376 Diag(diag::err_drv_cannot_read_config_file)
1383 llvm::sys::path::native(CfgFileName);
1385 std::unique_ptr<InputArgList> NewOptions = std::make_unique<InputArgList>(
1392 for (Arg *A : *NewOptions)
1396 CfgOptions = std::move(NewOptions);
1399 for (
auto *Opt : *NewOptions) {
1400 const Arg *BaseArg = &Opt->getBaseArg();
1406 ConfigFiles.push_back(std::string(CfgFileName));
1410 bool Driver::loadConfigFiles() {
1411 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1412 llvm::cl::tokenizeConfigFile);
1413 ExpCtx.setVFS(&
getVFS());
1417 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1420 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1421 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1426 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1428 llvm::sys::fs::expand_tilde(
1429 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1430 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1439 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1442 if (loadDefaultConfigFiles(ExpCtx))
1448 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1451 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1452 CfgFilePath.assign(CfgFileName);
1453 if (llvm::sys::path::is_relative(CfgFilePath)) {
1454 if (
getVFS().makeAbsolute(CfgFilePath)) {
1455 Diag(diag::err_drv_cannot_open_config_file)
1456 << CfgFilePath <<
"cannot get absolute path";
1460 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1462 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1463 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1464 if (!SearchDir.empty())
1465 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1470 if (readConfigFile(CfgFilePath, ExpCtx))
1479 bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1482 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1486 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1489 std::string RealMode = getExecutableForDriverMode(Mode);
1499 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1500 PrefixTriple.isOSUnknown())
1501 Triple = PrefixTriple.str();
1505 if (Triple.empty()) {
1506 llvm::Triple RealTriple =
1508 Triple = RealTriple.str();
1509 assert(!Triple.empty());
1524 std::string CfgFileName = Triple +
'-' + RealMode +
".cfg";
1525 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1526 return readConfigFile(CfgFilePath, ExpCtx);
1530 if (TryModeSuffix) {
1532 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1533 return readConfigFile(CfgFilePath, ExpCtx);
1538 CfgFileName = RealMode +
".cfg";
1539 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1540 if (readConfigFile(CfgFilePath, ExpCtx))
1542 }
else if (TryModeSuffix) {
1544 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1545 readConfigFile(CfgFilePath, ExpCtx))
1550 CfgFileName = Triple +
".cfg";
1551 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1552 return readConfigFile(CfgFilePath, ExpCtx);
1560 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1569 if (!DriverMode.empty())
1570 setDriverMode(DriverMode);
1572 setResourceDirectory();
1577 CLOptions = std::make_unique<InputArgList>(
1582 ContainsError = loadConfigFiles();
1583 bool HasConfigFile = !ContainsError && (CfgOptions.get() !=
nullptr);
1586 InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
1587 : std::move(*CLOptions));
1590 for (
auto *Opt : *CLOptions) {
1591 if (Opt->getOption().matches(options::OPT_config))
1593 const Arg *BaseArg = &Opt->getBaseArg();
1600 if (
IsCLMode() && !ContainsError) {
1602 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1604 CLModePassThroughArgList.push_back(A->getValue());
1607 if (!CLModePassThroughArgList.empty()) {
1610 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1615 for (
auto *Opt : *CLModePassThroughOptions) {
1621 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false) &&
1623 setDriverMode(
"g++");
1626 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1627 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1628 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1631 bool CCCPrintPhases;
1634 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1635 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1638 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1639 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1642 Args.ClaimAllArgs(options::OPT_pipe);
1650 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1652 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1653 CCCGenericGCCName = A->getValue();
1656 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1660 if (Args.hasArg(options::OPT_fproc_stat_report))
1667 llvm::Triple
T(TargetTriple);
1668 T.setOS(llvm::Triple::Win32);
1669 T.setVendor(llvm::Triple::PC);
1670 T.setEnvironment(llvm::Triple::MSVC);
1671 T.setObjectFormat(llvm::Triple::COFF);
1672 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1673 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1674 TargetTriple =
T.str();
1677 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1678 StringRef TargetProfile = A->getValue();
1681 TargetTriple = *Triple;
1683 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1687 if (Args.hasArg(options::OPT_spirv)) {
1688 llvm::Triple
T(TargetTriple);
1689 T.setArch(llvm::Triple::spirv);
1690 T.setOS(llvm::Triple::Vulkan);
1693 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1694 const llvm::StringSet<> ValidValues = {
"vulkan1.2",
"vulkan1.3"};
1695 if (ValidValues.contains(A->getValue())) {
1696 T.setOSName(A->getValue());
1698 Diag(diag::err_drv_invalid_value)
1699 << A->getAsString(Args) << A->getValue();
1704 TargetTriple =
T.str();
1707 Diag(diag::err_drv_dxc_missing_target_profile);
1711 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1712 TargetTriple = A->getValue();
1713 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1714 Dir =
Dir = A->getValue();
1715 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1719 if (std::optional<std::string> CompilerPathValue =
1720 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1721 StringRef CompilerPath = *CompilerPathValue;
1722 while (!CompilerPath.empty()) {
1723 std::pair<StringRef, StringRef> Split =
1724 CompilerPath.split(llvm::sys::EnvPathSeparator);
1725 PrefixDirs.push_back(std::string(Split.first));
1726 CompilerPath = Split.second;
1729 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1731 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1734 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1737 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1738 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1739 .Case(
"cwd", SaveTempsCwd)
1740 .Case(
"obj", SaveTempsObj)
1741 .Default(SaveTempsCwd);
1744 if (Args.getLastArg(options::OPT_fsycl_dump_device_code_EQ))
1745 DumpDeviceCode =
true;
1747 if (
const Arg *A = Args.getLastArg(
1748 options::OPT_offload_host_only, options::OPT_offload_device_only,
1749 options::OPT_offload_host_device, options::OPT_fsycl_device_only)) {
1750 if (A->getOption().matches(options::OPT_offload_host_only))
1751 Offload = OffloadHost;
1752 else if (A->getOption().matches(options::OPT_offload_device_only) ||
1753 A->getOption().matches(options::OPT_fsycl_device_only))
1754 Offload = OffloadDevice;
1756 Offload = OffloadHostDevice;
1762 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1763 StringRef
Name = A->getValue();
1764 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1765 .Case(
"off", EmbedNone)
1766 .Case(
"all", EmbedBitcode)
1767 .Case(
"bitcode", EmbedBitcode)
1768 .Case(
"marker", EmbedMarker)
1771 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1774 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1778 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1785 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1787 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1788 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1789 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1790 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1791 Std->containsValue(
"c++latest"));
1794 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1795 options::OPT_fmodule_header)) {
1797 ModulesModeCXX20 =
true;
1798 if (A->getOption().matches(options::OPT_fmodule_header))
1801 StringRef ArgName = A->getValue();
1802 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1807 Diags.
Report(diag::err_drv_invalid_value)
1808 << A->getAsString(Args) << ArgName;
1814 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1815 std::make_unique<InputArgList>(std::move(Args));
1818 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1826 if (!Triple.isWasm()) {
1827 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1828 StringRef TripleObjectFormat =
1829 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1830 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1831 TripleVersionName != TripleObjectFormat) {
1832 Diags.
Report(diag::err_drv_triple_version_invalid)
1834 ContainsError =
true;
1839 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1840 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1841 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1849 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1850 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1852 case llvm::Triple::arm:
1853 case llvm::Triple::armeb:
1854 case llvm::Triple::thumb:
1855 case llvm::Triple::thumbeb:
1856 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1857 Diag(diag::warn_target_unrecognized_env)
1859 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1862 case llvm::Triple::aarch64:
1863 case llvm::Triple::aarch64_be:
1864 case llvm::Triple::aarch64_32:
1865 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1866 Diag(diag::warn_target_unrecognized_env)
1868 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1885 BuildInputs(C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1888 if (checkForOffloadStaticLib(*C, *TranslatedArgs))
1889 setOffloadStaticLibSeen();
1893 if (checkForSYCLDefaultDevice(*C, *TranslatedArgs))
1894 setSYCLDefaultTriple(
true);
1903 TranslatedArgs->hasFlag(options::OPT_fopenmp_new_driver,
1904 options::OPT_no_offload_new_driver,
true)) ||
1905 TranslatedArgs->hasFlag(options::OPT_offload_new_driver,
1906 options::OPT_no_offload_new_driver,
false))
1907 setUseNewOffloadingDriver();
1912 for (
auto TI = SYCLTCRange.first, TE = SYCLTCRange.second; TI != TE; ++TI) {
1913 if (TI->second->getTriple().getSubArch() !=
1914 llvm::Triple::SPIRSubArch_fpga)
1916 ArgStringList TargetArgs;
1924 for (StringRef ArgString : TargetArgs) {
1925 if (ArgString ==
"-hardware" || ArgString ==
"-simulation") {
1936 if (TC.
getTriple().isOSBinFormatMachO())
1939 BuildActions(*C, C->getArgs(), Inputs, C->getActions());
1941 if (CCCPrintPhases) {
1951 static void printArgList(raw_ostream &OS,
const llvm::opt::ArgList &Args) {
1952 llvm::opt::ArgStringList ASL;
1953 for (
const auto *A : Args) {
1957 while (A->getAlias())
1959 A->render(Args, ASL);
1962 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1963 if (I != ASL.begin())
1965 llvm::sys::printArg(OS, *I,
true);
1970 bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1972 using namespace llvm::sys;
1973 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1974 "Only knows about .crash files on Darwin");
1979 path::home_directory(CrashDiagDir);
1980 if (CrashDiagDir.starts_with(
"/var/root"))
1982 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1990 fs::file_status FileStatus;
1991 TimePoint<> LastAccessTime;
1995 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1996 File != FileEnd && !EC;
File.increment(EC)) {
2000 if (fs::status(
File->path(), FileStatus))
2002 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
2003 llvm::MemoryBuffer::getFile(
File->path());
2008 StringRef
Data = CrashFile.get()->getBuffer();
2009 if (!
Data.starts_with(
"Process:"))
2012 size_t ParentProcPos =
Data.find(
"Parent Process:");
2013 if (ParentProcPos == StringRef::npos)
2015 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
2016 if (LineEnd == StringRef::npos)
2018 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
2019 int OpenBracket = -1, CloseBracket = -1;
2020 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
2021 if (ParentProcess[i] ==
'[')
2023 if (ParentProcess[i] ==
']')
2029 if (OpenBracket < 0 || CloseBracket < 0 ||
2030 ParentProcess.slice(OpenBracket + 1, CloseBracket)
2031 .getAsInteger(10, CrashPID) || CrashPID != PID) {
2041 const auto FileAccessTime = FileStatus.getLastModificationTime();
2042 if (FileAccessTime > LastAccessTime) {
2043 CrashFilePath.assign(
File->path());
2044 LastAccessTime = FileAccessTime;
2049 if (!CrashFilePath.empty()) {
2050 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
2060 "\n********************\n\n"
2061 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
2062 "Preprocessed source(s) and associated run script(s) are located at:";
2070 if (C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
2074 if (Arg *A = C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
2075 Level = llvm::StringSwitch<unsigned>(A->getValue())
2077 .Case(
"compiler", 1)
2091 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2092 if (!IsLLD ||
Level < 2)
2099 SavedTemps = std::move(C.getTempFiles());
2100 assert(!C.getTempFiles().size());
2117 C.initCompilationForDiagnostics();
2123 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2124 StringRef ReproduceOption =
2125 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2128 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2132 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2134 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2135 Diag(clang::diag::note_drv_command_failed_diag_msg)
2136 <<
"\n\n********************";
2144 BuildInputs(C.getDefaultToolChain(), C.getArgs(), Inputs);
2146 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2147 bool IgnoreInput =
false;
2153 }
else if (!strcmp(it->second->getValue(),
"-")) {
2154 Diag(clang::diag::note_drv_command_failed_diag_msg)
2155 <<
"Error generating preprocessed source(s) - "
2156 "ignoring input from stdin.";
2161 it = Inputs.erase(it);
2168 if (Inputs.empty()) {
2169 Diag(clang::diag::note_drv_command_failed_diag_msg)
2170 <<
"Error generating preprocessed source(s) - "
2171 "no preprocessable inputs.";
2177 llvm::StringSet<> ArchNames;
2178 for (
const Arg *A : C.getArgs()) {
2179 if (A->getOption().matches(options::OPT_arch)) {
2180 StringRef ArchName = A->getValue();
2181 ArchNames.insert(ArchName);
2184 if (ArchNames.size() > 1) {
2185 Diag(clang::diag::note_drv_command_failed_diag_msg)
2186 <<
"Error generating preprocessed source(s) - cannot generate "
2187 "preprocessed source with multiple -arch options.";
2193 const ToolChain &TC = C.getDefaultToolChain();
2194 if (TC.
getTriple().isOSBinFormatMachO())
2203 Diag(clang::diag::note_drv_command_failed_diag_msg)
2204 <<
"Error generating preprocessed source(s).";
2210 C.ExecuteJobs(C.getJobs(), FailingCommands);
2213 if (!FailingCommands.empty()) {
2214 Diag(clang::diag::note_drv_command_failed_diag_msg)
2215 <<
"Error generating preprocessed source(s).";
2220 if (TempFiles.empty()) {
2221 Diag(clang::diag::note_drv_command_failed_diag_msg)
2222 <<
"Error generating preprocessed source(s).";
2230 for (
auto &TempFile : TempFiles) {
2231 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile.first;
2234 if (ReproCrashFilename.empty()) {
2235 ReproCrashFilename = TempFile.first;
2236 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2238 if (StringRef(TempFile.first).ends_with(
".cache")) {
2241 VFS = llvm::sys::path::filename(TempFile.first);
2242 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2246 for (
auto &TempFile : SavedTemps)
2247 C.addTempFile(TempFile.first);
2253 llvm::sys::path::replace_extension(Script,
"sh");
2255 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2256 llvm::sys::fs::FA_Write,
2257 llvm::sys::fs::OF_Text);
2259 Diag(clang::diag::note_drv_command_failed_diag_msg)
2260 <<
"Error generating run script: " << Script <<
" " << EC.message();
2263 <<
"# Driver args: ";
2265 ScriptOS <<
"# Original command: ";
2266 Cmd.Print(ScriptOS,
"\n",
true);
2267 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
2268 if (!AdditionalInformation.empty())
2269 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2273 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2277 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2279 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2280 Diag(clang::diag::note_drv_command_failed_diag_msg)
2281 << ReproCrashFilename.str();
2283 llvm::sys::path::append(CrashDiagDir,
Name);
2284 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2285 Diag(clang::diag::note_drv_command_failed_diag_msg)
2286 <<
"Crash backtrace is located in";
2287 Diag(clang::diag::note_drv_command_failed_diag_msg)
2288 << CrashDiagDir.str();
2289 Diag(clang::diag::note_drv_command_failed_diag_msg)
2290 <<
"(choose the .crash file that corresponds to your crash)";
2294 Diag(clang::diag::note_drv_command_failed_diag_msg)
2295 <<
"\n\n********************";
2303 if (
Cmd.getResponseFileSupport().ResponseKind ==
2305 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
2306 Cmd.getArguments()))
2310 Cmd.setResponseFile(C.addTempFile(C.getArgs().MakeArgString(TmpName)));
2316 if (C.getArgs().hasArg(options::OPT_fdriver_only)) {
2317 if (C.getArgs().hasArg(options::OPT_v))
2318 C.getJobs().Print(llvm::errs(),
"\n",
true);
2320 C.ExecuteJobs(C.getJobs(), FailingCommands,
true);
2330 if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2331 C.getJobs().Print(llvm::errs(),
"\n",
true);
2340 for (
auto &Job : C.getJobs())
2341 setUpResponseFiles(C, Job);
2343 C.ExecuteJobs(C.getJobs(), FailingCommands);
2346 if (FailingCommands.empty())
2352 for (
const auto &CmdPair : FailingCommands) {
2353 int CommandRes = CmdPair.first;
2354 const Command *FailingCommand = CmdPair.second;
2359 C.CleanupFileMap(C.getResultFiles(), JA,
true);
2363 C.CleanupFileMap(C.getFailureResultFiles(), JA,
true);
2368 if (CommandRes == EX_IOERR) {
2385 Diag(clang::diag::err_drv_command_signalled)
2388 Diag(clang::diag::err_drv_command_failed)
2393 if (!CustomDiag.empty())
2394 Diag(clang::diag::note_drv_command_failed_diag_msg) << CustomDiag;
2402 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2410 "spir",
"spir64",
"spir64_fpga",
"spir64_x86_64",
2411 "spir64_gen",
"spirv32",
"spirv64"};
2412 if (std::find(SYCLAlias.begin(), SYCLAlias.end(), TargetArch) !=
2415 TT.setArchName(TargetArch);
2416 TT.setVendor(llvm::Triple::UnknownVendor);
2417 TT.setOS(llvm::Triple::UnknownOS);
2420 return llvm::Triple(TargetArch);
2429 if (Arg *A = C.getArgs().getLastArg(options::OPT_fsycl_help_EQ)) {
2430 StringRef AV(A->getValue());
2432 if (AV ==
"gen" || AV ==
"all")
2434 "ocloc",
"--help",
""));
2435 if (AV ==
"fpga" || AV ==
"all")
2437 "aoc",
"-help",
"-sycl"));
2438 if (AV ==
"x86_64" || AV ==
"all")
2440 "opencl-aot",
"--help",
""));
2441 if (HelpArgs.empty()) {
2442 C.getDriver().Diag(diag::err_drv_unsupported_option_argument)
2443 << A->getSpelling() << AV;
2449 for (
auto &HA : HelpArgs) {
2450 llvm::outs() <<
"Emitting help information for " << std::get<1>(HA) <<
'\n'
2451 <<
"Use triple of '" << std::get<0>(HA).normalize() <<
2452 "' to enable ahead of time compilation\n";
2454 llvm::outs().flush();
2455 std::vector<StringRef> ToolArgs = {std::get<1>(HA), std::get<2>(HA),
2458 C.getDefaultToolChain().GetProgramPath(std::get<1>(HA).data()));
2460 if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2461 llvm::errs() <<
"\"" << ExecPath <<
"\" \"" << ToolArgs[1] <<
"\"";
2462 if (!ToolArgs[2].empty())
2463 llvm::errs() <<
" \"" << ToolArgs[2] <<
"\"";
2464 llvm::errs() <<
"\n";
2467 auto ToolBinary = llvm::sys::findProgramByName(ExecPath);
2468 if (ToolBinary.getError()) {
2469 C.getDriver().Diag(diag::err_drv_command_failure) << ExecPath;
2473 llvm::sys::ExecuteAndWait(ToolBinary.get(), ToolArgs);
2485 const ToolChain &TC = C.getDefaultToolChain();
2489 if (Arg *A = C.getArgs().getLastArg(options::OPT_mthread_model)) {
2492 OS <<
"Thread model: " << A->getValue();
2498 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2503 if (!llvm::cl::getCompilerBuildConfig().empty())
2504 llvm::cl::printBuildConfig(OS);
2507 for (
auto ConfigFile : ConfigFiles)
2508 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2521 if (PassedFlags ==
"")
2525 std::vector<std::string> SuggestedCompletions;
2526 std::vector<std::string> Flags;
2538 const bool HasSpace = PassedFlags.ends_with(
",");
2542 StringRef TargetFlags = PassedFlags;
2543 while (TargetFlags !=
"") {
2545 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2546 Flags.push_back(std::string(CurFlag));
2551 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2554 const llvm::opt::OptTable &Opts =
getOpts();
2556 Cur = Flags.at(Flags.size() - 1);
2558 if (Flags.size() >= 2) {
2559 Prev = Flags.at(Flags.size() - 2);
2560 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2563 if (SuggestedCompletions.empty())
2564 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2571 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2572 llvm::outs() <<
'\n';
2578 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2582 SuggestedCompletions = Opts.findByPrefix(
2583 Cur, VisibilityMask,
2590 if (S.starts_with(Cur))
2591 SuggestedCompletions.push_back(std::string(S));
2598 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2599 if (
int X = A.compare_insensitive(B))
2601 return A.compare(B) > 0;
2604 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2611 if (C.getArgs().hasArg(options::OPT_dumpmachine)) {
2612 llvm::outs() << C.getDefaultToolChain().getTripleString() <<
'\n';
2616 if (C.getArgs().hasArg(options::OPT_dumpversion)) {
2619 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2623 if (C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2628 if (C.getArgs().hasArg(options::OPT_help) ||
2629 C.getArgs().hasArg(options::OPT__help_hidden)) {
2630 PrintHelp(C.getArgs().hasArg(options::OPT__help_hidden));
2634 if (C.getArgs().hasArg(options::OPT_fsycl_help_EQ)) {
2639 if (C.getArgs().hasArg(options::OPT__version)) {
2645 if (C.getArgs().hasArg(options::OPT_v) ||
2646 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2647 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2648 C.getArgs().hasArg(options::OPT_print_supported_extensions)) {
2650 SuppressMissingInputWarning =
true;
2653 if (C.getArgs().hasArg(options::OPT_v)) {
2655 llvm::errs() <<
"System configuration file directory: "
2658 llvm::errs() <<
"User configuration file directory: "
2662 const ToolChain &TC = C.getDefaultToolChain();
2664 if (C.getArgs().hasArg(options::OPT_v))
2667 if (C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2672 if (C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2673 llvm::outs() <<
"programs: =";
2674 bool separator =
false;
2678 llvm::outs() << llvm::sys::EnvPathSeparator;
2679 llvm::outs() << Path;
2684 llvm::outs() << llvm::sys::EnvPathSeparator;
2685 llvm::outs() << Path;
2688 llvm::outs() <<
"\n";
2691 StringRef sysroot = C.getSysRoot();
2695 llvm::outs() << llvm::sys::EnvPathSeparator;
2698 llvm::outs() << sysroot << Path.substr(1);
2700 llvm::outs() << Path;
2702 llvm::outs() <<
"\n";
2706 if (C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2712 if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2713 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2714 llvm::outs() << *RuntimePath <<
'\n';
2720 if (C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2722 for (
std::size_t I = 0; I != Flags.size(); I += 2)
2723 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2729 if (Arg *A = C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2730 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2734 if (Arg *A = C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2735 StringRef ProgName = A->getValue();
2738 if (! ProgName.empty())
2741 llvm::outs() <<
"\n";
2745 if (Arg *A = C.getArgs().getLastArg(options::OPT_autocomplete)) {
2746 StringRef PassedFlags = A->getValue();
2751 if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2757 llvm::outs() << TC.
getCompilerRT(C.getArgs(),
"builtins") <<
"\n";
2760 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2766 if (C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2772 if (C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2775 std::set<llvm::StringRef> SortedFlags;
2776 for (
const auto &FlagEntry : ExpandedFlags)
2777 SortedFlags.insert(FlagEntry.getKey());
2778 for (
auto Flag : SortedFlags)
2779 llvm::outs() << Flag <<
'\n';
2783 if (C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2786 llvm::outs() <<
".\n";
2789 assert(Suffix.front() ==
'/');
2790 llvm::outs() << Suffix.substr(1) <<
"\n";
2796 if (C.getArgs().hasArg(options::OPT_print_target_triple)) {
2801 if (C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2803 llvm::outs() << Triple.getTriple() <<
"\n";
2807 if (C.getArgs().hasArg(options::OPT_print_targets)) {
2808 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2825 std::map<Action *, unsigned> &Ids,
2831 llvm::raw_string_ostream os(str);
2833 auto getSibIndent = [](
int K) -> Twine {
2837 Twine SibIndent =
Indent + getSibIndent(
Kind);
2841 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2843 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2844 <<
PrintActions1(C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2845 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2846 bool IsFirst =
true;
2847 OA->doOnEachDependence(
2849 assert(TC &&
"Unknown host toolchain");
2861 os <<
":" << BoundArch;
2864 os <<
" {" <<
PrintActions1(C, A, Ids, SibIndent, SibKind) <<
"}";
2872 const char *Prefix =
"{";
2873 for (
Action *PreRequisite : *AL) {
2874 os << Prefix <<
PrintActions1(C, PreRequisite, Ids, SibIndent, SibKind);
2885 std::string offload_str;
2886 llvm::raw_string_ostream offload_os(offload_str);
2887 if (!isa<OffloadAction>(A)) {
2890 offload_os <<
", (" << S;
2897 auto getSelfIndent = [](
int K) -> Twine {
2901 unsigned Id = Ids.size();
2903 llvm::errs() <<
Indent + getSelfIndent(
Kind) <<
Id <<
": " << os.str() <<
", "
2912 std::map<Action *, unsigned> Ids;
2913 for (
Action *A : C.getActions())
2920 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2921 isa<AssembleJobAction>(A))
2929 DerivedArgList &Args = C.getArgs();
2931 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2934 llvm::StringSet<> ArchNames;
2936 for (Arg *A : Args) {
2937 if (A->getOption().matches(options::OPT_arch)) {
2940 llvm::Triple::ArchType Arch =
2942 if (Arch == llvm::Triple::UnknownArch) {
2943 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2948 if (ArchNames.insert(A->getValue()).second)
2949 Archs.push_back(A->getValue());
2963 for (
Action* Act : SingleActions) {
2971 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2975 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2980 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2981 Actions.append(Inputs.begin(), Inputs.end());
2983 Actions.push_back(C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2986 Arg *A = Args.getLastArg(options::OPT_g_Group);
2987 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2988 !A->getOption().matches(options::OPT_gstabs);
2996 if (Act->getType() == types::TY_Image) {
2998 Inputs.push_back(Actions.back());
3005 if (Args.hasArg(options::OPT_verify_debug_info)) {
3006 Action* LastAction = Actions.back();
3009 LastAction, types::TY_Nothing));
3028 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
3029 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3041 std::string Nearest;
3042 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3043 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3044 <<
Value << Nearest;
3083 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3086 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3094 return types::TY_CXXUHeader;
3096 return types::TY_CXXSHeader;
3100 llvm_unreachable(
"should not be called in this case");
3102 return types::TY_CXXHUHeader;
3108 const llvm::opt::OptTable &Opts =
getOpts();
3112 types::ID InputType = types::TY_Nothing;
3113 Arg *InputTypeArg =
nullptr;
3115 Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false) ||
3116 Args.hasArg(options::OPT_fsycl_device_only);
3119 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3120 options::OPT__SLASH_TP)) {
3121 InputTypeArg = TCTP;
3122 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC) && !IsSYCL
3127 bool ShowNote =
false;
3129 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3131 Diag(clang::diag::warn_drv_overriding_option)
3132 <<
Previous->getSpelling() << A->getSpelling();
3138 Diag(clang::diag::note_drv_t_option_is_global);
3143 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3144 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3145 if (LastXArg && LastInputArg &&
3146 LastInputArg->getIndex() < LastXArg->getIndex())
3147 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3150 for (Arg *A : Args) {
3151 if (A->getOption().
getKind() == Option::InputClass) {
3152 const char *
Value = A->getValue();
3156 if (InputType == types::TY_Nothing) {
3159 InputTypeArg->claim();
3164 CType = types::TY_CXX;
3167 if (memcmp(
Value,
"-", 2) == 0) {
3169 Ty = types::TY_Fortran;
3171 Ty = types::TY_HLSL;
3180 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3181 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3182 : clang::diag::err_drv_unknown_stdin_type);
3191 if (
const char *Ext = strrchr(
Value,
'.'))
3201 case types::TY_CHeader:
3202 Ty = types::TY_CXXHeader;
3204 case types::TY_PP_C:
3205 Ty = types::TY_PP_CXX;
3207 case types::TY_PP_CHeader:
3208 Ty = types::TY_PP_CXXHeader;
3214 Diag(clang::diag::warn_drv_fsycl_with_c_type)
3225 Ty = types::TY_Object;
3236 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3237 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3243 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3244 Ty == types::TY_Object)
3245 Ty = types::TY_LLVM_BC;
3253 if (Ty != types::TY_Object) {
3254 if (Args.hasArg(options::OPT_ObjC))
3255 Ty = types::TY_ObjC;
3256 else if (Args.hasArg(options::OPT_ObjCXX))
3257 Ty = types::TY_ObjCXX;
3264 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3268 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3269 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3272 const char *Ext = strrchr(
Value,
'.');
3274 Ty = types::TY_Object;
3278 InputTypeArg->claim();
3282 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3283 Args.hasArgNoClaim(options::OPT_hipstdpar))
3287 Inputs.push_back(std::make_pair(Ty, A));
3289 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3290 StringRef
Value = A->getValue();
3293 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3295 std::make_pair(IsSYCL ? types::TY_CXX : types::TY_C, InputArg));
3298 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3299 StringRef
Value = A->getValue();
3302 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3303 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3309 Inputs.push_back(std::make_pair(types::TY_Object, A));
3311 }
else if (A->getOption().matches(options::OPT_x)) {
3320 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3321 InputType = types::TY_Object;
3324 if (IsSYCL && (InputType == types::TY_C || InputType == types::TY_PP_C ||
3325 InputType == types::TY_CHeader))
3326 Diag(clang::diag::err_drv_fsycl_with_c_type) << A->getAsString(Args);
3332 }
else if (A->getOption().getID() == options::OPT_U) {
3333 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3334 StringRef Val = A->getValue(0);
3335 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3337 Diag(diag::warn_slash_u_filename) << Val;
3338 Diag(diag::note_use_dashdash);
3342 if (
CCCIsCPP() && Inputs.empty()) {
3346 Inputs.push_back(std::make_pair(types::TY_C, A));
3353 StringRef ExecPath(C.getArgs().MakeArgString(C.getDriver().Dir));
3354 llvm::ErrorOr<std::string> BundlerBinary =
3355 llvm::sys::findProgramByName(
"clang-offload-bundler", ExecPath);
3357 BundlerArgs.push_back(BundlerBinary.getError() ?
"clang-offload-bundler"
3358 : BundlerBinary.get().c_str());
3359 BundlerArgs.append(InputArgs);
3362 bool OutputOnly = C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
3363 if (C.getArgs().hasArg(options::OPT_v) || OutputOnly) {
3364 for (StringRef A : BundlerArgs)
3366 llvm::errs() <<
"\"" << A <<
"\" ";
3368 llvm::errs() << A <<
" ";
3369 llvm::errs() <<
'\n';
3371 if (BundlerBinary.getError())
3374 return !llvm::sys::ExecuteAndWait(BundlerBinary.get(), BundlerArgs);
3380 if (!llvm::sys::fs::exists(Object))
3390 TT.setVendorName(
"intel");
3391 TT.setOS(llvm::Triple::UnknownOS);
3395 const char *Targets =
3396 C.getArgs().MakeArgString(Twine(
"-targets=sycl-") + TT.str());
3397 const char *Inputs = C.getArgs().MakeArgString(Twine(
"-input=") + Object);
3406 const StringRef &File) {
3408 if (!llvm::sys::fs::exists(
File))
3417 StringRef ExecPath(C.getArgs().MakeArgString(C.getDriver().Dir));
3418 llvm::ErrorOr<std::string> BundlerBinary =
3419 llvm::sys::findProgramByName(
"clang-offload-bundler", ExecPath);
3420 const char *Input = C.getArgs().MakeArgString(Twine(
"-input=") +
File.str());
3424 BundlerBinary.get(), IsArchive ?
"-type=ao" :
"-type=o", Input,
"-list"};
3427 bool OutputOnly = C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
3428 if (C.getArgs().hasArg(options::OPT_v) || OutputOnly) {
3429 for (StringRef A : BundlerArgs)
3431 llvm::errs() <<
"\"" << A <<
"\" ";
3433 llvm::errs() << A <<
" ";
3434 llvm::errs() <<
'\n';
3436 if (BundlerBinary.getError())
3439 C.getDriver().GetTemporaryPath(
"bundle-list",
"txt"));
3440 llvm::FileRemover OutputRemover(OutputFile.c_str());
3441 std::optional<llvm::StringRef> Redirects[] = {
3447 std::string ErrorMessage;
3448 if (llvm::sys::ExecuteAndWait(BundlerBinary.get(), BundlerArgs, {}, Redirects,
3455 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
3456 llvm::MemoryBuffer::getFile(OutputFile.c_str());
3463 for (llvm::line_iterator LineIt(**OutputBuf); !LineIt.is_at_end(); ++LineIt)
3464 Sections.push_back(LineIt->str());
3465 if (Sections.empty())
3473 if (!llvm::sys::fs::exists(
File))
3483 const char *Targets =
3484 C.getArgs().MakeArgString(Twine(
"-targets=sycl-") + TT.str());
3485 const char *Inputs = C.getArgs().MakeArgString(Twine(
"-input=") +
File.str());
3487 Targets, Inputs,
"-check-section"};
3492 DerivedArgList &Args) {
3494 return !Sections.empty();
3500 const std::string &OptCheck) {
3501 return (Option == OptCheck || (
"-" + Option) == OptCheck);
3511 bool IsMSVC = C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
3513 std::optional<std::string> LibPath =
3514 llvm::sys::Process::GetEnv(IsMSVC ?
"LIB" :
"LIBRARY_PATH");
3517 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator,
'\0'};
3518 llvm::SplitString(*LibPath, SplitPaths, EnvPathSeparatorStr);
3519 for (StringRef Path : SplitPaths)
3520 LibPaths.emplace_back(Path.trim());
3523 for (std::string LibDirs : Args.getAllArgValues(options::OPT_L))
3524 LibPaths.emplace_back(LibDirs);
3532 auto resolveStaticLib = [&](StringRef LibName,
bool IsStatic) ->
bool {
3533 if (!LibName.starts_with(
"-l"))
3535 for (
auto &LPath : LibPaths) {
3540 llvm::sys::path::append(SoLibName,
3541 Twine(
"lib" + LibName.substr(2) +
".so").str());
3542 if (llvm::sys::fs::exists(SoLibName))
3546 llvm::sys::path::append(FullName,
3547 Twine(
"lib" + LibName.substr(2) +
".a").str());
3548 if (llvm::sys::fs::exists(FullName)) {
3549 LibArgs.push_back(Args.MakeArgString(FullName));
3555 for (
const auto *A : Args) {
3556 std::string
FileName = A->getAsString(Args);
3557 static bool IsLinkStateStatic(Args.hasArg(options::OPT_static));
3558 auto addLibArg = [&](StringRef LibName) ->
bool {
3561 LibArgs.push_back(Args.MakeArgString(LibName));
3566 if (A->getOption().
getKind() == Option::InputClass) {
3573 if (A->getOption().matches(options::OPT__SLASH_link)) {
3574 for (StringRef
Value : A->getValues()) {
3576 if (
Value.starts_with_insensitive(
"-libpath:") ||
3577 Value.starts_with_insensitive(
"/libpath:"))
3578 LibPaths.emplace_back(
Value.substr(std::string(
"-libpath:").size()));
3579 if (addLibArg(
Value))
3581 for (
auto LPath : LibPaths) {
3583 llvm::sys::path::append(FullLib,
Value);
3584 if (addLibArg(FullLib))
3589 if (A->getOption().matches(options::OPT_Wl_COMMA) ||
3590 A->getOption().matches(options::OPT_Xlinker)) {
3597 static std::string PrevArg;
3598 for (StringRef
Value : A->getValues()) {
3599 auto addKnownValues = [&](
const StringRef &
V) {
3604 LibArgs.push_back(Args.MakeArgString(
V));
3611 if (PrevArg !=
"-z" && PrevArg !=
"-rpath" &&
V[0] !=
'-' &&
3613 LibArgs.push_back(Args.MakeArgString(
V));
3620 IsLinkStateStatic =
true;
3626 IsLinkStateStatic =
false;
3629 resolveStaticLib(
V, IsLinkStateStatic);
3631 if (
Value[0] ==
'@') {
3635 ExpandArgs.push_back(
Value.data());
3637 llvm::BumpPtrAllocator A;
3638 llvm::StringSaver S(A);
3639 llvm::cl::ExpandResponseFiles(
3641 IsMSVC ? llvm::cl::TokenizeWindowsCommandLine
3642 : llvm::cl::TokenizeGNUCommandLine,
3644 for (StringRef EA : ExpandArgs)
3647 addKnownValues(
Value);
3652 if (A->getOption().matches(options::OPT_l))
3653 resolveStaticLib(A->getAsString(Args), IsLinkStateStatic);
3659 StringRef ObjFileName = llvm::sys::path::filename(ObjFilePath);
3660 StringRef ObjSuffix = isMSVCEnv ?
".obj" :
".o";
3661 StringRef NewObjSuffix = isMSVCEnv ?
".new.obj" :
".new.o";
3663 (ObjFileName.starts_with(
"libsycl-") &&
3664 ObjFileName.ends_with(ObjSuffix) &&
3665 !ObjFileName.ends_with(NewObjSuffix))
3674 bool Driver::checkForSYCLDefaultDevice(
Compilation &C,
3675 DerivedArgList &Args)
const {
3677 if (!Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false))
3680 if (Args.hasArg(options::OPT_fno_sycl_link_spirv))
3685 if (
const Arg *A = Args.getLastArg(options::OPT_fsycl_targets_EQ)) {
3686 for (
const char *Val : A->getValues()) {
3687 llvm::Triple TT(
C.getDriver().MakeSYCLDeviceTriple(Val));
3688 if ((TT.isSPIROrSPIRV()) && TT.getSubArch() == llvm::Triple::NoSubArch)
3692 }
else if (!Args.hasArg(options::OPT_fintelfpga))
3696 for (StringRef Arg : AllArgs) {
3706 bool Driver::checkForOffloadStaticLib(
Compilation &C,
3707 DerivedArgList &Args)
const {
3709 if (!Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false) &&
3710 !Args.hasArg(options::OPT_fopenmp_targets_EQ))
3714 for (StringRef OLArg : OffloadLibArgs)
3718 return !(
hasFPGABinary(C, OLArg.str(), types::TY_FPGA_AOCR) ||
3728 if (isa<OffloadDepsJobAction>(A))
3736 class OffloadingActionBuilder final {
3738 bool IsValid =
false;
3744 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3747 std::map<Action *, const Arg *> HostActionToInputArgMap;
3750 class DeviceActionBuilder {
3754 enum ActionBuilderReturnCode {
3773 DerivedArgList &Args;
3782 OffloadingActionBuilder &OffloadingActionBuilderRef;
3785 DeviceActionBuilder(
Compilation &C, DerivedArgList &Args,
3788 OffloadingActionBuilder &OAB)
3789 :
C(
C), Args(Args), Inputs(Inputs),
3790 AssociatedOffloadKind(AssociatedOffloadKind),
3791 OffloadingActionBuilderRef(OAB) {}
3792 virtual ~DeviceActionBuilder() {}
3797 virtual ActionBuilderReturnCode
3801 return ABRT_Inactive;
3806 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
3807 return ABRT_Inactive;
3811 virtual void appendTopLevelActions(
ActionList &AL) {}
3814 virtual void appendTopLevelLinkAction(
ActionList &AL) {}
3817 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3833 virtual bool canUseBundlerUnbundler()
const {
return false; }
3837 bool isValid() {
return !ToolChains.empty(); }
3841 return AssociatedOffloadKind;
3846 virtual void pushForeignAction(
Action *A) {}
3851 class CudaActionBuilderBase :
public DeviceActionBuilder {
3855 bool CompileHostOnly =
false;
3856 bool CompileDeviceOnly =
false;
3858 bool EmitAsm =
false;
3868 TargetID(
const char *
ID) :
ID(
ID) {}
3869 operator const char *() {
return ID; }
3870 operator StringRef() {
return StringRef(
ID); }
3879 Action *CudaFatBinary =
nullptr;
3882 bool IsActive =
false;
3885 bool Relocatable =
false;
3892 enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
3893 UseCUIDKind UseCUID = CUID_Hash;
3896 StringRef FixedCUID;
3899 CudaActionBuilderBase(
Compilation &C, DerivedArgList &Args,
3902 OffloadingActionBuilder &OAB)
3903 : DeviceActionBuilder(
C, Args, Inputs, OFKind, OAB) {
3905 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3906 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3907 options::OPT_fno_gpu_rdc,
false);
3910 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3917 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3918 assert(!GpuArchList.empty() &&
3919 "We should have at least one GPU architecture.");
3923 if (!(IA->getType() == types::TY_CUDA ||
3924 IA->getType() == types::TY_HIP ||
3925 IA->getType() == types::TY_PP_HIP)) {
3928 return ABRT_Inactive;
3934 if (CompileHostOnly)
3935 return ABRT_Success;
3938 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3939 : types::TY_CUDA_DEVICE;
3940 std::string CUID = FixedCUID.str();
3942 if (UseCUID == CUID_Random)
3943 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
3945 else if (UseCUID == CUID_Hash) {
3947 llvm::MD5::MD5Result Hash;
3949 llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
3951 Hasher.update(RealPath);
3952 for (
auto *A : Args) {
3953 if (A->getOption().matches(options::OPT_INPUT))
3955 Hasher.update(A->getAsString(Args));
3958 CUID = llvm::utohexstr(Hash.low(),
true);
3963 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3964 CudaDeviceActions.push_back(
3965 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3968 return ABRT_Success;
3972 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3976 if (UA->getType() == types::TY_Object && !Relocatable)
3977 return ABRT_Inactive;
3979 CudaDeviceActions.clear();
3980 auto *IA = cast<InputAction>(UA->getInputs().back());
3981 std::string
FileName = IA->getInputArg().getAsString(Args);
3987 const StringRef LibFileExt =
".lib";
3988 if (IA->getType() == types::TY_Object &&
3989 (!llvm::sys::path::has_extension(FileName) ||
3991 llvm::sys::path::extension(FileName).drop_front()) !=
3993 llvm::sys::path::extension(FileName) == LibFileExt))
3994 return ABRT_Inactive;
3996 for (
auto Arch : GpuArchList) {
3997 CudaDeviceActions.push_back(UA);
3998 UA->registerDependentActionInfo(ToolChains[0], Arch,
3999 AssociatedOffloadKind);
4002 return ABRT_Success;
4005 return IsActive ? ABRT_Success : ABRT_Inactive;
4008 void appendTopLevelActions(
ActionList &AL)
override {
4010 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
4012 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
4017 if (CudaFatBinary) {
4019 CudaDeviceActions.clear();
4020 CudaFatBinary =
nullptr;
4024 if (CudaDeviceActions.empty())
4030 assert(CudaDeviceActions.size() == GpuArchList.size() &&
4031 "Expecting one action per GPU architecture.");
4032 assert(ToolChains.size() == 1 &&
4033 "Expecting to have a single CUDA toolchain.");
4034 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
4035 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
4037 CudaDeviceActions.clear();
4042 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
4044 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4062 assert(HostTC &&
"No toolchain for host compilation.");
4064 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
4068 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
4073 ToolChains.push_back(
4078 CompileHostOnly =
C.getDriver().offloadHostOnly();
4079 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
4080 EmitAsm = Args.getLastArg(options::OPT_S);
4081 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
4082 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
4083 StringRef UseCUIDStr = A->getValue();
4084 UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
4085 .Case(
"hash", CUID_Hash)
4086 .Case(
"random", CUID_Random)
4087 .Case(
"none", CUID_None)
4088 .Default(CUID_Invalid);
4089 if (UseCUID == CUID_Invalid) {
4090 C.getDriver().Diag(diag::err_drv_invalid_value)
4091 << A->getAsString(Args) << UseCUIDStr;
4092 C.setContainsError();
4098 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4099 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4100 options::OPT_no_offload_arch_EQ)) {
4101 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
4106 std::set<StringRef> GpuArchs;
4108 for (Arg *A : Args) {
4109 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
4110 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
4114 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
4115 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
4118 }
else if (ArchStr ==
"native") {
4119 const ToolChain &TC = *ToolChains.front();
4120 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
4123 << llvm::Triple::getArchTypeName(TC.
getArch())
4128 for (
auto GPU : *GPUsOrErr) {
4129 GpuArchs.insert(Args.MakeArgString(GPU));
4132 ArchStr = getCanonicalOffloadArch(ArchStr);
4133 if (ArchStr.empty()) {
4135 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
4136 GpuArchs.insert(ArchStr);
4137 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
4138 GpuArchs.erase(ArchStr);
4140 llvm_unreachable(
"Unexpected option.");
4146 if (ConflictingArchs) {
4147 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4148 << ConflictingArchs->first << ConflictingArchs->second;
4149 C.setContainsError();
4154 for (
auto Arch : GpuArchs)
4155 GpuArchList.push_back(Arch.data());
4160 if (GpuArchList.empty()) {
4161 if (ToolChains.front()->getTriple().isSPIROrSPIRV())
4164 GpuArchList.push_back(DefaultCudaArch);
4173 class CudaActionBuilder final :
public CudaActionBuilderBase {
4175 CudaActionBuilder(
Compilation &C, DerivedArgList &Args,
4177 OffloadingActionBuilder &OAB)
4178 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda, OAB) {
4182 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
4185 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
4191 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4193 const std::set<StringRef> &GpuArchs)
override {
4194 return std::nullopt;
4197 bool canUseBundlerUnbundler()
const override {
4198 return Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false);
4201 ActionBuilderReturnCode
4204 PhasesTy &Phases)
override {
4206 return ABRT_Inactive;
4210 if (CudaDeviceActions.empty())
4211 return ABRT_Success;
4213 assert(CudaDeviceActions.size() == GpuArchList.size() &&
4214 "Expecting one action per GPU architecture.");
4215 assert(!CompileHostOnly &&
4216 "Not expecting CUDA actions in host-only compilation.");
4226 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
4229 for (
auto Ph : Phases) {
4234 if (Ph > FinalPhase)
4237 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
4247 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
4251 Action *AssembleAction = CudaDeviceActions[I];
4252 assert(AssembleAction->
getType() == types::TY_Object);
4253 assert(AssembleAction->
getInputs().size() == 1);
4261 DeviceActions.push_back(
4267 if (!DeviceActions.empty()) {
4269 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
4271 if (!CompileDeviceOnly) {
4272 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
4276 CudaFatBinary =
nullptr;
4281 CudaDeviceActions.clear();
4285 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
4290 return ABRT_Success;
4294 "instructions should only occur "
4295 "before the backend phase!");
4298 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
4300 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
4301 C, Args, CurPhase, CudaDeviceActions[I]);
4305 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
4308 OffloadingActionBuilderRef.pushForeignAction(
4310 DDep, DDep.
getActions().front()->getType()));
4314 return ABRT_Success;
4319 class HIPActionBuilder final :
public CudaActionBuilderBase {
4327 std::optional<bool> BundleOutput;
4328 std::optional<bool> EmitReloc;
4331 HIPActionBuilder(
Compilation &C, DerivedArgList &Args,
4333 OffloadingActionBuilder &OAB)
4334 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP, OAB) {
4338 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
4339 options::OPT_fno_hip_emit_relocatable)) {
4340 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
4341 options::OPT_fno_hip_emit_relocatable,
false);
4345 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4346 <<
"-fhip-emit-relocatable"
4350 if (!CompileDeviceOnly) {
4351 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4352 <<
"-fhip-emit-relocatable"
4353 <<
"--cuda-device-only";
4358 if (Args.hasArg(options::OPT_gpu_bundle_output,
4359 options::OPT_no_gpu_bundle_output))
4360 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
4361 options::OPT_no_gpu_bundle_output,
true) &&
4362 (!EmitReloc || !*EmitReloc);
4365 bool canUseBundlerUnbundler()
const override {
return true; }
4367 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
4368 llvm::StringMap<bool> Features;
4375 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
4376 C.setContainsError();
4380 return Args.MakeArgStringRef(CanId);
4383 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4385 const std::set<StringRef> &GpuArchs)
override {
4389 ActionBuilderReturnCode
4392 PhasesTy &Phases)
override {
4394 return ABRT_Inactive;
4400 if (CudaDeviceActions.empty())
4401 return ABRT_Success;
4404 CudaDeviceActions.size() == GpuArchList.size()) &&
4405 "Expecting one action per GPU architecture.");
4406 assert(!CompileHostOnly &&
4407 "Not expecting HIP actions in host-only compilation.");
4409 bool ShouldLink = !EmitReloc || !*EmitReloc;
4412 !EmitAsm && ShouldLink) {
4418 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
4419 if (
C.getDriver().isUsingLTO(
true)) {
4423 AL.push_back(CudaDeviceActions[I]);
4426 CudaDeviceActions[I] =
4433 if (ToolChains.front()->getTriple().isSPIROrSPIRV()) {
4436 types::ID Output = Args.hasArg(options::OPT_S)
4438 : types::TY_LLVM_BC;
4444 AssociatedOffloadKind);
4445 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
4447 AssociatedOffloadKind);
4448 AL.push_back(AssembleAction);
4451 CudaDeviceActions[I] =
4462 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
4463 AssociatedOffloadKind);
4465 DDep, CudaDeviceActions[I]->getType());
4468 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
4471 types::TY_HIP_FATBIN);
4473 if (!CompileDeviceOnly) {
4474 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
4475 AssociatedOffloadKind);
4478 CudaFatBinary =
nullptr;
4483 CudaDeviceActions.clear();
4486 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
4489 return ABRT_Success;
4495 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
4496 auto LI = DeviceLinkerInputs.begin();
4497 for (
auto *A : CudaDeviceActions) {
4504 CudaDeviceActions.clear();
4505 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
4509 for (
Action *&A : CudaDeviceActions)
4510 A =
C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A,
4511 AssociatedOffloadKind);
4513 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
4515 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
4517 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
4518 AssociatedOffloadKind);
4520 DDep, CudaDeviceActions[I]->getType());
4524 CudaDeviceActions.clear();
4527 return (CompileDeviceOnly &&
4528 (CurPhase == FinalPhase ||
4534 void appendLinkDeviceActions(
ActionList &AL)
override {
4535 if (DeviceLinkerInputs.size() == 0)
4538 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
4539 "Linker inputs and GPU arch list sizes do not match.");
4545 for (
auto &LI : DeviceLinkerInputs) {
4547 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
4551 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
4555 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
4556 GpuArchList[I], AssociatedOffloadKind);
4558 DeviceLinkDeps, DeviceLinkAction->getType()));
4561 DeviceLinkerInputs.clear();
4564 if (Args.hasArg(options::OPT_emit_llvm)) {
4573 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
4576 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
4577 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
4578 AssociatedOffloadKind);
4581 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
4587 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
4594 class OpenMPActionBuilder final :
public DeviceActionBuilder {
4602 OpenMPActionBuilder(
Compilation &C, DerivedArgList &Args,
4604 OffloadingActionBuilder &OAB)
4605 : DeviceActionBuilder(
C, Args, Inputs,
Action::OFK_OpenMP, OAB) {}
4607 ActionBuilderReturnCode
4610 PhasesTy &Phases)
override {
4611 if (OpenMPDeviceActions.empty())
4612 return ABRT_Inactive;
4615 assert(OpenMPDeviceActions.size() == ToolChains.size() &&
4616 "Number of OpenMP actions and toolchains do not match.");
4621 assert(ToolChains.size() == DeviceLinkerInputs.size() &&
4622 "Toolchains and linker inputs sizes do not match.");
4623 auto LI = DeviceLinkerInputs.begin();
4624 for (
auto *A : OpenMPDeviceActions) {
4631 OpenMPDeviceActions.clear();
4632 return ABRT_Success;
4636 for (
Action *&A : OpenMPDeviceActions)
4637 A =
C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A);
4639 return ABRT_Success;
4642 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
4645 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
4646 OpenMPDeviceActions.clear();
4647 for (
unsigned I = 0; I < ToolChains.size(); ++I)
4648 OpenMPDeviceActions.push_back(
4649 C.MakeAction<
InputAction>(IA->getInputArg(), IA->getType()));
4650 return ABRT_Success;
4654 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
4655 OpenMPDeviceActions.clear();
4656 if (
auto *IA = dyn_cast<InputAction>(UA->getInputs().back())) {
4657 std::string
FileName = IA->getInputArg().getAsString(Args);
4661 if (IA->getType() == types::TY_Object &&
4662 (!llvm::sys::path::has_extension(FileName) ||
4664 llvm::sys::path::extension(FileName).drop_front()) !=
4666 return ABRT_Inactive;
4668 for (
unsigned I = 0; I < ToolChains.size(); ++I) {
4669 OpenMPDeviceActions.push_back(UA);
4670 UA->registerDependentActionInfo(
4673 return ABRT_Success;
4680 if (isa<CompileJobAction>(HostAction)) {
4682 assert(ToolChains.size() == OpenMPDeviceActions.size() &&
4683 "Toolchains and device action sizes do not match.");
4687 auto TC = ToolChains.begin();
4688 for (
Action *&A : OpenMPDeviceActions) {
4689 assert(isa<CompileJobAction>(A));
4696 return ABRT_Success;
4699 void appendTopLevelActions(
ActionList &AL)
override {
4700 if (OpenMPDeviceActions.empty())
4704 assert(OpenMPDeviceActions.size() == ToolChains.size() &&
4705 "Number of OpenMP actions and toolchains do not match.");
4708 auto TI = ToolChains.begin();
4709 for (
auto *A : OpenMPDeviceActions) {
4716 OpenMPDeviceActions.clear();
4719 void appendLinkDeviceActions(
ActionList &AL)
override {
4720 assert(ToolChains.size() == DeviceLinkerInputs.size() &&
4721 "Toolchains and linker inputs sizes do not match.");
4724 auto TC = ToolChains.begin();
4725 for (
auto &LI : DeviceLinkerInputs) {
4726 auto *DeviceLinkAction =
4729 DeviceLinkDeps.
add(*DeviceLinkAction, **TC,
nullptr,
4732 DeviceLinkAction->getType()));
4735 DeviceLinkerInputs.clear();
4749 for (
unsigned I = 0; I < ToolChains.size(); ++I) {
4754 if (!ToolChains[I]->getTriple().isSPIROrSPIRV()) {
4760 DeviceLinkerInputs[I].push_back(AA);
4762 DeviceLinkerInputs[I].push_back(DA);
4770 for (
auto TI = OpenMPTCRange.first, TE = OpenMPTCRange.second; TI != TE;
4772 ToolChains.push_back(TI->second);
4774 DeviceLinkerInputs.resize(ToolChains.size());
4778 bool canUseBundlerUnbundler()
const override {
4787 class SYCLActionBuilder final :
public DeviceActionBuilder {
4789 bool CompileDeviceOnly =
false;
4792 bool WrapDeviceOnlyBinary =
false;
4795 bool DeviceCodeSplit =
false;
4802 struct DeviceTargetInfo {
4803 DeviceTargetInfo(
const ToolChain *TC,
const char *BA)
4804 : TC(TC), BoundArch(BA) {}
4807 const char *BoundArch;
4819 Action *SYCLLinkBinary =
nullptr;
4827 SYCLFinalDeviceList;
4837 types::ID FPGAOutType = types::TY_FPGA_AOCX;
4857 JobAction *finalizeNVPTXDependences(
Action *Input,
const llvm::Triple &TT) {
4858 auto *BA =
C.getDriver().ConstructPhaseAction(
4860 if (TT.getOS() != llvm::Triple::NVCL) {
4861 auto *AA =
C.getDriver().ConstructPhaseAction(
4865 types::TY_CUDA_FATBIN);
4867 return cast<JobAction>(BA);
4871 const llvm::Triple &TT) {
4872 auto *BA =
C.getDriver().ConstructPhaseAction(
4876 BA, AssociatedOffloadKind);
4883 return HIPFatBinary;
4886 Action *ExternalCudaAction =
nullptr;
4889 SYCLActionBuilder(
Compilation &C, DerivedArgList &Args,
4891 OffloadingActionBuilder &OAB)
4892 : DeviceActionBuilder(
C, Args, Inputs,
Action::OFK_SYCL, OAB),
4893 SYCLInstallation(
C.getDriver()) {}
4895 void withBoundArchForToolChain(
const ToolChain *TC,
4896 llvm::function_ref<
void(
const char *)> Op) {
4897 for (
auto &A : GpuArchList) {
4899 Op(A.second ? Args.MakeArgString(A.second) :
nullptr);
4908 void pushForeignAction(
Action *A)
override {
4912 ExternalCudaAction = A;
4915 ActionBuilderReturnCode
4918 PhasesTy &Phases)
override {
4919 bool SYCLDeviceOnly =
C.getDriver().offloadDeviceOnly();
4923 bool IsPreprocessOnly =
4924 Args.getLastArg(options::OPT_E) ||
4925 Args.getLastArg(options::OPT__SLASH_EP, options::OPT__SLASH_P) ||
4926 Args.getLastArg(options::OPT_M, options::OPT_MM);
4927 if (IsPreprocessOnly) {
4928 for (
auto TargetActionInfo :
4929 llvm::zip(SYCLDeviceActions, SYCLTargetInfoList)) {
4930 Action *&A = std::get<0>(TargetActionInfo);
4931 auto &
TargetInfo = std::get<1>(TargetActionInfo);
4932 A =
C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A,
4933 AssociatedOffloadKind);
4943 return SYCLDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
4951 if (SYCLDeviceActions.empty())
4952 return ABRT_Success;
4954 Action *DeviceCompilerInput =
nullptr;
4955 const DeviceTargetInfo &DevTarget = SYCLTargetInfoList.back();
4956 for (
auto TargetActionInfo :
4957 llvm::zip(SYCLDeviceActions, SYCLTargetInfoList)) {
4958 Action *&A = std::get<0>(TargetActionInfo);
4959 auto &
TargetInfo = std::get<1>(TargetActionInfo);
4960 types::ID OutputType = types::TY_LLVM_BC;
4961 if ((SYCLDeviceOnly || Args.hasArg(options::OPT_emit_llvm)) &&
4962 Args.hasArg(options::OPT_S))
4963 OutputType = types::TY_LLVM_IR;
4967 Args.getLastArgValue(options::OPT_fsycl_device_obj_EQ)
4968 .equals_insensitive(
"spirv")) {
4969 auto *CompileAction =
4976 if (Args.hasArg(options::OPT_fsyntax_only))
4977 OutputType = types::TY_Nothing;
4985 TargetTriple.isSPIRAOT() && FinalPhase !=
phases::Link) {
4987 CAList.push_back(A);
4989 appendSYCLDeviceLink(CAList,
TargetInfo.TC, DeviceLinkActions,
4995 A = DeviceLinkActions.back();
4997 DeviceCompilerInput = A;
4999 DA.
add(*DeviceCompilerInput, *DevTarget.TC, DevTarget.BoundArch,
5001 return SYCLDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
5006 return ABRT_Inactive;
5011 if (!SYCLDeviceActions.empty()) {
5012 assert(SYCLDeviceActions.size() == DeviceLinkerInputs.size() &&
5013 "Device action and device linker inputs sizes do not match.");
5015 for (
auto TargetAction :
5016 llvm::zip(DeviceLinkerInputs, SYCLDeviceActions)) {
5017 ActionList &LinkerList = std::get<0>(TargetAction);
5018 Action *A = std::get<1>(TargetAction);
5020 LinkerList.push_back(A);
5024 if (ExternalCudaAction) {
5025 assert(DeviceLinkerInputs.size() == 1 &&
5026 "Number of SYCL actions and toolchains/boundarch pairs do not "
5028 DeviceLinkerInputs[0].push_back(ExternalCudaAction);
5029 ExternalCudaAction =
nullptr;
5032 if (CompileDeviceOnly && !SYCLDeviceActions.empty()) {
5033 for (
auto SDA : SYCLDeviceActions)
5034 SYCLLinkBinaryList.push_back(SDA);
5037 SYCLDeviceActions.clear();
5039 if (WrapDeviceOnlyBinary)
5040 return ABRT_Ignore_Host;
5042 C.MakeAction<
LinkJobAction>(SYCLLinkBinaryList, types::TY_Image);
5046 return ABRT_Ignore_Host;
5051 SYCLDeviceActions.clear();
5052 return ABRT_Success;
5056 for (
auto TargetActionInfo :
5057 llvm::zip(SYCLDeviceActions, SYCLTargetInfoList)) {
5058 auto &
TargetInfo = std::get<1>(TargetActionInfo);
5063 Action *&A = std::get<0>(TargetActionInfo);
5064 A =
C.getDriver().ConstructPhaseAction(C, Args, CurPhase, A,
5065 AssociatedOffloadKind);
5068 return ABRT_Success;
5071 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
5074 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
5075 SYCLDeviceActions.clear();
5080 return ABRT_Inactive;
5082 std::string InputName = IA->getInputArg().getAsString(Args);
5085 if (
C.getDriver().getOffloadStaticLibSeen() &&
5086 IA->getType() == types::TY_Object &&
isObjectFile(InputName))
5087 return ABRT_Inactive;
5090 if (IA->getType() == types::TY_Object && !
isObjectFile(InputName))
5091 return ABRT_Inactive;
5093 for (
auto &
TargetInfo : SYCLTargetInfoList) {
5095 SYCLDeviceActions.push_back(
5096 C.MakeAction<
InputAction>(IA->getInputArg(), IA->getType()));
5098 return ABRT_Success;
5102 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
5103 SYCLDeviceActions.clear();
5104 if (
auto *IA = dyn_cast<InputAction>(UA->getInputs().back())) {
5108 return ABRT_Inactive;
5110 std::string
FileName = IA->getInputArg().getAsString(Args);
5114 if (IA->getType() == types::TY_Object) {
5116 return ABRT_Inactive;
5119 const auto *TC = ToolChains.front();
5121 llvm::Triple::SPIRSubArch_fpga &&
5124 .isWindowsMSVCEnvironment()))
5125 FPGAObjectInputs.push_back(IA);
5129 for (
auto &
TargetInfo : SYCLTargetInfoList) {
5130 SYCLDeviceActions.push_back(UA);
5134 return ABRT_Success;
5136 return ABRT_Success;
5139 void appendLinkDeviceActions(
ActionList &AL)
override {
5140 if (DeviceLinkerInputs.size() == 0)
5143 for (
const auto &LinkInputEnum : enumerate(DeviceLinkerInputs)) {
5144 auto &LI = LinkInputEnum.value();
5145 int Index = LinkInputEnum.index();
5146 const ToolChain *TC = SYCLTargetInfoList[Index].TC;
5147 const char *BoundArch = SYCLTargetInfoList[Index].BoundArch;
5149 auto TripleIt = llvm::find_if(SYCLTripleList, [&](
auto &SYCLTriple) {
5152 if (TripleIt == SYCLTripleList.end()) {
5166 appendSYCLDeviceLink(LI, TC, AL, BoundArch,
5167 WrapDeviceOnlyBinary,
5170 DeviceLinkerInputs.clear();
5175 if (!WrapDeviceOnlyBinary)
5187 void appendTopLevelLinkAction(
ActionList &AL)
override {
5188 if (!SYCLLinkBinary)
5192 withBoundArchForToolChain(ToolChains.front(), [&](
const char *BoundArch) {
5193 Dep.add(*SYCLLinkBinary, *ToolChains.front(), BoundArch,
5197 SYCLLinkBinary =
nullptr;
5200 void appendTopLevelActions(
ActionList &AL)
override {
5202 if (!SYCLDeviceActions.empty()) {
5203 assert(SYCLDeviceActions.size() == SYCLTargetInfoList.size() &&
5204 "Number of SYCL actions and toolchains/boundarch pairs do not "
5208 for (
auto TargetActionInfo :
5209 llvm::zip(SYCLDeviceActions, SYCLTargetInfoList)) {
5210 Action *A = std::get<0>(TargetActionInfo);
5211 DeviceTargetInfo &
TargetInfo = std::get<1>(TargetActionInfo);
5215 if (ExternalCudaAction) {
5217 SYCLTargetInfoList.size() == 1 &&
5218 "Number of SYCL actions and toolchains/boundarch pairs do not "
5223 LinkObjects.push_back(
5225 LinkObjects.push_back(ExternalCudaAction);
5226 Action *DeviceLinkAction =
5234 ExternalCudaAction =
nullptr;
5240 SYCLDeviceActions.clear();
5263 const char *BoundArch,
bool SkipWrapper,
5264 bool AddOffloadAction =
false) {
5266 const char *BoundArch) {
5267 if (AddOffloadAction) {
5270 DeviceLinkActions.push_back(
5273 DeviceLinkActions.push_back(A);
5289 auto IsNVPTX = TargetTriple.isNVPTX();
5290 auto IsAMDGCN = TargetTriple.isAMDGCN();
5291 auto IsSPIR = TargetTriple.isSPIROrSPIRV();
5292 bool IsSpirvAOT = TargetTriple.isSPIRAOT();
5293 const bool IsSYCLNativeCPU =
5296 for (
const auto &Input : ListIndex) {
5297 if (TargetTriple.getSubArch() == llvm::Triple::SPIRSubArch_fpga &&
5299 assert(BoundArch ==
nullptr &&
5300 "fpga triple bounded arch not nullptr");
5302 if (Input->
getType() == types::TY_FPGA_AOCO) {
5303 FPGADeviceLibObjects.push_back(Input);
5308 if (Args.hasArg(options::OPT_fintelfpga)) {
5309 if (Input->
getType() == types::TY_FPGA_AOCR ||
5310 Input->
getType() == types::TY_FPGA_AOCR_EMU ||
5311 Input->
getType() == types::TY_FPGA_AOCX)
5314 FPGAAOCDevices.push_back(Input);
5316 llvm_unreachable(
"Unexpected FPGA input type.");
5324 LinkObjects.push_back(Input);
5332 Input, Input->
getType() == types::TY_Tempfilelist
5333 ? types::TY_Tempfilelist
5334 : types::TY_LLVM_BC);
5335 LinkObjects.push_back(ConvertSPIRVAction);
5339 if (FPGAAOCDevices.size()) {
5340 assert(FPGAAOCDevices.size() == FPGAAOCArchives.size() &&
5341 "Unexpected number of AOC binaries");
5346 for (
auto AOCRItem : llvm::zip(FPGAAOCArchives, FPGAAOCDevices)) {
5347 Action *Archive = std::get<0>(AOCRItem);
5351 Archive, types::TY_Tempfilelist);
5355 UnbundleAction, types::TY_Tempfilelist, types::TY_Tempfilelist);
5362 if (
Device->getType() == types::TY_FPGA_AOCX) {
5364 Device, types::TY_Tempfilelist, types::TY_Tempfilelist);
5368 ActionList WrapperItems({RenameAction, RenameUnbundle});
5370 WrapperItems, types::TY_Object);
5371 addDeps(DeviceWrappingAction, TC, BoundArch);
5373 auto *FPGAAOTAction =
5376 FPGAAOTAction, types::TY_Tempfilelist, types::TY_Tempfilelist);
5377 RenameAction->addRenameColumnTform(
5380 ActionList WrapperItems({RenameAction, RenameUnbundle});
5382 WrapperItems, types::TY_Object);
5384 Action *DeviceAction = DeviceWrappingAction;
5385 if (Args.hasArg(options::OPT_fsycl_link_EQ)) {
5386 if (
auto *OWA = dyn_cast<OffloadWrapperJobAction>(DeviceAction))
5387 OWA->setCompileStep(
false);
5389 BundlingActions.push_back(DeviceWrappingAction);
5395 BundlingActions, types::TY_Object);
5396 if (
auto *OWA = dyn_cast<OffloadWrapperJobAction>(DeviceAction))
5398 Action *CompiledDeviceAction =
5401 addDeps(CompiledDeviceAction, TC, BoundArch);
5403 addDeps(DeviceAction, TC, BoundArch);
5407 for (
const auto &A : SYCLFinalDeviceList) {
5412 auto Input(A.first);
5413 for (StringRef TargetString : A.second) {
5416 if (InputType == types::TY_Archive)
5417 InputType = types::TY_Tempfilelist;
5421 UA->setTargetString(TargetString.str());
5424 addDeps(UA, TC,
"");
5427 if (!LinkObjects.empty()) {
5516 Action *DeviceLinkAction =
5518 FullLinkObjects.push_back(DeviceLinkAction);
5520 FullLinkObjects = LinkObjects;
5526 bool SYCLDeviceLibLinked =
false;
5527 if (IsSPIR || IsNVPTX) {
5530 Args.hasFlag(options::OPT_fsycl_device_lib_jit_link,
5531 options::OPT_fno_sycl_device_lib_jit_link,
false);
5532 bool UseAOTLink = IsSPIR && (IsSpirvAOT || !UseJitLink);
5533 SYCLDeviceLibLinked = addSYCLDeviceLibs(
5534 TC, SYCLDeviceLibs, UseAOTLink,
5535 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment());
5537 if (IsSYCLNativeCPU) {
5538 SYCLDeviceLibLinked |= addSYCLNativeCPULibs(TC, SYCLDeviceLibs);
5542 for (
Action *FullLinkObject : FullLinkObjects) {
5543 if (FullLinkObject->getKind() ==
5546 Action *FullDeviceLinkAction =
nullptr;
5549 if (SYCLDeviceLibLinked) {
5553 SYCLDeviceLibs.insert(SYCLDeviceLibs.begin(), FullLinkObject);
5555 SYCLDeviceLibs, types::TY_LLVM_BC);
5557 FullDeviceLinkAction = FullLinkObject;
5559 ActionList DeviceCodeAndSYCLLibs{FullDeviceLinkAction,
5562 DeviceCodeAndSYCLLibs, types::TY_LLVM_BC);
5564 if (FullDeviceLinkAction->
getType() == types::TY_Tempfilelist) {
5568 auto *ParallelLinkDeviceCode =
5570 cast<JobAction>(FullDeviceLinkAction), LinkDeviceCode);
5575 std::function<void(
const Action *)> traverseActionTree =
5578 for (
const auto &Input : Act->getInputs()) {
5579 traverseActionTree(Input);
5582 traverseActionTree(LinkSYCLLibs);
5584 ParallelLinkDeviceCode};
5585 auto *ReplaceFilesAction =
5587 TformInputs, types::TY_Tempfilelist,
5588 types::TY_Tempfilelist);
5592 ReplaceFilesAction->addExtractColumnTform(
5594 FullDeviceLinkAction = ReplaceFilesAction;
5597 FullDeviceLinkAction = LinkDeviceCode;
5601 FullDeviceLinkAction = FullLinkObject;
5605 bool IsAOT = IsNVPTX || IsAMDGCN || IsSpirvAOT || IsSYCLNativeCPU;
5609 types::ID PostLinkOutType = IsSPIR || IsSYCLNativeCPU
5610 ? types::TY_Tempfiletable
5611 : types::TY_LLVM_BC;
5612 auto createPostLinkAction = [&]() {
5615 FullDeviceLinkAction, PostLinkOutType, types::TY_Tempfiletable);
5617 return TypedPostLinkAction;
5619 Action *PostLinkAction = createPostLinkAction();
5620 if (IsSYCLNativeCPU) {
5625 FullDeviceLinkAction, types::TY_PP_Asm);
5628 addDeps(AsmAct, TC, BoundArch);
5630 PostLinkAction, types::TY_Object);
5631 addDeps(DeviceWrappingAction, TC, BoundArch);
5634 if ((IsNVPTX || IsAMDGCN) &&
5635 Args.hasArg(options::OPT_fsycl_embed_ir)) {
5642 PostLinkAction, types::TY_Object,
true);
5643 addDeps(WrapBitcodeAction, TC, BoundArch);
5645 bool NoRDCFatStaticArchive =
5647 FullDeviceLinkAction->
getType() == types::TY_Tempfilelist;
5648 if (NoRDCFatStaticArchive)
5650 cast<JobAction>(FullDeviceLinkAction),
5651 cast<JobAction>(PostLinkAction));
5653 auto createExtractIRFilesAction = [&]() {
5654 auto *TypedExtractIRFilesAction =
5657 IsSPIR ? types::TY_Tempfilelist : PostLinkAction->
getType(),
5658 types::TY_Tempfilelist);
5662 return TypedExtractIRFilesAction;
5665 Action *ExtractIRFilesAction = createExtractIRFilesAction();
5667 if (IsNVPTX || IsAMDGCN) {
5669 IsNVPTX ? finalizeNVPTXDependences(ExtractIRFilesAction,
5671 : finalizeAMDGCNDependences(ExtractIRFilesAction,
5674 cast<JobAction>(ExtractIRFilesAction), FinAction);
5676 ActionList TformInputs{PostLinkAction, ForEachWrapping};
5678 TformInputs, types::TY_Tempfiletable, types::TY_Tempfiletable);
5683 WrapperInputs.push_back(ReplaceFilesAction);
5685 if (NoRDCFatStaticArchive) {
5687 cast<JobAction>(FullDeviceLinkAction),
5688 cast<JobAction>(ExtractIRFilesAction));
5690 auto *MergeAllTablesIntoOne =
5692 types::TY_Tempfilelist,
5693 types::TY_Tempfilelist);
5694 MergeAllTablesIntoOne->addMergeTform(
5696 ExtractIRFilesAction = MergeAllTablesIntoOne;
5701 ExtractIRFilesAction, types::TY_Tempfilelist);
5705 types::ID OutType = types::TY_Tempfilelist;
5706 if (!DeviceCodeSplit) {
5707 OutType = (TargetTriple.getSubArch() ==
5708 llvm::Triple::SPIRSubArch_fpga)
5715 BEInputs.push_back(BuildCodeAction);
5721 BEInputs.push_back(UnbundleAction);
5726 for (
Action *A : FPGAObjectInputs)
5727 unbundleAdd(A, types::TY_FPGA_Dependencies);
5728 for (
Action *A : FPGAArchiveInputs)
5729 unbundleAdd(A, types::TY_FPGA_Dependencies_List);
5730 for (
const auto &A : FPGADeviceLibObjects)
5731 BEInputs.push_back(A);
5735 if (NoRDCFatStaticArchive) {
5736 auto *MergeAllTablesIntoOne =
5738 types::TY_Tempfilelist,
5739 types::TY_Tempfilelist);
5740 MergeAllTablesIntoOne->addMergeTform(
5742 PostLinkAction = MergeAllTablesIntoOne;
5744 ActionList TformInputs{PostLinkAction, BuildCodeAction};
5746 TformInputs, types::TY_Tempfiletable, types::TY_Tempfiletable);
5750 WrapperInputs.push_back(ReplaceFilesAction);
5754 withBoundArchForToolChain(TC, [&](
const char *BoundArch) {
5755 addDeps(WrapperInputs.front(), TC, BoundArch);
5764 WrapperInputs, types::TY_Object);
5768 if (TargetTriple.getSubArch() == llvm::Triple::SPIRSubArch_fpga) {
5769 Action *DeviceAction = DeviceWrappingAction;
5770 if (Args.hasArg(options::OPT_fsycl_link_EQ)) {
5772 if (
auto *OWA = dyn_cast<OffloadWrapperJobAction>(DeviceAction))
5773 OWA->setCompileStep(
false);
5775 BundlingActions.push_back(DeviceWrappingAction);
5781 BundlingActions, types::TY_Object);
5782 if (
auto *OWA = dyn_cast<OffloadWrapperJobAction>(DeviceAction))
5784 Action *CompiledDeviceAction =
5787 addDeps(CompiledDeviceAction, TC,
nullptr);
5789 addDeps(DeviceAction, TC,
nullptr);
5792 (TargetTriple.getSubArch() == llvm::Triple::SPIRSubArch_gen &&
5793 BoundArch !=
nullptr);
5794 addDeps(DeviceWrappingAction, TC, AddBA ? BoundArch :
nullptr);
5797 withBoundArchForToolChain(TC, [&](
const char *BoundArch) {
5798 addDeps(DeviceWrappingAction, TC, BoundArch);
5805 bool addSYCLNativeCPULibs(
const ToolChain *TC,
5807 std::string LibSpirvFile;
5808 if (Args.hasArg(options::OPT_fsycl_libspirv_path_EQ)) {
5810 Args.getLastArgValue(options::OPT_fsycl_libspirv_path_EQ).str();
5811 if (llvm::sys::fs::exists(ProvidedPath))
5812 LibSpirvFile = ProvidedPath;
5818 llvm::sys::path::append(WithoutInstallPath, Twine(
"../../clc"));
5819 LibraryPaths.emplace_back(WithoutInstallPath.c_str());
5823 llvm::sys::path::append(WithInstallPath, Twine(
"../../../share/clc"));
5824 LibraryPaths.emplace_back(WithInstallPath.c_str());
5829 std::string LibSpirvTargetName =
5831 ?
"remangled-l32-signed_char.libspirv-"
5832 :
"remangled-l64-signed_char.libspirv-";
5835 for (StringRef LibraryPath : LibraryPaths) {
5837 llvm::sys::path::append(LibSpirvTargetFile, LibSpirvTargetName);
5838 if (llvm::sys::fs::exists(LibSpirvTargetFile) ||
5839 Args.hasArg(options::OPT__HASH_HASH_HASH)) {
5840 LibSpirvFile = std::string(LibSpirvTargetFile.str());
5846 if (!LibSpirvFile.empty()) {
5847 Arg *LibClcInputArg =
MakeInputArg(Args,
C.getDriver().getOpts(),
5848 Args.MakeArgString(LibSpirvFile));
5849 auto *SYCLLibClcInputAction =
5850 C.MakeAction<
InputAction>(*LibClcInputArg, types::TY_LLVM_BC);
5851 DeviceLinkObjects.push_back(SYCLLibClcInputAction);
5858 bool isSpirvAOT,
bool isMSVCEnv) {
5859 int NumOfDeviceLibLinked = 0;
5867 for (
const auto &DeviceLib : DeviceLibraries) {
5868 bool LibLocSelected =
false;
5869 for (
const auto &LLCandidate : LibLocCandidates) {
5873 llvm::sys::path::append(LibName, DeviceLib);
5874 if (llvm::sys::fs::exists(LibName)) {
5875 ++NumOfDeviceLibLinked;
5877 Args.MakeArgString(LibName));
5881 llvm::Triple::SPIRSubArch_fpga)) {
5882 auto *SYCLDeviceLibsInputAction =
5883 C.MakeAction<
InputAction>(*InputArg, types::TY_Object);
5884 auto *SYCLDeviceLibsUnbundleAction =
5886 SYCLDeviceLibsInputAction);
5890 SYCLDeviceLibsUnbundleAction->registerDependentActionInfo(
5893 Dep.
add(*SYCLDeviceLibsUnbundleAction, *TC,
"",
5895 auto *SYCLDeviceLibsDependenciesAction =
5897 Dep, SYCLDeviceLibsUnbundleAction->
getType());
5898 DeviceLinkObjects.push_back(SYCLDeviceLibsDependenciesAction);
5902 auto *SYCLDeviceLibsInputAction =
5903 C.MakeAction<
InputAction>(*InputArg, types::TY_LLVM_BC);
5904 DeviceLinkObjects.push_back(SYCLDeviceLibsInputAction);
5906 if (!LibLocSelected)
5907 LibLocSelected = !LibLocSelected;
5915 if (TC->
getTriple().isNVPTX() && NumOfDeviceLibLinked) {
5916 std::string LibSpirvFile;
5917 if (Args.hasArg(options::OPT_fsycl_libspirv_path_EQ)) {
5919 Args.getLastArgValue(options::OPT_fsycl_libspirv_path_EQ).str();
5920 if (llvm::sys::fs::exists(ProvidedPath))
5921 LibSpirvFile = ProvidedPath;
5927 llvm::sys::path::append(WithoutInstallPath, Twine(
"../../clc"));
5928 LibraryPaths.emplace_back(WithoutInstallPath.c_str());
5932 llvm::sys::path::append(WithInstallPath, Twine(
"../../../share/clc"));
5933 LibraryPaths.emplace_back(WithInstallPath.c_str());
5936 std::string LibSpirvTargetName =
5938 ?
"remangled-l32-signed_char.libspirv-nvptx64-nvidia-cuda."
5940 :
"remangled-l64-signed_char.libspirv-nvptx64-nvidia-cuda."
5943 for (StringRef LibraryPath : LibraryPaths) {
5945 llvm::sys::path::append(LibSpirvTargetFile, LibSpirvTargetName);
5946 if (llvm::sys::fs::exists(LibSpirvTargetFile) ||
5947 Args.hasArg(options::OPT__HASH_HASH_HASH)) {
5948 LibSpirvFile = std::string(LibSpirvTargetFile.str());
5954 if (!LibSpirvFile.empty()) {
5955 Arg *LibClcInputArg =
MakeInputArg(Args,
C.getDriver().getOpts(),
5956 Args.MakeArgString(LibSpirvFile));
5957 auto *SYCLLibClcInputAction =
5958 C.MakeAction<
InputAction>(*LibClcInputArg, types::TY_LLVM_BC);
5959 DeviceLinkObjects.push_back(SYCLLibClcInputAction);
5964 for (
const auto &LinkInputEnum : enumerate(DeviceLinkerInputs)) {
5965 const char *BoundArch =
5966 SYCLTargetInfoList[LinkInputEnum.index()].BoundArch;
5967 std::string LibDeviceFile =
5969 if (!LibDeviceFile.empty()) {
5970 Arg *CudaDeviceLibInputArg =
5972 Args.MakeArgString(LibDeviceFile));
5973 auto *SYCLDeviceLibInputAction =
C.MakeAction<
InputAction>(
5974 *CudaDeviceLibInputArg, types::TY_LLVM_BC);
5975 DeviceLinkObjects.push_back(SYCLDeviceLibInputAction);
5979 return NumOfDeviceLibLinked != 0;
5983 for (
auto &SAI : SYCLAOTInputs) {
5985 std::string FN(SAI.second);
5986 const char *FNStr = Args.MakeArgString(FN);
5987 Arg *myArg = Args.MakeSeparateArg(
5988 nullptr,
C.getDriver().getOpts().getOption(options::OPT_INPUT),
5991 C.MakeAction<
InputAction>(*myArg, types::TY_SYCL_FATBIN);
5992 auto *DeviceWrappingAction =
5996 llvm::Triple TT(SAI.first);
5998 auto SYCLDeviceTC = llvm::find_if(
5999 ToolChains, [&](
auto &TC) {
return TC->
getTriple() == TT; });
6000 assert(SYCLDeviceTC != ToolChains.end() &&
6001 "No toolchain found for this AOT input");
6003 DA.
add(*DeviceWrappingAction, **SYCLDeviceTC,
6010 for (
auto &
TargetInfo : SYCLTargetInfoList) {
6013 DeviceLinkerInputs[I++].push_back(DA);
6023 bool initializeGpuArchMap() {
6024 const OptTable &Opts =
C.getDriver().getOpts();
6025 for (
auto *A : Args) {
6027 llvm::Triple *TargetBE =
nullptr;
6029 auto GetTripleIt = [&,
this](llvm::StringRef Triple) {
6030 llvm::Triple TargetTriple{Triple};
6031 auto TripleIt = llvm::find_if(SYCLTripleList, [&](
auto &SYCLTriple) {
6032 return SYCLTriple == TargetTriple;
6034 return TripleIt != SYCLTripleList.end() ? &*TripleIt :
nullptr;
6037 if (A->getOption().matches(options::OPT_Xsycl_backend_EQ)) {
6038 TargetBE = GetTripleIt(A->getValue(0));
6041 Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
6044 }
else if (A->getOption().matches(options::OPT_Xsycl_backend)) {
6045 if (SYCLTripleList.size() > 1) {
6046 C.getDriver().Diag(diag::err_drv_Xsycl_target_missing_triple)
6047 << A->getSpelling();
6051 TargetBE = &SYCLTripleList.front();
6052 Index = Args.getBaseArgs().MakeIndex(A->getValue(0));
6056 auto ParsedArg = Opts.ParseOneArg(Args, Index);
6060 ParsedArg->getOption().matches(options::OPT_offload_arch_EQ)) {
6061 const char *ArchStr = ParsedArg->getValue(0);
6062 if (TargetBE->isNVPTX()) {
6066 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch)
6071 }
else if (TargetBE->isAMDGCN()) {
6072 llvm::StringMap<bool> Features;
6075 ArchStr, &Features);
6077 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
6081 ArchStr = Args.MakeArgStringRef(CanId);
6084 GpuArchList.emplace_back(*TargetBE, ArchStr);
6090 for (
auto &Triple : SYCLTripleList) {
6092 if (Triple.isNVPTX() && llvm::none_of(GpuArchList, [&](
auto &
P) {
6093 return P.first.isNVPTX();
6096 GpuArchList.emplace_back(Triple, DefaultArch);
6100 if (Triple.isAMDGCN() && llvm::none_of(GpuArchList, [&](
auto &
P) {
6101 return P.first.isAMDGCN();
6103 C.getDriver().Diag(clang::diag::err_drv_sycl_missing_amdgpu_arch)
6104 << (SYCLTripleList.size() > 1) << Triple.str();
6116 checkForOffloadMismatch(
Compilation &C, DerivedArgList &Args,
6118 if (Targets.empty())
6125 for (StringRef OLArg : OffloadLibArgs) {
6127 for (
auto &Section : Sections) {
6130 std::string Prefix(
"sycl-");
6131 if (Section.compare(0, Prefix.length(), Prefix) != 0)
6134 std::string Arch = Section.substr(Prefix.length());
6138 if (Arch.compare(0, 4,
"fpga") == 0)
6139 Arch =
C.getDriver().MakeSYCLDeviceTriple(
"spir64_fpga").str();
6141 if (std::find(UniqueSections.begin(), UniqueSections.end(), Arch) ==
6142 UniqueSections.end())
6143 UniqueSections.push_back(Arch);
6147 if (!UniqueSections.size())
6150 for (
auto &SyclTarget : Targets) {
6151 std::string SectionTriple = SyclTarget.TC->getTriple().str();
6152 if (SyclTarget.BoundArch) {
6153 SectionTriple +=
"-";
6154 SectionTriple += SyclTarget.BoundArch;
6157 if (std::find(UniqueSections.begin(), UniqueSections.end(),
6158 SectionTriple) != UniqueSections.end())
6163 if (SyclTarget.TC->getTriple().isSPIROrSPIRV()) {
6164 bool SectionFound =
false;
6165 for (
auto Section : UniqueSections) {
6170 for (
auto ArchStr : ArchList) {
6171 std::string Arch(ArchStr +
"_image");
6172 if (Section.find(Arch) != std::string::npos) {
6173 SectionFound =
true;
6184 for (std::string Section : UniqueSections) {
6186 ArchListStr +=
", ";
6187 ArchListStr += Section;
6191 C.getDriver().Diag(diag::err_drv_no_rdc_sycl_target_missing)
6192 << SectionTriple << ArchListStr;
6193 C.setContainsError();
6195 C.getDriver().Diag(diag::warn_drv_sycl_target_missing)
6196 << SectionTriple << ArchListStr;
6204 void checkForMisusedAddDefaultSpecConstsImageFlag(
6207 if (!Args.hasFlag(options::OPT_fsycl_add_default_spec_consts_image,
6208 options::OPT_fno_sycl_add_default_spec_consts_image,
6212 bool foundAOT = std::any_of(
6213 Targets.begin(), Targets.end(), [](
const DeviceTargetInfo &DTI) {
6214 llvm::Triple T = DTI.TC->getTriple();
6216 T.getSubArch() == llvm::Triple::SPIRSubArch_fpga ||
6217 T.getSubArch() == llvm::Triple::SPIRSubArch_gen ||
6218 T.getSubArch() == llvm::Triple::SPIRSubArch_x86_64;
6220 return T.isNVPTX() || T.isAMDGCN() || isSpirvAOT;
6225 diag::warn_drv_fsycl_add_default_spec_consts_image_flag_in_non_AOT);
6234 const StringRef &Input) {
6237 for (
auto S : Sections) {
6240 for (
auto A : ArchList) {
6241 std::string Arch(
"sycl-" + A +
"_image");
6242 if (S.find(Arch) != std::string::npos)
6243 FinalDeviceSections.push_back(S);
6246 return FinalDeviceSections;
6251 void populateSYCLDeviceTraitsMacrosArgs(
6254 if (Targets.empty())
6257 const auto &TargetTable = DeviceConfigFile::TargetTable;
6258 std::map<StringRef, unsigned int> AllDevicesHave;
6259 std::map<StringRef, bool> AnyDeviceHas;
6260 bool AnyDeviceHasAnyAspect =
false;
6261 unsigned int ValidTargets = 0;
6262 for (
const auto &[TC, BoundArch] : Targets) {
6263 assert(TC &&
"Invalid SYCL Offload Toolchain");
6266 auto TargetIt = TargetTable.end();
6267 const llvm::Triple &TargetTriple = TC->
getTriple();
6268 const StringRef TargetArch{BoundArch};
6269 if (!TargetArch.empty()) {
6270 TargetIt = llvm::find_if(TargetTable, [&](
const auto &
Value) {
6271 using namespace tools::SYCL;
6274 return TargetArch == Device && TargetTriple.isAMDGCN();
6276 return TargetArch == Device && TargetTriple.isNVPTX();
6278 return TargetArch == Device && TargetTriple.isSPIRAOT();
6282 TargetIt = TargetTable.find(TargetTriple.str());
6283 if (TargetIt == TargetTable.end())
6284 TargetIt = TargetTable.find(TargetTriple.getArchName().str());
6287 if (TargetIt != TargetTable.end()) {
6288 const DeviceConfigFile::TargetInfo &Info = (*TargetIt).second;
6290 const auto &AspectList = Info.aspects;
6291 const auto &MaySupportOtherAspects = Info.maySupportOtherAspects;
6292 if (!AnyDeviceHasAnyAspect)
6293 AnyDeviceHasAnyAspect = MaySupportOtherAspects;
6294 for (
const auto &Aspect : AspectList) {
6298 const auto &AspectIt = AllDevicesHave.find(Aspect);
6299 if (AspectIt != AllDevicesHave.end())
6300 ++AllDevicesHave[Aspect];
6302 AllDevicesHave[Aspect] = 1;
6308 AnyDeviceHas[Aspect] =
true;
6316 if (ValidTargets == 0)
6317 AnyDeviceHasAnyAspect =
true;
6319 const Driver &D =
C.getDriver();
6320 if (AnyDeviceHasAnyAspect) {
6322 constexpr
static StringRef MacroAnyDeviceAnyAspect{
6323 "-D__SYCL_ANY_DEVICE_HAS_ANY_ASPECT__=1"};
6328 for (
const auto &[TargetKey, SupportedTarget] : AnyDeviceHas) {
6329 assert(SupportedTarget);
6331 {
"-D__SYCL_ANY_DEVICE_HAS_", TargetKey,
"__=1"}};
6335 for (
const auto &[TargetKey, SupportedTargets] : AllDevicesHave) {
6336 if (SupportedTargets != ValidTargets)
6339 {
"-D__SYCL_ALL_DEVICES_HAVE_", TargetKey,
"__=1"}};
6345 using namespace tools::SYCL;
6349 for (
auto TI = SYCLTCRange.first, TE = SYCLTCRange.second; TI != TE;
6351 ToolChains.push_back(TI->second);
6354 if (ToolChains.empty())
6357 auto *DeviceCodeSplitArg =
6358 Args.getLastArg(options::OPT_fsycl_device_code_split_EQ);
6361 DeviceCodeSplit = DeviceCodeSplitArg &&
6362 DeviceCodeSplitArg->getValue() != StringRef(
"off");
6366 C.getInputArgs().getLastArg(options::OPT_fsycl_targets_EQ);
6367 Arg *SYCLfpga =
C.getInputArgs().getLastArg(options::OPT_fintelfpga);
6368 bool HasValidSYCLRuntime =
C.getInputArgs().hasFlag(
6369 options::OPT_fsycl, options::OPT_fno_sycl,
false);
6370 bool SYCLfpgaTriple =
false;
6371 bool ShouldAddDefaultTriple =
true;
6372 bool GpuInitHasErrors =
false;
6373 bool HasSYCLTargetsOption = SYCLTargets;
6376 if (SYCLfpga && !HasValidSYCLRuntime)
6377 HasValidSYCLRuntime =
true;
6379 if (HasSYCLTargetsOption) {
6381 Arg *SYCLTargetsValues = SYCLTargets;
6383 llvm::StringMap<StringRef> FoundNormalizedTriples;
6384 for (StringRef Val : SYCLTargetsValues->getValues()) {
6385 StringRef UserTargetName(Val);
6386 if (
auto ValidDevice = gen::isGPUTarget<gen::IntelGPU>(Val)) {
6387 if (ValidDevice->empty())
6391 GpuArchList.emplace_back(
C.getDriver().MakeSYCLDeviceTriple(
6392 "spir64_gen"), ValidDevice->data());
6393 UserTargetName =
"spir64_gen";
6394 }
else if (
auto ValidDevice =
6395 gen::isGPUTarget<gen::NvidiaGPU>(Val)) {
6396 if (ValidDevice->empty())
6400 GpuArchList.emplace_back(
6401 C.getDriver().MakeSYCLDeviceTriple(
"nvptx64-nvidia-cuda"),
6402 ValidDevice->data());
6403 UserTargetName =
"nvptx64-nvidia-cuda";
6404 }
else if (
auto ValidDevice = gen::isGPUTarget<gen::AmdGPU>(Val)) {
6405 if (ValidDevice->empty())
6409 GpuArchList.emplace_back(
6410 C.getDriver().MakeSYCLDeviceTriple(
"amdgcn-amd-amdhsa"),
6411 ValidDevice->data());
6412 UserTargetName =
"amdgcn-amd-amdhsa";
6413 }
else if (Val ==
"native_cpu") {
6417 SYCLTripleList.push_back(TT);
6421 llvm::Triple TT(
C.getDriver().MakeSYCLDeviceTriple(Val));
6422 std::string NormalizedName = TT.normalize();
6425 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
6426 if (Duplicate != FoundNormalizedTriples.end())
6431 FoundNormalizedTriples[NormalizedName] = Val;
6433 SYCLTripleList.push_back(
6434 C.getDriver().MakeSYCLDeviceTriple(UserTargetName));
6435 if (TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga)
6436 SYCLfpgaTriple =
true;
6439 if (TT.getSubArch() == llvm::Triple::SPIRSubArch_gen)
6440 GpuArchList.emplace_back(TT,
nullptr);
6444 GpuInitHasErrors = initializeGpuArchMap();
6445 if (GpuInitHasErrors)
6450 for (
auto &TT : SYCLTripleList) {
6451 auto TCIt = llvm::find_if(
6452 ToolChains, [&](
auto &TC) {
return TT == TC->
getTriple(); });
6453 assert(TCIt != ToolChains.end() &&
6454 "Toolchain was not created for this platform");
6455 if (!TT.isNVPTX() && !TT.isAMDGCN()) {
6460 TT.getSubArch() == llvm::Triple::SPIRSubArch_gen) {
6461 StringRef
Device(GpuArchList[I].second);
6462 SYCLTargetInfoList.emplace_back(
6467 SYCLTargetInfoList.emplace_back(*TCIt,
nullptr);
6469 const char *OffloadArch =
nullptr;
6470 for (
auto &A : GpuArchList) {
6471 if (TT == A.first) {
6472 OffloadArch = A.second;
6476 assert(OffloadArch &&
"Failed to find matching arch.");
6477 SYCLTargetInfoList.emplace_back(*TCIt, OffloadArch);
6482 }
else if (HasValidSYCLRuntime) {
6484 bool SYCLfpga =
C.getInputArgs().hasArg(options::OPT_fintelfpga);
6486 const char *SYCLTargetArch =
6488 llvm::Triple TT =
C.getDriver().MakeSYCLDeviceTriple(SYCLTargetArch);
6489 auto TCIt = llvm::find_if(
6490 ToolChains, [&](
auto &TC) {
return TT == TC->
getTriple(); });
6491 assert(TCIt != ToolChains.end() &&
6492 "Toolchain was not created for this platform");
6493 SYCLTripleList.push_back(TT);
6494 SYCLTargetInfoList.emplace_back(*TCIt,
nullptr);
6496 SYCLfpgaTriple =
true;
6499 WrapDeviceOnlyBinary =
6500 Args.hasArg(options::OPT_fsycl_link_EQ) && !SYCLfpgaTriple;
6502 CompileDeviceOnly = WrapDeviceOnlyBinary;
6505 if (
auto *A =
C.getInputArgs().getLastArg(options::OPT_fsycl_link_EQ)) {
6506 FPGAOutType = (A->getValue() == StringRef(
"early"))
6507 ? types::TY_FPGA_AOCR
6508 : types::TY_FPGA_AOCX;
6509 if (
C.getDriver().IsFPGAEmulationMode())
6510 FPGAOutType = (A->getValue() == StringRef(
"early"))
6511 ? types::TY_FPGA_AOCR_EMU
6512 : types::TY_FPGA_AOCX;
6515 auto makeInputAction = [&](
const StringRef
Name,
6517 const llvm::opt::OptTable &Opts =
C.getDriver().getOpts();
6525 if (SYCLfpgaTriple && Args.hasArg(options::OPT_fintelfpga)) {
6527 for (StringRef LA : LinkArgs) {
6529 FPGAArchiveInputs.push_back(makeInputAction(LA, types::TY_Archive));
6530 for (
types::ID Type : {types::TY_FPGA_AOCR, types::TY_FPGA_AOCR_EMU,
6531 types::TY_FPGA_AOCX}) {
6533 FPGAAOCArchives.push_back(makeInputAction(LA,
Type));
6541 if (HasValidSYCLRuntime) {
6543 for (StringRef LA : LinkArgs) {
6545 deviceBinarySections(C, LA));
6546 if (!DeviceTargets.empty()) {
6549 IsArchive ? types::TY_Archive : types::TY_Object;
6550 SYCLFinalDeviceList.push_back(
6551 std::make_pair(makeInputAction(LA,
FileType), DeviceTargets));
6559 llvm::Triple TT = SYCLTripleList.front();
6560 auto TCIt = llvm::find_if(
6561 ToolChains, [&](
auto &TC) {
return TT == TC->
getTriple(); });
6562 SYCLTargetInfoList.emplace_back(*TCIt,
nullptr);
6564 if (SYCLTargetInfoList.empty()) {
6568 const auto *TC = ToolChains.front();
6569 SYCLTargetInfoList.emplace_back(TC,
nullptr);
6572 checkForOffloadMismatch(C, Args, SYCLTargetInfoList);
6573 checkForMisusedAddDefaultSpecConstsImageFlag(C, Args, SYCLTargetInfoList);
6578 populateSYCLDeviceTraitsMacrosArgs(C, Args, SYCLTargetInfoList);
6580 DeviceLinkerInputs.resize(SYCLTargetInfoList.size());
6584 bool canUseBundlerUnbundler()
const override {
6601 OffloadingActionBuilder(
Compilation &C, DerivedArgList &Args,
6609 SpecializedBuilders.push_back(
6610 new CudaActionBuilder(C, Args, Inputs, *
this));
6613 SpecializedBuilders.push_back(
new HIPActionBuilder(C, Args, Inputs, *
this));
6616 SpecializedBuilders.push_back(
6617 new OpenMPActionBuilder(C, Args, Inputs, *
this));
6620 SpecializedBuilders.push_back(
6621 new SYCLActionBuilder(C, Args, Inputs, *
this));
6629 unsigned ValidBuilders = 0u;
6630 unsigned ValidBuildersSupportingBundling = 0u;
6631 for (
auto *SB : SpecializedBuilders) {
6632 IsValid = IsValid && !SB->initialize();
6635 if (SB->isValid()) {
6637 if (SB->canUseBundlerUnbundler())
6638 ++ValidBuildersSupportingBundling;
6642 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
6645 ~OffloadingActionBuilder() {
6646 for (
auto *SB : SpecializedBuilders)
6652 void pushForeignAction(
Action *A) {
6653 for (
auto *SB : SpecializedBuilders) {
6655 SB->pushForeignAction(A);
6660 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
6661 assert(HostAction &&
"Invalid host action");
6662 assert(InputArg &&
"Invalid input argument");
6663 auto Loc = HostActionToInputArgMap.find(HostAction);
6664 if (
Loc == HostActionToInputArgMap.end())
6665 HostActionToInputArgMap[HostAction] = InputArg;
6666 assert(HostActionToInputArgMap[HostAction] == InputArg &&
6667 "host action mapped to multiple input arguments");
6675 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
6677 DeviceActionBuilder::PhasesTy &Phases) {
6681 if (SpecializedBuilders.empty())
6684 assert(HostAction &&
"Invalid host action!");
6685 recordHostAction(HostAction, InputArg);
6690 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
6691 unsigned InactiveBuilders = 0u;
6692 unsigned IgnoringBuilders = 0u;
6693 for (
auto *SB : SpecializedBuilders) {
6694 if (!SB->isValid()) {
6699 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
6704 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
6709 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
6710 OffloadKind |= SB->getAssociatedOffloadKind();
6715 if (IgnoringBuilders &&
6716 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
6740 bool updateInputForFPGA(
Action *&A,
const Arg *InputArg,
6741 DerivedArgList &Args) {
6742 std::string InputName = InputArg->getAsString(Args);
6743 const Driver &D =
C.getDriver();
6748 auto ArchiveTypeMismatch = [&D, &InputName](
bool EmitDiag) {
6750 D.
Diag(clang::diag::warn_drv_mismatch_fpga_archive) << InputName;
6753 if (A->
getType() == types::TY_FPGA_AOCO) {
6756 A =
C.MakeAction<
InputAction>(*InputArg, types::TY_FPGA_AOCO);
6762 A =
C.MakeAction<
InputAction>(*InputArg, types::TY_FPGA_AOCX);
6767 {types::TY_FPGA_AOCR,
false},
6768 {types::TY_FPGA_AOCR_EMU,
true}};
6769 for (
const auto &ArchiveType : FPGAAOCTypes) {
6770 bool BinaryFound =
hasFPGABinary(C, InputName, ArchiveType.first);
6773 A =
C.MakeAction<
InputAction>(*InputArg, ArchiveType.first);
6776 ArchiveTypeMismatch(BinaryFound &&
6785 bool addHostDependenceToDeviceActions(
Action *&HostAction,
6786 const Arg *InputArg,
6787 DerivedArgList &Args) {
6792 if (HostAction->
getType() == types::TY_FPGA_AOCX)
6794 recordHostAction(HostAction, InputArg);
6802 bool HasFPGATarget =
false;
6803 if (CanUseBundler && isa<InputAction>(HostAction) &&
6804 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
6807 HostAction->
getType() == types::TY_PP_HIP)) {
6810 bool HasSPIRTarget =
false;
6813 for (
auto TI = SYCLTCRange.first, TE = SYCLTCRange.second; TI != TE;
6815 HasFPGATarget |= TI->second->getTriple().getSubArch() ==
6816 llvm::Triple::SPIRSubArch_fpga;
6817 HasSPIRTarget |= TI->second->getTriple().isSPIROrSPIRV();
6822 HostAction->
getType() == types::TY_FPGA_AOCO)
6825 if (HasFPGATarget && !updateInputForFPGA(A, InputArg, Args))
6830 A, (HasSPIRTarget && HostAction->
getType() == types::TY_Archive)
6831 ? types::TY_Tempfilelist
6836 HostAction = UnbundlingHostAction;
6837 recordHostAction(HostAction, InputArg);
6840 assert(HostAction &&
"Invalid host action!");
6843 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
6844 for (
auto *SB : SpecializedBuilders) {
6848 auto RetCode = SB->addDeviceDependences(HostAction);
6852 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
6853 "Host dependence not expected to be ignored.!");
6857 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
6858 OffloadKind |= SB->getAssociatedOffloadKind();
6867 (Args.hasArg(options::OPT_fsycl_link_EQ) && !HasFPGATarget) ||
6868 (HasFPGATarget && ((Args.hasArg(options::OPT_fsycl_link_EQ) &&
6869 HostAction->
getType() == types::TY_Object) ||
6870 HostAction->
getType() == types::TY_FPGA_AOCX)))
6871 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
6880 bool appendTopLevelLinkAction(
ActionList &AL) {
6883 for (
auto *SB : SpecializedBuilders) {
6886 SB->appendTopLevelLinkAction(OffloadAL);
6889 AL.append(OffloadAL.begin(), OffloadAL.end());
6897 const Arg *InputArg) {
6899 recordHostAction(HostAction, InputArg);
6903 for (
auto *SB : SpecializedBuilders) {
6906 SB->appendTopLevelActions(OffloadAL);
6913 if (CanUseBundler && HostAction &&
6914 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
6916 OffloadAL.push_back(HostAction);
6920 assert(HostAction == AL.back() &&
"Host action not in the list??");
6922 recordHostAction(HostAction, InputArg);
6923 AL.back() = HostAction;
6925 AL.append(OffloadAL.begin(), OffloadAL.end());
6939 void addDeviceLinkDependenciesFromHost(
ActionList &LinkerInputs) {
6942 types::TY_Host_Dependencies_Image);
6945 unsigned ActiveOffloadKinds = 0u;
6946 for (
auto &I : InputArgToOffloadKindMap)
6947 ActiveOffloadKinds |= I.second;
6951 nullptr, ActiveOffloadKinds);
6955 for (
auto *SB : SpecializedBuilders) {
6958 SB->addDeviceLinkDependencies(DA);
6962 void appendDeviceLinkActions(
ActionList &AL) {
6963 for (DeviceActionBuilder *SB : SpecializedBuilders) {
6966 SB->appendLinkDeviceActions(AL);
6970 void makeHostLinkDeviceOnlyAction(
ActionList &Inputs) {
6973 appendDeviceLinkActions(DeviceAL);
6974 if (DeviceAL.empty())
6979 for (DeviceActionBuilder *SB : SpecializedBuilders) {
6982 HA = SB->appendLinkHostActions(DeviceAL);
6989 Inputs.push_back(HA);
6993 void makeHostLinkAction(
ActionList &LinkerInputs) {
6995 bool IsCUinSYCL =
false;
6996 for (
auto &I : InputArgToOffloadKindMap) {
7004 for (
size_t i = 0; i < LinkerInputs.size(); ++i) {
7008 InputArgToOffloadKindMap[HostActionToInputArgMap[LinkerInputs[i]]]);
7015 appendDeviceLinkActions(DeviceAL);
7016 if (DeviceAL.empty())
7021 for (DeviceActionBuilder *SB : SpecializedBuilders) {
7024 HA = SB->appendLinkHostActions(DeviceAL);
7030 LinkerInputs.push_back(HA);
7034 for (
auto &DeviceAction : DeviceAL) {
7037 LinkerInputs.push_back(DeviceAction);
7050 for (
auto *SB : SpecializedBuilders) {
7054 SB->appendLinkDependences(DDeps);
7058 unsigned ActiveOffloadKinds = 0u;
7059 for (
auto &I : InputArgToOffloadKindMap)
7060 ActiveOffloadKinds |= I.second;
7072 for (
auto *A : HostAction->
inputs()) {
7073 auto ArgLoc = HostActionToInputArgMap.find(A);
7074 if (ArgLoc == HostActionToInputArgMap.end())
7076 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
7077 if (OFKLoc == InputArgToOffloadKindMap.end())
7089 nullptr, ActiveOffloadKinds);
7093 void unbundleStaticArchives(
Compilation &C, DerivedArgList &Args) {
7094 if (!Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false))
7101 const llvm::opt::OptTable &Opts =
C.getDriver().getOpts();
7102 auto unbundleStaticLib = [&](
types::ID T,
const StringRef &A) {
7103 Arg *InputArg =
MakeInputArg(Args, Opts, Args.MakeArgString(A));
7105 addHostDependenceToDeviceActions(Current, InputArg, Args);
7107 addDeviceDependencesToHostAction(Current, InputArg,
phases::Link,
7110 for (StringRef LA : LinkArgs) {
7129 if (
C.getDriver().IsFPGAHWMode())
7130 unbundleStaticLib(types::TY_FPGA_AOCO, LA);
7131 unbundleStaticLib(types::TY_Archive, LA);
7138 void Driver::handleArguments(
Compilation &C, DerivedArgList &Args,
7143 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
7144 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
7145 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
7146 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
7147 Args.eraseArg(options::OPT__SLASH_Yc);
7148 Args.eraseArg(options::OPT__SLASH_Yu);
7149 YcArg = YuArg =
nullptr;
7151 if (YcArg && Inputs.size() > 1) {
7152 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
7153 Args.eraseArg(options::OPT__SLASH_Yc);
7161 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
7162 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
7163 Args.AddFlagArg(
nullptr,
7164 getOpts().getOption(options::OPT_frtlib_add_rpath));
7167 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
7168 Diag(clang::diag::err_drv_emit_llvm_link);
7170 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7171 .equals_insensitive(
"lld"))
7172 Diag(clang::diag::err_drv_lto_without_lld);
7178 if (!Args.hasArg(options::OPT_dumpdir)) {
7179 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
7180 Arg *Arg = Args.MakeSeparateArg(
7181 nullptr,
getOpts().getOption(options::OPT_dumpdir),
7183 (FinalOutput ? FinalOutput->getValue()
7195 Args.eraseArg(options::OPT__SLASH_Fp);
7196 Args.eraseArg(options::OPT__SLASH_Yc);
7197 Args.eraseArg(options::OPT__SLASH_Yu);
7198 YcArg = YuArg =
nullptr;
7201 unsigned LastPLSize = 0;
7202 for (
auto &I : Inputs) {
7204 const Arg *InputArg = I.second;
7207 LastPLSize = PL.size();
7212 if (InitialPhase > FinalPhase) {
7213 if (InputArg->isClaimed())
7220 if (Args.hasArg(options::OPT_Qunused_arguments))
7226 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
7227 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
7231 (Args.getLastArg(options::OPT__SLASH_EP,
7232 options::OPT__SLASH_P) ||
7233 Args.getLastArg(options::OPT_E) ||
7234 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
7236 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
7237 << InputArg->getAsString(Args) << !!FinalPhaseArg
7238 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
7240 Diag(clang::diag::warn_drv_input_file_unused)
7241 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
7243 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
7256 Actions.push_back(ClangClPch);
7270 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
7271 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
7277 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
7279 if (!SuppressMissingInputWarning && Inputs.empty()) {
7280 Diag(clang::diag::err_drv_no_input_files);
7285 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
7286 StringRef
V = A->getValue();
7287 if (Inputs.size() > 1 && !
V.empty() &&
7288 !llvm::sys::path::is_separator(
V.back())) {
7290 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
7291 << A->getSpelling() <<
V;
7292 Args.eraseArg(options::OPT__SLASH_Fo);
7297 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
7298 StringRef
V = A->getValue();
7299 if (Inputs.size() > 1 && !
V.empty() &&
7300 !llvm::sys::path::is_separator(
V.back())) {
7302 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
7303 << A->getSpelling() <<
V;
7304 Args.eraseArg(options::OPT__SLASH_Fa);
7309 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
7310 if (A->getValue()[0] ==
'\0') {
7312 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
7313 Args.eraseArg(options::OPT__SLASH_o);
7317 handleArguments(C, Args, Inputs, Actions);
7320 const llvm::opt::OptTable &Opts =
getOpts();
7321 Arg *SYCLFpgaArg = C.getInputArgs().getLastArg(options::OPT_fintelfpga);
7323 !Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false))
7324 Args.AddFlagArg(0, Opts.getOption(options::OPT_fsycl));
7328 if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false)) {
7332 if (SaveTemps == SaveTempsObj) {
7333 auto *OptO = C.getArgs().getLastArg(options::OPT_o);
7334 OutFileDir = (OptO ? OptO->getValues()[0] :
"");
7335 llvm::sys::path::remove_filename(OutFileDir);
7336 if (!OutFileDir.empty())
7337 OutFileDir.append(llvm::sys::path::get_separator());
7340 for (
auto &I : Inputs) {
7341 std::string SrcFileName(I.second->getAsString(Args));
7342 if ((I.first == types::TY_PP_C || I.first == types::TY_PP_CXX ||
7346 llvm::sys::fs::createUniquePath(
"uid%%%%%%%%%%%%%%%%", ResultID,
false);
7352 std::string TmpFileNameHeader;
7353 std::string TmpFileNameFooter;
7354 auto StemmedSrcFileName = llvm::sys::path::stem(SrcFileName).str();
7356 TmpFileNameHeader.append(C.getDriver().GetUniquePath(
7357 OutFileDir.c_str() + StemmedSrcFileName +
"-header",
"h"));
7358 TmpFileNameFooter.append(C.getDriver().GetUniquePath(
7359 OutFileDir.c_str() + StemmedSrcFileName +
"-footer",
"h"));
7361 TmpFileNameHeader.assign(C.getDriver().GetTemporaryPath(
7362 StemmedSrcFileName +
"-header",
"h"));
7364 C.getDriver().GetTemporaryPath(StemmedSrcFileName +
"-footer",
"h");
7366 StringRef TmpFileHeader =
7367 C.addTempFile(C.getArgs().MakeArgString(TmpFileNameHeader));
7368 StringRef TmpFileFooter =
7369 C.addTempFile(C.getArgs().MakeArgString(TmpFileNameFooter));
7372 if (Arg *A = C.getArgs().getLastArg(options::OPT_fsycl_footer_path_EQ)) {
7374 llvm::sys::path::append(OutName,
7375 llvm::sys::path::filename(TmpFileNameFooter));
7376 TmpFileFooter = C.addTempFile(C.getArgs().MakeArgString(OutName));
7382 bool UseNewOffloadingDriver =
7384 Args.hasFlag(options::OPT_offload_new_driver,
7385 options::OPT_no_offload_new_driver,
false);
7388 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
7389 !UseNewOffloadingDriver
7390 ? std::make_unique<OffloadingActionBuilder>(C, Args, Inputs)
7401 for (
auto &I : Inputs) {
7403 const Arg *InputArg = I.second;
7416 if (!UseNewOffloadingDriver)
7417 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg, Args))
7423 if (!UseNewOffloadingDriver)
7424 Current = OffloadBuilder->addDeviceDependencesToHostAction(
7425 Current, InputArg, Phase, PL.back(), FullPL);
7431 assert(Phase == PL.back() &&
"linking must be final compilation step.");
7435 if (!(C.getInputArgs().hasArg(options::OPT_hip_link) &&
7436 (C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
7438 LinkerInputs.push_back(Current);
7448 assert(Phase == PL.back() &&
"merging must be final compilation step.");
7449 MergerInputs.push_back(Current);
7467 if (NewCurrent == Current)
7470 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
7473 Current = NewCurrent;
7477 if (UseNewOffloadingDriver)
7481 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
7486 if (Current->getType() == types::TY_Nothing)
7492 Actions.push_back(Current);
7495 if (!UseNewOffloadingDriver)
7496 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
7498 Current->propagateHostOffloadInfo(C.getActiveOffloadKinds(),
7502 if (!UseNewOffloadingDriver) {
7503 OffloadBuilder->appendTopLevelLinkAction(Actions);
7507 if (!LinkerInputs.empty() && C.getDriver().getOffloadStaticLibSeen())
7508 OffloadBuilder->addDeviceLinkDependenciesFromHost(LinkerInputs);
7510 OffloadBuilder->unbundleStaticArchives(C, Args);
7515 bool EarlyLink =
false;
7516 if (
const Arg *A = Args.getLastArg(options::OPT_fsycl_link_EQ))
7517 EarlyLink = A->getValue() == StringRef(
"early");
7518 for (
auto &LI : LinkerInputs) {
7519 Action *UnbundlerInput =
nullptr;
7520 auto wrapObject = [&] {
7521 if (EarlyLink && Args.hasArg(options::OPT_fintelfpga)) {
7532 if (
auto *IA = dyn_cast<InputAction>(LI)) {
7533 if (IA->getType() == types::TY_FPGA_AOCR ||
7534 IA->getType() == types::TY_FPGA_AOCX ||
7535 IA->getType() == types::TY_FPGA_AOCR_EMU) {
7537 UnbundlerInput = LI;
7539 std::string
FileName = IA->getInputArg().getAsString(Args);
7547 if (UnbundlerInput && !PL.empty()) {
7548 if (
auto *IA = dyn_cast<InputAction>(UnbundlerInput)) {
7549 std::string
FileName = IA->getInputArg().getAsString(Args);
7551 if (!UseNewOffloadingDriver)
7552 OffloadBuilder->addHostDependenceToDeviceActions(UnbundlerInput,
7560 if (!UseNewOffloadingDriver &&
7562 if (Args.hasArg(options::OPT_fsycl_link_EQ) &&
7563 !Args.hasArg(options::OPT_fintelfpga)) {
7565 OffloadBuilder->makeHostLinkDeviceOnlyAction(LAList);
7566 if (!LAList.empty()) {
7567 Action *LA = LAList.front();
7568 LA = OffloadBuilder->processHostLinkAction(LA);
7569 Actions.push_back(LA);
7571 }
else if (LinkerInputs.empty())
7572 OffloadBuilder->appendDeviceLinkActions(Actions);
7575 if (!LinkerInputs.empty()) {
7576 if (!UseNewOffloadingDriver)
7577 OffloadBuilder->makeHostLinkAction(LinkerInputs);
7579 if (Args.hasArg(options::OPT_fsycl_link_EQ))
7580 LinkType = types::TY_Archive;
7585 }
else if (UseNewOffloadingDriver ||
7586 Args.hasArg(options::OPT_offload_link)) {
7593 if (!UseNewOffloadingDriver)
7594 LA = OffloadBuilder->processHostLinkAction(LA);
7595 Actions.push_back(LA);
7599 if (!MergerInputs.empty())
7603 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
7610 for (
auto &I : Inputs) {
7612 const Arg *InputArg = I.second;
7617 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
7618 InputType == types::TY_Asm)
7623 for (
auto Phase : PhaseList) {
7627 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
7632 if (InputType == types::TY_Object)
7639 assert(Phase == PhaseList.back() &&
7640 "merging must be final compilation step.");
7641 MergerInputs.push_back(Current);
7650 Actions.push_back(Current);
7654 if (!MergerInputs.empty())
7659 for (
auto Opt : {options::OPT_print_supported_cpus,
7660 options::OPT_print_supported_extensions}) {
7667 if (Arg *A = Args.getLastArg(Opt)) {
7668 if (Opt == options::OPT_print_supported_extensions &&
7669 !C.getDefaultToolChain().getTriple().isRISCV() &&
7670 !C.getDefaultToolChain().getTriple().isAArch64() &&
7671 !C.getDefaultToolChain().getTriple().isARM()) {
7672 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
7673 <<
"--print-supported-extensions";
7682 for (
auto &I : Inputs)
7688 if (C.getDefaultToolChain().getTriple().isDXIL()) {
7692 if (TC.requiresValidation(Args)) {
7693 Action *LastAction = Actions.back();
7695 LastAction, types::TY_DX_CONTAINER));
7700 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
7706 const llvm::opt::DerivedArgList &Args,
7708 const llvm::Triple &Triple,
7709 bool SuppressError =
false) {
7713 if (!SuppressError && Triple.isNVPTX() &&
7715 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
7716 <<
"CUDA" << ArchStr;
7718 }
else if (!SuppressError && Triple.isAMDGPU() &&
7720 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
7721 <<
"HIP" << ArchStr;
7729 llvm::StringMap<bool> Features;
7735 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
7736 C.setContainsError();
7748 static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
7750 llvm::Triple Triple) {
7751 if (!Triple.isAMDGPU())
7752 return std::nullopt;
7754 std::set<StringRef> ArchSet;
7755 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
7762 bool SuppressError)
const {
7764 TC = &C.getDefaultToolChain();
7767 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
7768 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
7769 options::OPT_no_offload_arch_EQ)) {
7770 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
7772 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
7774 :
"--no-offload-arch");
7777 if (KnownArchs.contains(TC))
7778 return KnownArchs.lookup(TC);
7781 for (
auto *Arg : Args) {
7783 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
7784 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
7787 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
7788 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
7789 Arg = ExtractedArg.get();
7794 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
7795 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
7796 if (Arch ==
"native" || Arch.empty()) {
7800 llvm::consumeError(GPUsOrErr.takeError());
7803 << llvm::Triple::getArchTypeName(TC->
getArch())
7808 for (
auto ArchStr : *GPUsOrErr) {
7815 C, Args, Arch, TC->
getTriple(), SuppressError);
7816 if (ArchStr.empty())
7818 Archs.insert(ArchStr);
7821 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
7822 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
7823 if (Arch ==
"all") {
7827 C, Args, Arch, TC->
getTriple(), SuppressError);
7828 if (ArchStr.empty())
7830 Archs.erase(ArchStr);
7836 if (
auto ConflictingArchs =
7838 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
7839 << ConflictingArchs->first << ConflictingArchs->second;
7840 C.setContainsError();
7847 if (Archs.empty()) {
7853 Archs.insert(StringRef());
7855 Archs.insert(StringRef());
7857 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
7858 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
7865 llvm::opt::DerivedArgList &Args,
7867 Action *HostAction)
const {
7872 !(isa<CompileJobAction>(HostAction) ||
7886 auto TCRange = C.getOffloadToolChains(
Kind);
7887 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
7888 ToolChains.push_back(TI->second);
7890 if (ToolChains.empty())
7894 const Arg *InputArg = Input.second;
7905 TCAndArchs.push_back(std::make_pair(TC, Arch));
7907 for (
unsigned I = 0, E = TCAndArchs.size(); I != E; ++I)
7908 DeviceActions.push_back(C.MakeAction<
InputAction>(*InputArg, InputType));
7910 if (DeviceActions.empty())
7917 assert(Phase == PL.back() &&
"linking must be final compilation step.");
7926 auto TCAndArch = TCAndArchs.begin();
7927 for (
Action *&A : DeviceActions) {
7928 if (A->
getType() == types::TY_Nothing)
7936 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
7938 HostAction->
getType() != types::TY_Nothing) {
7945 TCAndArch->second.data(),
Kind);
7947 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(),
Kind);
7956 for (
Action *&A : DeviceActions) {
7957 if (!Args.getLastArgValue(options::OPT_fsycl_device_obj_EQ)
7958 .equals_insensitive(
"spirv") ||
7965 for (
Action *&A : DeviceActions) {
7966 if ((A->
getType() != types::TY_Object &&
7967 A->
getType() != types::TY_LTO_BC) ||
7969 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
7975 auto TCAndArch = TCAndArchs.begin();
7976 for (
Action *A : DeviceActions) {
7977 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(),
Kind);
7979 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(),
Kind);
7984 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
7986 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(),
Kind);
7994 bool ShouldBundleHIP =
7996 Args.hasFlag(options::OPT_gpu_bundle_output,
7997 options::OPT_no_gpu_bundle_output,
true) &&
7998 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
7999 !llvm::any_of(OffloadActions,
8004 return C.MakeAction<
OffloadAction>(DDeps, types::TY_Nothing);
8006 if (OffloadActions.empty())
8011 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
8015 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
8019 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
8024 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
8033 nullptr, C.getActiveOffloadKinds());
8038 return C.MakeAction<
OffloadAction>(DDep, types::TY_Nothing);
8042 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
8043 return A->
getType() == types::TY_Nothing;
8044 }) && isa<CompileJobAction>(HostAction);
8047 nullptr, SingleDeviceOutput ? DDep : DDeps);
8048 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
8054 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
8065 llvm_unreachable(
"link action invalid here.");
8067 llvm_unreachable(
"ifsmerge action invalid here.");
8072 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
8073 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
8074 OutputTy = types::TY_Dependencies;
8079 if (!Args.hasFlag(options::OPT_frewrite_includes,
8080 options::OPT_fno_rewrite_includes,
false) &&
8081 !Args.hasFlag(options::OPT_frewrite_imports,
8082 options::OPT_fno_rewrite_imports,
false) &&
8083 !Args.hasFlag(options::OPT_fdirectives_only,
8084 options::OPT_fno_directives_only,
false) &&
8088 "Cannot preprocess this input type!");
8092 !Args.hasArg(options::OPT_fno_sycl_use_footer) &&
8094 Input->
getType() != types::TY_CUDA_DEVICE) {
8097 auto *AppendFooter =
8112 if (Args.hasArg(options::OPT_extract_api))
8119 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
8120 !Args.getLastArg(options::OPT__precompile))
8125 "Cannot precompile this input type!");
8129 const char *ModName =
nullptr;
8130 if (OutputTy == types::TY_PCH) {
8131 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
8132 ModName = A->getValue();
8134 OutputTy = types::TY_ModuleFile;
8137 if (Args.hasArg(options::OPT_fsyntax_only)) {
8139 OutputTy = types::TY_Nothing;
8145 if (Args.hasArg(options::OPT_fsyntax_only))
8147 if (Args.hasArg(options::OPT_rewrite_objc))
8149 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
8151 types::TY_RewrittenLegacyObjC);
8152 if (Args.hasArg(options::OPT__analyze))
8154 if (Args.hasArg(options::OPT__migrate))
8156 if (Args.hasArg(options::OPT_emit_ast))
8158 if (Args.hasArg(options::OPT_emit_cir))
8160 if (Args.hasArg(options::OPT_module_file_info))
8162 if (Args.hasArg(options::OPT_verify_pch))
8164 if (Args.hasArg(options::OPT_extract_api))
8171 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
8172 !Args.hasArg(options::OPT_emit_llvm))
8173 Output = types::TY_PP_Asm;
8174 else if (Args.hasArg(options::OPT_S))
8175 Output = types::TY_LTO_IR;
8177 Output = types::TY_LTO_BC;
8183 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
8189 llvm::Triple OffloadTriple =
8193 types::TY_Tempfiletable);
8195 OffloadTriple.isSPIROrSPIRV() && !OffloadTriple.isSPIRAOT());
8197 TypedPostLinkAction, types::TY_Tempfilelist,
8198 types::TY_Tempfilelist);
8202 auto *OutputAction =
8206 TypedExtractIRFilesAction, OutputAction);
8210 ForEach, types::TY_Tempfilelist, types::TY_Tempfilelist);
8213 return ExtractBCFiles;
8217 if (Args.hasArg(options::OPT_emit_llvm) ||
8219 C.getDriver().getUseNewOffloadingDriver()) ||
8223 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
8227 Args.hasArg(options::OPT_S) &&
8231 !Args.hasFlag(options::OPT_offload_new_driver,
8232 options::OPT_no_offload_new_driver,
false)))
8234 : types::TY_LLVM_BC;
8243 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
8247 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
8249 Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
8269 unsigned NumOutputs = 0;
8270 unsigned NumIfsOutputs = 0;
8271 for (
const Action *A : C.getActions()) {
8272 if (A->
getType() != types::TY_Nothing &&
8273 A->
getType() != types::TY_DX_CONTAINER &&
8275 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
8277 0 == NumIfsOutputs++) ||
8282 A->
getType() == types::TY_Nothing &&
8283 !C.getArgs().hasArg(options::OPT_fsyntax_only))
8284 NumOutputs += A->
size();
8287 if (NumOutputs > 1) {
8288 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
8289 FinalOutput =
nullptr;
8293 const llvm::Triple &RawTriple = C.getDefaultToolChain().getTriple();
8296 llvm::StringSet<> ArchNames;
8297 if (RawTriple.isOSBinFormatMachO())
8298 for (
const Arg *A : C.getArgs())
8299 if (A->getOption().matches(options::OPT_arch))
8300 ArchNames.insert(A->getValue());
8303 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
8304 for (
Action *A : C.getActions()) {
8311 const char *LinkingOutput =
nullptr;
8312 if (isa<LipoJobAction>(A)) {
8314 LinkingOutput = FinalOutput->getValue();
8322 ArchNames.size() > 1,
8323 LinkingOutput, CachedResults,
8330 for (
auto &J : C.getJobs())
8331 J.InProcess =
false;
8334 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
8335 std::optional<llvm::sys::ProcessStatistics> ProcStat =
8336 Cmd.getProcessStatistics();
8340 const char *LinkingOutput =
nullptr;
8342 LinkingOutput = FinalOutput->getValue();
8343 else if (!
Cmd.getOutputFilenames().empty())
8344 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
8349 using namespace llvm;
8351 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
8352 <<
"output=" << LinkingOutput;
8353 outs() <<
", total="
8354 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
8356 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
8357 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
8361 llvm::raw_string_ostream Out(Buffer);
8362 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
8365 llvm::sys::printArg(Out, LinkingOutput, true);
8366 Out <<
',' << ProcStat->TotalTime.count() <<
','
8367 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
8371 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
8372 llvm::sys::fs::OF_Append |
8373 llvm::sys::fs::OF_Text);
8378 llvm::errs() <<
"ERROR: Cannot lock file "
8379 << CCPrintStatReportFilename <<
": "
8380 << toString(L.takeError()) <<
"\n";
8391 if (Diags.hasErrorOccurred() ||
8392 C.getArgs().hasArg(options::OPT_Qunused_arguments))
8396 (void)C.getArgs().hasArg(options::OPT_fdriver_only);
8398 (void)C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
8401 (void)C.getArgs().hasArg(options::OPT_driver_mode);
8402 (void)C.getArgs().hasArg(options::OPT_rsp_quoting);
8404 bool HasAssembleJob = llvm::any_of(C.getJobs(), [](
auto &J) {
8408 return strstr(J.getCreator().getShortName(),
"assembler");
8410 for (Arg *A : C.getArgs()) {
8414 if (!A->isClaimed()) {
8420 const Option &Opt = A->getOption();
8421 if (Opt.getKind() == Option::FlagClass) {
8422 bool DuplicateClaimed =
false;
8424 for (
const Arg *AA : C.getArgs().filtered(&Opt)) {
8425 if (AA->isClaimed()) {
8426 DuplicateClaimed =
true;
8431 if (DuplicateClaimed)
8437 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
8439 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
8444 !
C.getActions().empty()) {
8445 Diag(diag::err_drv_unsupported_opt_for_target)
8448 Diag(clang::diag::warn_drv_unused_argument)
8449 << A->getAsString(
C.getArgs());
8459 class ToolSelector final {
8470 bool IsHostSelector;
8481 bool CanBeCollapsed =
true) {
8483 if (Inputs.size() != 1)
8486 Action *CurAction = *Inputs.begin();
8487 if (CanBeCollapsed &&
8493 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
8497 if (!IsHostSelector) {
8498 if (OA->hasSingleDeviceDependence(
true)) {
8500 OA->getSingleDeviceDependence(
true);
8501 if (CanBeCollapsed &&
8504 SavedOffloadAction.push_back(OA);
8505 return dyn_cast<JobAction>(CurAction);
8507 }
else if (OA->hasHostDependence()) {
8508 CurAction = OA->getHostDependence();
8509 if (CanBeCollapsed &&
8512 SavedOffloadAction.push_back(OA);
8513 return dyn_cast<JobAction>(CurAction);
8518 return dyn_cast<JobAction>(CurAction);
8522 bool canCollapseAssembleAction()
const {
8523 return TC.useIntegratedAs() && !SaveTemps &&
8524 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
8525 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
8526 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
8527 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
8531 bool canCollapsePreprocessorAction()
const {
8532 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
8533 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
8534 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
8539 struct JobActionInfo final {
8549 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
8551 unsigned ElementNum) {
8552 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
8553 for (
unsigned I = 0; I < ElementNum; ++I)
8554 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
8555 ActionInfo[I].SavedOffloadAction.end());
8571 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
8573 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
8574 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
8575 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
8576 if (!AJ || !BJ || !CJ)
8580 const Tool *
T = TC.SelectTool(*CJ);
8587 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
8593 const Tool *BT = TC.SelectTool(*BJ);
8598 if (!
T->hasIntegratedAssembler())
8601 Inputs = CJ->getInputs();
8602 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
8609 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
8611 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
8612 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
8617 const Tool *
T = TC.SelectTool(*BJ);
8621 if (!
T->hasIntegratedAssembler())
8624 Inputs = BJ->getInputs();
8625 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
8632 if (ActionInfo.size() < 2)
8634 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
8635 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
8644 bool InputIsBitcode =
true;
8645 for (
size_t i = 1; i < ActionInfo.size(); i++)
8646 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
8647 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
8648 InputIsBitcode =
false;
8651 if (!InputIsBitcode && !canCollapsePreprocessorAction())
8655 const Tool *
T = TC.SelectTool(*CJ);
8662 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
8665 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode))
8668 Inputs = CJ->getInputs();
8669 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
8680 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
8686 for (
Action *A : Inputs) {
8687 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
8688 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
8689 NewInputs.push_back(A);
8695 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
8696 PreprocessJobOffloadActions.end());
8697 NewInputs.append(PJ->input_begin(), PJ->input_end());
8704 const Compilation &C,
bool SaveTemps,
bool EmbedBitcode)
8705 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
8707 assert(BaseAction &&
"Invalid base action.");
8724 ActionChain.back().JA = BaseAction;
8725 while (ActionChain.back().JA) {
8726 const Action *CurAction = ActionChain.back().JA;
8729 ActionChain.resize(ActionChain.size() + 1);
8730 JobActionInfo &AI = ActionChain.back();
8734 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
8738 ActionChain.pop_back();
8746 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
8747 CollapsedOffloadAction);
8749 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
8751 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
8757 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
8769 StringRef BoundArch,
8771 std::string TriplePlusArch = TC->
getTriple().normalize();
8772 if (!BoundArch.empty()) {
8773 TriplePlusArch +=
"-";
8774 TriplePlusArch += BoundArch;
8776 TriplePlusArch +=
"-";
8778 return TriplePlusArch;
8784 const std::map<std::pair<const Action *, std::string>,
InputInfoList>
8790 auto Lookup = CachedResults.find(
8793 if (Lookup != CachedResults.end()) {
8795 InputInfos.append(Lookup->second);
8799 TargetDeviceOffloadKind, CachedResults, FEA);
8806 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
8807 std::map<std::pair<const Action *, std::string>,
InputInfoList>
8810 std::pair<const Action *, std::string> ActionTC = {
8812 auto CachedResult = CachedResults.find(ActionTC);
8813 if (CachedResult != CachedResults.end()) {
8814 return CachedResult->second;
8817 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
8818 CachedResults, TargetDeviceOffloadKind);
8819 CachedResults[ActionTC] = Result;
8824 const JobAction *JA,
const char *BaseInput,
8827 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
8831 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
8832 Path = A->getValue();
8833 if (llvm::sys::fs::is_directory(Path)) {
8835 llvm::sys::path::replace_extension(Tmp,
"json");
8836 llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
8839 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
8842 Path = DumpDir->getValue();
8843 Path += llvm::sys::path::filename(BaseInput);
8845 Path = Result.getFilename();
8847 llvm::sys::path::replace_extension(Path,
"json");
8849 const char *ResultFile = C.getArgs().MakeArgString(Path);
8850 C.addTimeTraceFile(ResultFile, JA);
8851 C.addResultFile(ResultFile, JA);
8856 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
8857 std::map<std::pair<const Action *, std::string>,
InputInfoList>
8860 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
8863 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
8896 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
8898 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
8899 const char *DepBoundArch) {
8902 LinkingOutput, CachedResults,
8912 OA->doOnEachDependence(
8913 BuildingForOffloadDevice,
8916 C, DepA, DepTC, DepBoundArch,
false,
8917 !!DepBoundArch, LinkingOutput, CachedResults,
8921 A = BuildingForOffloadDevice
8922 ? OA->getSingleDeviceDependence(
true)
8923 : OA->getHostDependence();
8927 std::pair<const Action *, std::string> ActionTC = {
8928 OA->getHostDependence(),
8930 if (CachedResults.find(ActionTC) != CachedResults.end()) {
8932 Inputs.append(OffloadDependencesInputInfo);
8937 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
8940 const Arg &Input = IA->getInputArg();
8942 if (Input.getOption().matches(options::OPT_INPUT)) {
8943 const char *
Name = Input.getValue();
8952 if (!ArchName.empty())
8953 TC = &getToolChain(
C.getArgs(),
8955 C.getArgs(), ArchName));
8957 TC = &
C.getDefaultToolChain();
8960 MultipleArchs, LinkingOutput, CachedResults,
8961 TargetDeviceOffloadKind);
8966 auto MainActionOutput = CachedResults.find(
8967 {FEA->getJobAction(),
8969 if (MainActionOutput != CachedResults.end()) {
8973 TargetDeviceOffloadKind)}] =
8974 MainActionOutput->second;
8975 return MainActionOutput->second;
8981 false, MultipleArchs, LinkingOutput,
8982 CachedResults, TargetDeviceOffloadKind);
8983 unsigned OffsetIdx =
C.getJobs().size();
8985 false, MultipleArchs, LinkingOutput,
8986 CachedResults, TargetDeviceOffloadKind);
8988 auto begin =
C.getJobs().getJobsForOverride().begin() + OffsetIdx;
8989 auto end =
C.getJobs().getJobsForOverride().end();
8993 std::make_move_iterator(begin), std::make_move_iterator(end));
8994 C.getJobs().getJobsForOverride().erase(begin, end);
8997 for (std::unique_ptr<Command>
Cmd :
8998 llvm::make_range(std::make_move_iterator(JobsToWrap.begin()),
8999 std::make_move_iterator(JobsToWrap.end()))) {
9000 const JobAction *SourceAction = cast<JobAction>(&
Cmd->getSource());
9001 if (FEA->getSerialActions().count(SourceAction)) {
9002 C.addCommand(std::move(
Cmd));
9010 TargetDeviceOffloadKind, CachedResults, FEA);
9011 const Tool *Creator = &
Cmd->getCreator();
9012 StringRef ParallelJobs;
9014 ParallelJobs =
C.getArgs().getLastArgValue(
9015 options::OPT_fsycl_max_parallel_jobs_EQ);
9026 const JobAction *JA = cast<JobAction>(A);
9029 auto *DA = dyn_cast<OffloadDepsJobAction>(JA);
9034 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
9041 for (
const auto *OA : CollapsedOffloadActions)
9042 cast<OffloadAction>(OA)->doOnEachDependence(
9043 BuildingForOffloadDevice,
9046 C, DepA, DepTC, DepBoundArch,
false,
9047 !!DepBoundArch, LinkingOutput, CachedResults,
9053 for (
const Action *Input : Inputs) {
9057 bool SubJobAtTopLevel =
9058 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
9061 SubJobAtTopLevel, MultipleArchs, LinkingOutput, CachedResults,
9066 const char *BaseInput = InputInfos[0].getBaseInput();
9067 for (
auto &Info : InputInfos) {
9068 if (Info.isFilename()) {
9069 BaseInput = Info.getBaseInput();
9076 if (JA->
getType() == types::TY_dSYM)
9077 BaseInput = InputInfos[0].getFilename();
9080 if (!OffloadDependencesInputInfo.empty())
9081 InputInfos.append(OffloadDependencesInputInfo.begin(),
9082 OffloadDependencesInputInfo.end());
9085 llvm::Triple EffectiveTriple;
9087 const ArgList &Args =
9089 if (InputInfos.size() != 1) {
9093 EffectiveTriple = llvm::Triple(
9101 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
9105 for (
auto &UI : UA->getDependentActionsInfo()) {
9107 "Unbundling with no offloading??");
9114 bool IsFPGAObjLink =
9115 (JA->
getType() == types::TY_Object &&
9116 EffectiveTriple.getSubArch() == llvm::Triple::SPIRSubArch_fpga &&
9117 C.getInputArgs().hasArg(options::OPT_fsycl_link_EQ));
9118 if (
C.getDriver().getOffloadStaticLibSeen() &&
9119 (JA->
getType() == types::TY_Archive ||
9120 JA->
getType() == types::TY_Tempfilelist)) {
9128 std::string TmpFileName =
C.getDriver().GetTemporaryPath(
9129 llvm::sys::path::stem(BaseInput),
9130 JA->
getType() == types::TY_Archive ?
"a" :
"txt");
9131 const char *TmpFile =
C.addTempFile(
9132 C.getArgs().MakeArgString(TmpFileName), JA->
getType());
9137 if (EffectiveTriple.isSPIROrSPIRV()) {
9138 if (!UI.DependentToolChain->getTriple().isSPIROrSPIRV())
9147 if (JA->
getType() == types::TY_FPGA_AOCO) {
9148 TI = types::TY_TempAOCOfilelist;
9151 if (JA->
getType() == types::TY_FPGA_AOCR ||
9152 JA->
getType() == types::TY_FPGA_AOCX ||
9153 JA->
getType() == types::TY_FPGA_AOCR_EMU) {
9157 TI = types::TY_Tempfilelist;
9164 TI = types::TY_Tempfilelist;
9167 std::string TmpFileName =
C.getDriver().GetTemporaryPath(
9168 llvm::sys::path::stem(BaseInput), Ext);
9169 const char *TmpFile =
9170 C.addTempFile(
C.getArgs().MakeArgString(TmpFileName), TI);
9178 UI.DependentOffloadKind,
9179 UI.DependentToolChain->getTriple().normalize(),
9191 UnbundlingResults.push_back(CurI);
9201 Arch = UI.DependentBoundArch;
9213 DependentOffloadKind = UI.DependentOffloadKind;
9216 DependentOffloadKind)}] = {
9222 if (JA->
getType() == types::TY_FPGA_Dependencies ||
9223 JA->
getType() == types::TY_FPGA_Dependencies_List) {
9225 std::string TmpFileName =
9226 C.getDriver().GetTemporaryPath(llvm::sys::path::stem(BaseInput), Ext);
9227 const char *TmpFile =
9228 C.addTempFile(
C.getArgs().MakeArgString(TmpFileName), JA->
getType());
9230 UnbundlingResults.push_back(Result);
9234 std::pair<const Action *, std::string> ActionTC = {
9236 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
9237 "Result does not exist??");
9238 Result = CachedResults[ActionTC].front();
9240 }
else if (
auto *DA = dyn_cast<OffloadDepsJobAction>(JA)) {
9243 "Deps job with no offloading");
9246 DI.DependentOffloadKind,
9247 DI.DependentToolChain->getTriple().normalize(),
9258 UnbundlingResults.push_back(CurI);
9265 : DI.DependentBoundArch
9269 DI.DependentOffloadKind)}] = {
9275 std::pair<const Action *, std::string> ActionTC = {
9277 auto It = CachedResults.find(ActionTC);
9278 assert(It != CachedResults.end() &&
"Result does not exist??");
9279 Result = It->second.front();
9280 }
else if (JA->
getType() == types::TY_Nothing)
9283 std::string OffloadingPrefix;
9287 Args.hasArg(options::OPT_fsycl_link_EQ)) {
9288 OffloadingPrefix =
"-";
9289 OffloadingPrefix += TC->
getTriple().getArchName();
9295 isa<OffloadPackagerJobAction>(A) ||
9299 if (isa<OffloadWrapperJobAction>(JA)) {
9300 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
9301 BaseInput = FinalOutput->getValue();
9306 C.getArgs().MakeArgString(std::string(BaseInput) +
"-wrapper");
9309 AtTopLevel, MultipleArchs,
9312 if (
T->canEmitIR() && OffloadingPrefix.empty())
9317 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
9318 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
9319 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
9320 llvm::errs() << InputInfos[i].getAsString();
9322 llvm::errs() <<
", ";
9324 if (UnbundlingResults.empty())
9325 llvm::errs() <<
"], output: " << Result.getAsString() <<
"\n";
9327 llvm::errs() <<
"], outputs: [";
9328 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
9329 llvm::errs() << UnbundlingResults[i].getAsString();
9331 llvm::errs() <<
", ";
9333 llvm::errs() <<
"] \n";
9336 if (UnbundlingResults.empty())
9338 C, *JA, Result, InputInfos,
9342 T->ConstructJobMultipleOutputs(
9343 C, *JA, UnbundlingResults, InputInfos,
9352 return Target.isOSWindows() ?
"a.exe" :
"a.out";
9364 if (ArgValue.empty()) {
9367 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
9369 llvm::sys::path::append(
Filename, BaseName);
9372 if (!llvm::sys::path::has_extension(ArgValue)) {
9377 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
9382 llvm::sys::path::replace_extension(
Filename, Extension);
9385 return Args.MakeArgString(
Filename.c_str());
9389 if (isa<PreprocessJobAction>(JA))
9391 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
9393 if (isa<OffloadBundlingJobAction>(JA) &&
9400 StringRef Suffix,
bool MultipleArchs,
9401 StringRef BoundArch,
9403 bool NeedUniqueDirectory)
const {
9405 Arg *A = C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
9406 std::optional<std::string> CrashDirectory =
9408 ? std::string(A->getValue())
9409 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
9410 if (CrashDirectory) {
9411 if (!
getVFS().exists(*CrashDirectory))
9412 llvm::sys::fs::create_directories(*CrashDirectory);
9414 llvm::sys::path::append(Path, Prefix);
9415 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
9416 if (std::error_code EC =
9417 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
9418 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
9422 if (MultipleArchs && !BoundArch.empty()) {
9423 if (NeedUniqueDirectory) {
9425 llvm::sys::path::append(TmpName,
9426 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
9436 return C.addTempFile(C.getArgs().MakeArgString(TmpName),
Type);
9451 const char *BaseInput) {
9452 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
9453 (C.getArgs().hasArg(options::OPT_fmodule_output) ||
9454 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
9459 return C.addResultFile(C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
9463 const char *BaseInput,
9464 StringRef OrigBoundArch,
bool AtTopLevel,
9466 StringRef OffloadingPrefix)
const {
9467 std::string BoundArch = OrigBoundArch.str();
9468 if (is_style_windows(llvm::sys::path::Style::native)) {
9471 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
9474 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
9476 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
9477 if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
9478 return C.addResultFile(FinalOutput->getValue(), &JA);
9481 if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT__SLASH_o))
9482 return C.addResultFile(FinalOutput->getValue(), &JA);
9486 if (C.getArgs().hasArg(options::OPT__SLASH_P) &&
9487 ((AtTopLevel && isa<PreprocessJobAction>(JA)) ||
9488 isa<OffloadBundlingJobAction>(JA))) {
9489 StringRef BaseName = llvm::sys::path::filename(BaseInput);
9491 if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi))
9492 NameArg = A->getValue();
9493 return C.addResultFile(
9499 if (isa<AppendFooterJobAction>(JA)) {
9500 if (Arg *A = C.getArgs().getLastArg(options::OPT_fsycl_footer_path_EQ)) {
9502 StringRef BaseName = llvm::sys::path::filename(BaseInput);
9506 std::string::size_type
End = std::string::npos;
9508 End = BaseName.rfind(
'.');
9510 Suffixed += OffloadingPrefix;
9513 llvm::sys::path::append(OutName, Suffixed.c_str());
9515 std::string TmpName =
9518 llvm::sys::path::append(OutName, llvm::sys::path::filename(TmpName));
9520 return C.addTempFile(C.getArgs().MakeArgString(OutName));
9529 if (JA.
getType() == types::TY_ModuleFile &&
9530 C.getArgs().getLastArg(options::OPT_module_file_info)) {
9534 if (JA.
getType() == types::TY_PP_Asm &&
9535 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
9536 StringRef FcValue = C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
9539 return C.addResultFile(C.getArgs().MakeArgString(FcValue.str()), &JA);
9542 if (JA.
getType() == types::TY_Object &&
9543 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
9544 StringRef FoValue = C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
9547 return C.addResultFile(C.getArgs().MakeArgString(FoValue.str()), &JA);
9551 if (JA.
getType() == types::TY_PP_Asm &&
9552 (C.getArgs().hasArg(options::OPT__SLASH_FA) ||
9553 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
9555 StringRef BaseName = llvm::sys::path::filename(BaseInput);
9556 StringRef FaValue = C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
9557 return C.addResultFile(
9562 if (JA.
getType() == types::TY_API_INFO &&
9563 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
9564 C.getArgs().hasArg(options::OPT_o))
9565 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
9566 << C.getArgs().getLastArgValue(options::OPT_o);
9573 bool SpecifiedModuleOutput =
9574 C.getArgs().hasArg(options::OPT_fmodule_output) ||
9575 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
9576 if (MultipleArchs && SpecifiedModuleOutput)
9577 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
9581 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
9582 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
9583 assert(!C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
9589 (!C.getArgs().hasArg(options::OPT__SLASH_Fo) ||
9593 (C.getArgs().hasArg(options::OPT__SLASH_Fo) &&
9595 isa<OffloadUnbundlingJobAction>(JA) ||
9598 StringRef
Name = llvm::sys::path::filename(BaseInput);
9599 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
9600 const char *Suffix =
9605 llvm::Triple Triple(C.getDriver().getTargetTriple());
9606 bool NeedUniqueDirectory =
9609 Triple.isOSDarwin();
9610 return CreateTempFile(C, Split.first, Suffix, MultipleArchs, BoundArch,
9611 JA.
getType(), NeedUniqueDirectory);
9619 if (isa<DsymutilJobAction>(JA) && C.getArgs().hasArg(options::OPT_dsym_dir)) {
9620 ExternalPath += C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
9625 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
9626 llvm::sys::path::filename(BasePath));
9627 BaseName = ExternalPath;
9628 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
9629 BaseName = BasePath;
9631 BaseName = llvm::sys::path::filename(BasePath);
9634 const char *NamedOutput;
9636 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
9637 JA.
getType() == types::TY_Archive) &&
9638 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
9642 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
9646 }
else if (JA.
getType() == types::TY_Image &&
9647 C.getArgs().hasArg(options::OPT__SLASH_Fe,
9648 options::OPT__SLASH_o)) {
9652 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
9656 }
else if (JA.
getType() == types::TY_Image) {
9666 !C.getArgs().hasFlag(options::OPT_fgpu_rdc,
9667 options::OPT_fno_gpu_rdc,
false);
9668 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA) ||
9669 isa<BackendCompileJobAction>(JA);
9670 if (UseOutExtension) {
9672 llvm::sys::path::replace_extension(Output,
"");
9674 Output += OffloadingPrefix;
9675 if (MultipleArchs && !BoundArch.empty()) {
9677 Output.append(BoundArch);
9679 if (UseOutExtension)
9681 NamedOutput = C.getArgs().MakeArgString(Output.c_str());
9684 NamedOutput = C.getArgs().MakeArgString(
GetClPchPath(C, BaseName));
9685 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
9686 C.getArgs().hasArg(options::OPT__SLASH_o)) {
9689 .getLastArg(options::OPT__SLASH_o)
9694 const char *Suffix =
9696 assert(Suffix &&
"All types used for output should have a suffix.");
9698 std::string::size_type
End = std::string::npos;
9700 End = BaseName.rfind(
'.');
9702 Suffixed += OffloadingPrefix;
9703 if (MultipleArchs && !BoundArch.empty()) {
9705 Suffixed.append(BoundArch);
9710 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
9711 const llvm::opt::DerivedArgList &Args) {
9716 return isa<CompileJobAction>(JA) &&
9718 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
9723 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
9724 (C.getArgs().hasArg(options::OPT_emit_llvm) ||
9725 IsAMDRDCInCompilePhase(JA, C.getArgs())))
9729 NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str());
9733 if (!AtTopLevel &&
isSaveTempsObj() && C.getArgs().hasArg(options::OPT_o) &&
9734 JA.
getType() != types::TY_PCH) {
9735 Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
9737 llvm::sys::path::remove_filename(TempPath);
9738 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
9739 llvm::sys::path::append(TempPath, OutputFileName);
9740 NamedOutput = C.getArgs().MakeArgString(TempPath.c_str());
9746 if (!AtTopLevel && NamedOutput == BaseName) {
9747 bool SameFile =
false;
9749 llvm::sys::fs::current_path(Result);
9750 llvm::sys::path::append(Result, BaseName);
9751 llvm::sys::fs::equivalent(BaseInput, Result.c_str(), SameFile);
9754 StringRef
Name = llvm::sys::path::filename(BaseInput);
9755 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
9759 return C.addTempFile(C.getArgs().MakeArgString(TmpName));
9763 const auto &ResultFiles = C.getResultFiles();
9764 const auto CollidingFilenameIt =
9765 llvm::find_if(ResultFiles, [NamedOutput](
const auto &It) {
9766 return StringRef(NamedOutput) == It.second;
9768 if (CollidingFilenameIt != ResultFiles.end()) {
9771 StringRef CollidingName(CollidingFilenameIt->second);
9772 std::pair<StringRef, StringRef> Split = CollidingName.split(
'.');
9776 return C.addTempFile(C.getArgs().MakeArgString(UniqueName));
9782 if (C.getArgs().hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false) &&
9783 JA.
getType() == types::TY_PCH)
9784 Diag(clang::diag::err_drv_fsycl_with_pch);
9787 llvm::sys::path::remove_filename(BasePath);
9788 if (BasePath.empty())
9789 BasePath = NamedOutput;
9791 llvm::sys::path::append(BasePath, NamedOutput);
9792 return C.addResultFile(C.getArgs().MakeArgString(BasePath.c_str()), &JA);
9795 return C.addResultFile(NamedOutput, &JA);
9801 -> std::optional<std::string> {
9804 for (
const auto &
Dir :
P) {
9808 llvm::sys::path::append(
P,
Name);
9809 if (llvm::sys::fs::exists(Twine(
P)))
9810 return std::string(
P);
9812 return std::nullopt;
9819 llvm::sys::path::append(R,
Name);
9820 if (llvm::sys::fs::exists(Twine(R)))
9821 return std::string(R);
9824 llvm::sys::path::append(
P,
Name);
9825 if (llvm::sys::fs::exists(Twine(
P)))
9826 return std::string(
P);
9829 llvm::sys::path::append(D,
"..",
Name);
9830 if (llvm::sys::fs::exists(Twine(D)))
9831 return std::string(D);
9839 return std::string(
Name);
9842 void Driver::generatePrefixedToolNames(
9846 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
9847 Names.emplace_back(
Tool);
9851 llvm::sys::path::append(
Dir,
Name);
9852 if (llvm::sys::fs::can_execute(Twine(
Dir)))
9854 llvm::sys::path::remove_filename(
Dir);
9860 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
9865 if (llvm::sys::fs::is_directory(PrefixDir)) {
9868 return std::string(
P);
9871 if (llvm::sys::fs::can_execute(Twine(
P)))
9872 return std::string(
P);
9877 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
9885 for (
const auto &Path : List) {
9888 return std::string(
P);
9892 if (llvm::ErrorOr<std::string>
P =
9893 llvm::sys::findProgramByName(TargetSpecificExecutable))
9897 return std::string(
Name);
9902 std::string error =
"<NOT PRESENT>";
9906 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
9923 llvm::sys::path::remove_filename(path);
9924 llvm::sys::path::append(path,
"libc++.modules.json");
9925 if (TC.
getVFS().exists(path))
9926 return static_cast<std::string
>(path);
9931 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
9934 return evaluate(
"libc++.a").value_or(error);
9947 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
9949 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
9953 return std::string(Path);
9958 std::error_code EC = llvm::sys::fs::getPotentiallyUniqueFileName(
9959 Twine(BaseName) + Twine(
"-%%%%%%.") + Ext, Path);
9961 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
9965 return std::string(Path.str());
9970 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
9972 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
9976 return std::string(Path);
9981 if (Arg *FpArg = C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
9985 Output = FpArg->getValue();
9989 if (!llvm::sys::path::has_extension(Output))
9992 if (Arg *YcArg = C.getArgs().getLastArg(options::OPT__SLASH_Yc))
9993 Output = YcArg->getValue();
9996 llvm::sys::path::replace_extension(Output,
".pch");
9998 return std::string(Output);
10001 const ToolChain &Driver::getToolChain(
const ArgList &Args,
10002 const llvm::Triple &
Target)
const {
10004 auto &TC = ToolChains[
Target.str()];
10006 switch (
Target.getOS()) {
10008 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
10010 case llvm::Triple::Haiku:
10011 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
10013 case llvm::Triple::Darwin:
10014 case llvm::Triple::MacOSX:
10015 case llvm::Triple::IOS:
10016 case llvm::Triple::TvOS:
10017 case llvm::Triple::WatchOS:
10018 case llvm::Triple::XROS:
10019 case llvm::Triple::DriverKit:
10020 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
10022 case llvm::Triple::DragonFly:
10023 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
10025 case llvm::Triple::OpenBSD:
10026 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
10028 case llvm::Triple::NetBSD:
10029 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
10031 case llvm::Triple::FreeBSD:
10033 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
10036 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
10038 case llvm::Triple::Linux:
10039 case llvm::Triple::ELFIAMCU:
10040 if (
Target.getArch() == llvm::Triple::hexagon)
10041 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
10043 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
10044 !
Target.hasEnvironment())
10045 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
10047 else if (
Target.isPPC())
10048 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
10050 else if (
Target.getArch() == llvm::Triple::ve)
10051 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
10052 else if (
Target.isOHOSFamily())
10053 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
10055 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
10057 case llvm::Triple::NaCl:
10058 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
10060 case llvm::Triple::Fuchsia:
10061 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
10063 case llvm::Triple::Solaris:
10064 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
10066 case llvm::Triple::CUDA:
10067 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
10069 case llvm::Triple::AMDHSA:
10070 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
10072 case llvm::Triple::AMDPAL:
10073 case llvm::Triple::Mesa3D:
10074 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
10076 case llvm::Triple::Win32:
10077 switch (
Target.getEnvironment()) {
10079 if (
Target.isOSBinFormatELF())
10080 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
10081 else if (
Target.isOSBinFormatMachO())
10082 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
10084 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
10086 case llvm::Triple::GNU:
10087 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
10089 case llvm::Triple::Itanium:
10090 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
10093 case llvm::Triple::MSVC:
10094 case llvm::Triple::UnknownEnvironment:
10095 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
10096 .starts_with_insensitive(
"bfd"))
10097 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
10101 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
10105 case llvm::Triple::PS4:
10106 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
10108 case llvm::Triple::PS5:
10109 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
10111 case llvm::Triple::Hurd:
10112 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
10114 case llvm::Triple::LiteOS:
10115 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
10117 case llvm::Triple::ZOS:
10118 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
10120 case llvm::Triple::ShaderModel:
10121 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
10126 switch (
Target.getArch()) {
10127 case llvm::Triple::tce:
10128 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
10130 case llvm::Triple::tcele:
10131 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
10133 case llvm::Triple::hexagon:
10134 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
10137 case llvm::Triple::lanai:
10138 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
10140 case llvm::Triple::xcore:
10141 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
10143 case llvm::Triple::wasm32:
10144 case llvm::Triple::wasm64:
10145 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
10147 case llvm::Triple::avr:
10148 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
10150 case llvm::Triple::msp430:
10152 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
10154 case llvm::Triple::riscv32:
10155 case llvm::Triple::riscv64:
10158 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
10160 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
10162 case llvm::Triple::ve:
10163 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
10165 case llvm::Triple::spirv32:
10166 case llvm::Triple::spirv64:
10167 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
10169 case llvm::Triple::csky:
10170 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
10174 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
10175 else if (
Target.isOSBinFormatELF())
10176 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
10177 else if (
Target.isOSBinFormatMachO())
10178 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
10180 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
10188 const ToolChain &Driver::getOffloadingDeviceToolChain(
10189 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
10193 auto &TC = ToolChains[
Target.str() +
"/" + HostTC.
getTriple().str() +
10194 std::to_string(TargetDeviceOffloadKind)];
10199 switch (TargetDeviceOffloadKind) {
10201 TC = std::make_unique<toolchains::CudaToolChain>(
10202 *
this,
Target, HostTC, Args, TargetDeviceOffloadKind);
10205 if (
Target.getArch() == llvm::Triple::amdgcn &&
10206 Target.getVendor() == llvm::Triple::AMD &&
10207 Target.getOS() == llvm::Triple::AMDHSA)
10208 TC = std::make_unique<toolchains::HIPAMDToolChain>(
10209 *
this,
Target, HostTC, Args, TargetDeviceOffloadKind);
10210 else if (
Target.getArch() == llvm::Triple::spirv64 &&
10211 Target.getVendor() == llvm::Triple::UnknownVendor &&
10212 Target.getOS() == llvm::Triple::UnknownOS)
10213 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
10219 TC = std::make_unique<toolchains::CudaToolChain>(
10220 *
this,
Target, HostTC, Args, TargetDeviceOffloadKind);
10223 switch (
Target.getArch()) {
10224 case llvm::Triple::spir:
10225 case llvm::Triple::spir64:
10226 case llvm::Triple::spirv32:
10227 case llvm::Triple::spirv64:
10228 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, HostTC,
10231 case llvm::Triple::nvptx:
10232 case llvm::Triple::nvptx64:
10233 TC = std::make_unique<toolchains::CudaToolChain>(
10234 *
this,
Target, HostTC, Args, TargetDeviceOffloadKind);
10236 case llvm::Triple::amdgcn:
10237 TC = std::make_unique<toolchains::HIPAMDToolChain>(
10238 *
this,
Target, HostTC, Args, TargetDeviceOffloadKind);
10242 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target,
10258 if (JA.
size() != 1 ||
10263 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
10264 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
10265 !isa<ExtractAPIJobAction>(JA))
10273 if (JA.
size() != 1 ||
10278 if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) &&
10279 !isa<BackendJobAction>(JA))
10287 if (Args.hasArg(options::OPT_emit_static_lib))
10298 unsigned &Micro,
bool &HadExtra) {
10301 Major = Minor = Micro = 0;
10305 if (Str.consumeInteger(10, Major))
10309 if (!Str.consume_front(
"."))
10312 if (Str.consumeInteger(10, Minor))
10316 if (!Str.consume_front(
"."))
10319 if (Str.consumeInteger(10, Micro))
10337 unsigned CurDigit = 0;
10338 while (CurDigit < Digits.size()) {
10340 if (Str.consumeInteger(10, Digit))
10342 Digits[CurDigit] = Digit;
10345 if (!Str.consume_front(
"."))
10355 Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
10356 if (!UseDriverMode)
10368 const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
10375 return "clang-cpp";
10381 return "clang-dxc";
10384 llvm_unreachable(
"Unhandled Mode");
10388 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
10392 if (llvm::sys::fs::is_directory(
FileName))
10394 if (!llvm::sys::path::has_extension(
FileName))
10397 return FileName.rfind(
"-l", 0) != 0;
10398 std::string Ext(llvm::sys::path::extension(
FileName).drop_front());
10401 return (Ext !=
"lib" &&
10406 if (!llvm::sys::path::has_extension(
FileName))
10409 llvm::file_magic Magic;
10410 llvm::identify_magic(
FileName, Magic);
10412 return (Magic == llvm::file_magic::archive);
10417 if (Args.hasFlag(options::OPT_fsave_optimization_record,
10418 options::OPT_fno_save_optimization_record,
false))
10422 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
10423 options::OPT_fno_save_optimization_record,
false))
10427 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
10428 options::OPT_fno_save_optimization_record,
false))
10432 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
10433 options::OPT_fno_save_optimization_record,
false))
10440 static StringRef OptName =
10442 llvm::StringRef Opt;
10443 for (StringRef Arg : Args) {
10444 if (!Arg.starts_with(OptName))
10450 return Opt.consume_front(OptName) ? Opt :
"";
10457 llvm::BumpPtrAllocator &Alloc,
10458 llvm::vfs::FileSystem *FS) {
10467 for (
const char *F : Args) {
10468 if (strcmp(F,
"--rsp-quoting=posix") == 0)
10469 RSPQuoting = POSIX;
10470 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
10471 RSPQuoting = Windows;
10479 llvm::cl::TokenizerCallback Tokenizer;
10481 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
10483 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
10485 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
10488 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
10489 ECtx.setMarkEOLs(MarkEOLs);
10493 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
10497 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
10498 [](
const char *A) {
return A !=
nullptr; });
10499 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
10502 auto newEnd =
std::remove(Args.begin(), Args.end(),
nullptr);
10503 Args.resize(newEnd - Args.begin());
10507 return llvm::Error::success();
10511 return SavedStrings.insert(S).first->getKeyData();
10544 llvm::StringSet<> &SavedStrings) {
10547 if (Edit[0] ==
'^') {
10548 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
10549 OS <<
"### Adding argument " << Str <<
" at beginning\n";
10550 Args.insert(Args.begin() + 1, Str);
10551 }
else if (Edit[0] ==
'+') {
10552 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
10553 OS <<
"### Adding argument " << Str <<
" at end\n";
10554 Args.push_back(Str);
10555 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
10556 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
10557 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
10558 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
10559 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
10561 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
10563 if (Args[i] ==
nullptr)
10565 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
10567 if (Repl != Args[i]) {
10568 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
10572 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
10573 auto Option = Edit.substr(1);
10574 for (
unsigned i = 1; i < Args.size();) {
10575 if (Option == Args[i]) {
10576 OS <<
"### Deleting argument " << Args[i] <<
'\n';
10577 Args.erase(Args.begin() + i);
10578 if (Edit[0] ==
'X') {
10579 if (i < Args.size()) {
10580 OS <<
"### Deleting argument " << Args[i] <<
'\n';
10581 Args.erase(Args.begin() + i);
10583 OS <<
"### Invalid X edit, end of command line!\n";
10588 }
else if (Edit[0] ==
'O') {
10589 for (
unsigned i = 1; i < Args.size();) {
10590 const char *A = Args[i];
10594 if (A[0] ==
'-' && A[1] ==
'O' &&
10595 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
10596 (
'0' <= A[2] && A[2] <=
'9'))))) {
10597 OS <<
"### Deleting argument " << Args[i] <<
'\n';
10598 Args.erase(Args.begin() + i);
10602 OS <<
"### Adding argument " << Edit <<
" at end\n";
10603 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
10605 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
10610 const char *OverrideStr,
10611 llvm::StringSet<> &SavedStrings,
10614 OS = &llvm::nulls();
10616 if (OverrideStr[0] ==
'#') {
10618 OS = &llvm::nulls();
10621 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
10625 const char *S = OverrideStr;
10627 const char *
End = ::strchr(S,
' ');
10629 End = S + strlen(S);
clang::driver::toolchains::AIX AIX
static void CollectForEachInputs(InputInfoList &InputInfos, const Action *SourceAction, const ToolChain *TC, StringRef BoundArch, Action::OffloadKind TargetDeviceOffloadKind, const std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, const ForEachWrappingAction *FEA)
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static bool addSYCLDefaultTriple(Compilation &C, SmallVectorImpl< llvm::Triple > &SYCLTriples)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static bool hasOffloadSections(Compilation &C, const StringRef &File, DerivedArgList &Args)
static bool HasPreprocessOutput(const Action &JA)
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple, bool SuppressError=false)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static Arg * MakeInputArg(DerivedArgList &Args, const OptTable &Opts, StringRef Value, bool Claim=true)
static SmallVector< std::string, 4 > getOffloadSections(Compilation &C, const StringRef &File)
static bool hasFPGABinary(Compilation &C, std::string Object, types::ID Type)
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef DarwinArchName="")
Compute target triple from args.
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static bool ContainsOffloadDepsAction(const Action *A)
Check whether the given input tree contains any clang-offload-dependency actions.
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static bool hasSYCLDefaultSection(Compilation &C, const StringRef &File)
static SmallVector< const char *, 16 > getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj=false)
static std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static bool runBundler(const SmallVectorImpl< StringRef > &InputArgs, Compilation &C)
static const char * getDefaultSYCLArch(Compilation &C)
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool optionMatches(const std::string &Option, const std::string &OptCheck)
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static bool IsSYCLDeviceLibObj(std::string ObjFilePath, bool isMSVCEnv)
static bool isValidSYCLTriple(llvm::Triple T)
static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args, OptSpecifier OptEq, OptSpecifier OptNeg)
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static void appendOneArg(InputArgList &Args, const Arg *Opt, const Arg *BaseArg)
static const char BugReporMsg[]
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static std::optional< llvm::Triple > getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args)
static std::optional< llvm::Triple > getOffloadTargetTriple(const Driver &D, const ArgList &Args)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
static std::optional< llvm::Triple > getNVIDIAOffloadTargetTriple(const Driver &D, const ArgList &Args, const llvm::Triple &HostTriple)
llvm::MachO::FileType FileType
llvm::MachO::Target Target
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
The result of parsing/analyzing an expression, statement etc.
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool hasErrorOccurred() const
Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const
Based on the way the client configured the DiagnosticsEngine object, classify the specified diagnosti...
Encodes a location in the source.
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
The base class of the type hierarchy.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
const char * getClassName() const
const char * getOffloadingArch() const
unsigned getOffloadingHostActiveKinds() const
bool isOffloading(OffloadKind OKind) const
Command - An executable path/name and argument vector to execute.
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
StringRef getDiagForErrorCode(int ErrorCode) const
Get the custom driver diagnostic message for a particular error code if such was stored.
virtual int Execute(ArrayRef< std::optional< StringRef >> Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
const llvm::opt::ArgStringList & getArguments() const
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
void replaceArguments(llvm::opt::ArgStringList List)
Compilation - A set of tasks to perform for a single driver invocation.
A class to find a viable CUDA installation.
void WarnIfUnsupportedVersion()
std::string getLibDeviceFile(StringRef Gpu) const
Get libdevice file for given architecture.
bool isValid() const
Check whether we detected a valid Cuda install.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
llvm::Triple MakeSYCLDeviceTriple(StringRef TargetArch="spir64") const
MakeSYCLDeviceTriple - Returns the SYCL device triple for the specified subarch.
std::string SysRoot
sysroot, if present
SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
std::string UserConfigDir
User directory for config files.
void addSYCLDeviceTraitsMacroArg(const llvm::opt::ArgList &Args, StringRef Macro) const
SYCLDeviceTraitMacroArg - Add the given macro to the vector of args to be added to the device compila...
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, types::ID Type=types::TY_Nothing, bool NeedUniqueDirectory=false) const
Creates a temp file.
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, Action *HostAction) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
llvm::DenseSet< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain *TC, bool SuppressError=false) const
Returns the set of bound architectures active for this offload kind.
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
void PrintSYCLToolHelp(const Compilation &C) const
PrintSYCLToolHelp - Print help text from offline compiler tools.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
llvm::vfs::FileSystem & getVFS() const
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
void addIntegrationFiles(StringRef IntHeaderName, StringRef IntFooterName, StringRef FileName) const
addIntegrationFiles - Add the integration files that will be populated by the device compilation and ...
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
std::string Name
The name the driver was invoked as.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
std::string ClangExecutable
The original path to the clang executable.
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void addSYCLUniqueID(StringRef UniqueID, StringRef FileName) const
setSYCLUniqueID - set the Unique ID that is used for all FE invocations when performing compilations ...
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
LTOKind getLTOMode(bool IsOffload=false) const
Get the specific kind of LTO being performed.
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
bool getUseNewOffloadingDriver() const
getUseNewOffloadingDriver - use the new offload driver for OpenMP.
bool HandleImmediateArgs(const Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
std::pair< types::ID, const llvm::opt::Arg * > InputTy
An input type and its arguments.
bool IsFPGAHWMode() const
DiagnosticsEngine & getDiags() const
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError)
ParseArgStrings - Parse the given list of strings into an ArgList.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetUniquePath(StringRef BaseName, StringRef Ext) const
GetUniquePath = Return the pathname of a unique file to use as part of compilation.
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
const llvm::opt::OptTable & getOpts() const
std::string ResourceDir
The path to the compiler resource directory.
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
bool isUsingLTO(bool IsOffload=false) const
Returns true if we are performing any kind of LTO.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
static std::string GetResourcesPath(StringRef BinaryPath, StringRef CustomResourceDir="")
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
std::string getTargetTriple() const
bool getCheckInputsExist() const
bool CCCIsCC() const
Whether the driver should follow gcc like behavior.
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
bool IsFPGAEmulationMode() const
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
void setOffloadCompileMode(DeviceMode ModeValue)
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Wrap all jobs performed between TFormInput (excluded) and Job (included) behind a llvm-foreach call.
void addSerialAction(const Action *A)
const llvm::SmallSetVector< const Action *, 2 > & getSerialActions() const
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
ArrayRef< DependentActionInfo > getDependentActionsInfo() const
Return the information about all depending actions.
const ToolChain * getHostTC() const
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
void setOffloadKind(OffloadKind SetKind)
Set a ToolChain's effective triple.
void getSYCLDeviceLibPath(llvm::SmallVector< llvm::SmallString< 128 >, 4 > &DeviceLibPaths) const
void setRTSetsSpecConstants(bool Val)
const char * getPhaseName(ID Id)
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
bool isFPGA(ID Id)
isFPGA - Is this FPGA input.
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
ID getPrecompiledType(ID Id)
getPrecompiledType - Get the ID of the type for this input when it has been precompiled,...
bool isHIP(ID Id)
isHIP - Is this a HIP input.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
bool isArchive(ID Id)
isArchive - Is this an archive input.
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
bool isSYCLNativeCPU(const llvm::opt::ArgList &Args)
bool isStaticArchiveFile(const StringRef &FileName)
bool isObjectFile(std::string FileName)
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
const llvm::opt::OptTable & getDriverOptTable()
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
std::string toString(const til::SExpr *E)
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
CudaArch StringToCudaArch(llvm::StringRef S)
static bool IsAMDGpuArch(CudaArch A)
static bool IsNVIDIAGpuArch(CudaArch A)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
const FunctionProtoType * T
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
const char * CudaArchToString(CudaArch A)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Visibility
Describes the different kinds of visibility that a declaration may have.
float __ovld __cnfn normalize(float)
Returns a vector in the same direction as p but with a length of 1.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
llvm::SmallVector< std::string, 4 > TemporaryFiles
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
std::string ModeSuffix
Driver mode part of the executable name, as g++.
std::string TargetPrefix
Target part of the executable name, as i686-linux-android.