58#include "clang/Config/config.h"
69#include "llvm/ADT/ArrayRef.h"
70#include "llvm/ADT/STLExtras.h"
71#include "llvm/ADT/StringExtras.h"
72#include "llvm/ADT/StringRef.h"
73#include "llvm/ADT/StringSet.h"
74#include "llvm/ADT/StringSwitch.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/Support/CommandLine.h"
83#include "llvm/Support/ErrorHandling.h"
84#include "llvm/Support/ExitCodes.h"
85#include "llvm/Support/FileSystem.h"
86#include "llvm/Support/FormatVariadic.h"
87#include "llvm/Support/MD5.h"
88#include "llvm/Support/Path.h"
89#include "llvm/Support/PrettyStackTrace.h"
90#include "llvm/Support/Process.h"
91#include "llvm/Support/Program.h"
92#include "llvm/Support/Regex.h"
93#include "llvm/Support/StringSaver.h"
94#include "llvm/Support/VirtualFileSystem.h"
95#include "llvm/Support/raw_ostream.h"
96#include "llvm/TargetParser/Host.h"
97#include "llvm/TargetParser/RISCVISAInfo.h"
109using namespace clang;
113 const ArgList &Args) {
114 auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
118 switch (OffloadTargets.size()) {
120 D.Diag(diag::err_drv_only_one_offload_target_supported);
123 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) <<
"";
128 return llvm::Triple(OffloadTargets[0]);
131static std::optional<llvm::Triple>
133 const llvm::Triple &HostTriple) {
134 if (!Args.hasArg(options::OPT_offload_EQ)) {
135 return llvm::Triple(HostTriple.isArch64Bit() ?
"nvptx64-nvidia-cuda"
136 :
"nvptx-nvidia-cuda");
139 if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
140 TT->getArch() == llvm::Triple::spirv64)) {
141 if (Args.hasArg(options::OPT_emit_llvm))
143 D.Diag(diag::err_drv_cuda_offload_only_emit_bc);
146 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
149static std::optional<llvm::Triple>
151 if (!Args.hasArg(options::OPT_offload_EQ)) {
152 auto OffloadArchs = Args.getAllArgValues(options::OPT_offload_arch_EQ);
153 if (llvm::is_contained(OffloadArchs,
"amdgcnspirv") &&
154 OffloadArchs.size() == 1)
155 return llvm::Triple(
"spirv64-amd-amdhsa");
156 return llvm::Triple(
"amdgcn-amd-amdhsa");
161 if (TT->getArch() == llvm::Triple::amdgcn &&
162 TT->getVendor() == llvm::Triple::AMD &&
163 TT->getOS() == llvm::Triple::AMDHSA)
165 if (TT->getArch() == llvm::Triple::spirv64)
167 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
178 StringRef
Dir = llvm::sys::path::parent_path(BinaryPath);
181 StringRef ConfiguredResourceDir(CLANG_RESOURCE_DIR);
182 if (!ConfiguredResourceDir.empty()) {
183 llvm::sys::path::append(
P, ConfiguredResourceDir);
190 P = llvm::sys::path::parent_path(
Dir);
193 llvm::sys::path::append(
P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
194 CLANG_VERSION_MAJOR_STRING);
197 return std::string(
P);
203 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
204 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
207 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
208 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
209 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
210 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
211 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
212 CheckInputsExist(
true), ProbePrecompiled(
true),
213 SuppressMissingInputWarning(
false) {
216 this->VFS = llvm::vfs::getRealFileSystem();
221 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
224 llvm::sys::path::append(
P,
SysRoot);
228#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
229 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
233 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
234 llvm::sys::path::remove_dots(configFileDir,
true);
238#if defined(CLANG_CONFIG_FILE_USER_DIR)
241 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
250void Driver::setDriverMode(StringRef
Value) {
251 static StringRef OptName =
252 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
253 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
254 .Case(
"gcc", GCCMode)
255 .Case(
"g++", GXXMode)
256 .Case(
"cpp", CPPMode)
258 .Case(
"flang", FlangMode)
259 .Case(
"dxc", DXCMode)
263 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
267 bool UseDriverMode,
bool &ContainsError) {
268 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
269 ContainsError =
false;
271 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
272 unsigned MissingArgIndex, MissingArgCount;
273 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
274 MissingArgCount, VisibilityMask);
277 if (MissingArgCount) {
278 Diag(diag::err_drv_missing_argument)
279 << Args.getArgString(MissingArgIndex) << MissingArgCount;
286 for (
const Arg *A : Args) {
288 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
296 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
297 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
299 diag::warn_drv_empty_joined_argument,
304 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
306 auto ArgString = A->getAsString(Args);
308 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
310 getOpts().findExact(ArgString, Nearest,
312 DiagID = diag::err_drv_unknown_argument_with_suggestion;
313 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
315 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
316 : diag::err_drv_unknown_argument;
317 Diags.
Report(DiagID) << ArgString;
321 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
322 : diag::err_drv_unknown_argument_with_suggestion;
323 Diags.
Report(DiagID) << ArgString << Nearest;
329 for (
const Arg *A : Args.filtered(options::OPT_o)) {
330 if (ArgStrings[A->getIndex()] == A->getSpelling())
334 std::string ArgString = ArgStrings[A->getIndex()];
336 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
337 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
338 << A->getAsString(Args) << Nearest;
348 Arg **FinalPhaseArg)
const {
349 Arg *PhaseArg =
nullptr;
353 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
354 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
355 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
356 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
363 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
366 options::OPT_fmodule_header_EQ))) {
369 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
370 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
371 (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
372 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
373 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
374 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
375 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
376 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
377 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
378 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
379 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
383 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
387 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
390 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
398 *FinalPhaseArg = PhaseArg;
404 StringRef
Value,
bool Claim =
true) {
405 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
406 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
407 Args.AddSynthesizedArg(A);
413DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
414 const llvm::opt::OptTable &Opts =
getOpts();
415 DerivedArgList *DAL =
new DerivedArgList(Args);
417 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
418 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
419 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
420 bool IgnoreUnused =
false;
421 for (Arg *A : Args) {
425 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
429 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
430 IgnoreUnused =
false;
440 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
441 A->getOption().matches(options::OPT_Xlinker)) &&
442 A->containsValue(
"--no-demangle")) {
444 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
447 for (StringRef Val : A->getValues())
448 if (Val !=
"--no-demangle")
449 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
457 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
458 A->getNumValues() > 0 &&
459 (A->getValue(0) == StringRef(
"-MD") ||
460 A->getValue(0) == StringRef(
"-MMD"))) {
462 if (A->getValue(0) == StringRef(
"-MD"))
463 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
465 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
466 if (A->getNumValues() == 2)
467 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
472 if (A->getOption().matches(options::OPT_l)) {
473 StringRef
Value = A->getValue();
476 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
478 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
483 if (
Value ==
"cc_kext") {
484 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
490 if (A->getOption().matches(options::OPT__DASH_DASH)) {
492 for (StringRef Val : A->getValues())
501 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
502 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
505 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
506 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
510#if defined(HOST_LINK_VERSION)
511 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
512 strlen(HOST_LINK_VERSION) > 0) {
513 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
515 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
527 StringRef TargetTriple,
529 StringRef DarwinArchName =
"") {
531 if (
const Arg *A = Args.getLastArg(options::OPT_target))
532 TargetTriple = A->getValue();
534 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
539 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
543 if (
Target.isOSBinFormatMachO()) {
545 if (!DarwinArchName.empty()) {
552 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
553 StringRef ArchName = A->getValue();
560 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
561 options::OPT_mbig_endian)) {
562 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
563 ?
Target.getLittleEndianArchVariant()
564 :
Target.getBigEndianArchVariant();
565 if (
T.getArch() != llvm::Triple::UnknownArch) {
567 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
572 if (
Target.getArch() == llvm::Triple::tce)
577 if (std::optional<std::string> ObjectModeValue =
578 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
579 StringRef ObjectMode = *ObjectModeValue;
580 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
582 if (ObjectMode ==
"64") {
583 AT =
Target.get64BitArchVariant().getArch();
584 }
else if (ObjectMode ==
"32") {
585 AT =
Target.get32BitArchVariant().getArch();
587 D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
590 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
596 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
598 D.Diag(diag::err_drv_unsupported_opt_for_target)
599 << A->getAsString(Args) <<
Target.str();
602 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
603 options::OPT_m32, options::OPT_m16,
604 options::OPT_maix32, options::OPT_maix64);
606 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
608 if (A->getOption().matches(options::OPT_m64) ||
609 A->getOption().matches(options::OPT_maix64)) {
610 AT =
Target.get64BitArchVariant().getArch();
611 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
612 Target.getEnvironment() == llvm::Triple::GNUT64)
613 Target.setEnvironment(llvm::Triple::GNU);
614 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
615 Target.setEnvironment(llvm::Triple::Musl);
616 }
else if (A->getOption().matches(options::OPT_mx32) &&
617 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
618 AT = llvm::Triple::x86_64;
619 if (
Target.getEnvironment() == llvm::Triple::Musl)
620 Target.setEnvironment(llvm::Triple::MuslX32);
622 Target.setEnvironment(llvm::Triple::GNUX32);
623 }
else if (A->getOption().matches(options::OPT_m32) ||
624 A->getOption().matches(options::OPT_maix32)) {
625 AT =
Target.get32BitArchVariant().getArch();
626 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
627 Target.setEnvironment(llvm::Triple::GNU);
628 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
629 Target.setEnvironment(llvm::Triple::Musl);
630 }
else if (A->getOption().matches(options::OPT_m16) &&
631 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
632 AT = llvm::Triple::x86;
633 Target.setEnvironment(llvm::Triple::CODE16);
636 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
638 if (
Target.isWindowsGNUEnvironment())
644 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
645 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
646 D.Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
649 if (A && !A->getOption().matches(options::OPT_m32))
650 D.Diag(diag::err_drv_argument_not_allowed_with)
651 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
653 Target.setArch(llvm::Triple::x86);
654 Target.setArchName(
"i586");
655 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
656 Target.setEnvironmentName(
"");
657 Target.setOS(llvm::Triple::ELFIAMCU);
658 Target.setVendor(llvm::Triple::UnknownVendor);
659 Target.setVendorName(
"intel");
665 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
666 StringRef ABIName = A->getValue();
667 if (ABIName ==
"32") {
669 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
670 Target.getEnvironment() == llvm::Triple::GNUABIN32)
671 Target.setEnvironment(llvm::Triple::GNU);
672 }
else if (ABIName ==
"n32") {
674 if (
Target.getEnvironment() == llvm::Triple::GNU ||
675 Target.getEnvironment() == llvm::Triple::GNUT64 ||
676 Target.getEnvironment() == llvm::Triple::GNUABI64)
677 Target.setEnvironment(llvm::Triple::GNUABIN32);
678 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
679 Target.getEnvironment() == llvm::Triple::MuslABI64)
680 Target.setEnvironment(llvm::Triple::MuslABIN32);
681 }
else if (ABIName ==
"64") {
683 if (
Target.getEnvironment() == llvm::Triple::GNU ||
684 Target.getEnvironment() == llvm::Triple::GNUT64 ||
685 Target.getEnvironment() == llvm::Triple::GNUABIN32)
686 Target.setEnvironment(llvm::Triple::GNUABI64);
687 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
688 Target.getEnvironment() == llvm::Triple::MuslABIN32)
689 Target.setEnvironment(llvm::Triple::MuslABI64);
697 if (Args.hasArg(options::OPT_march_EQ) ||
698 Args.hasArg(options::OPT_mcpu_EQ)) {
700 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
702 if (!llvm::errorToBool(ISAInfo.takeError())) {
703 unsigned XLen = (*ISAInfo)->getXLen();
705 Target.setArch(llvm::Triple::riscv32);
707 Target.setArch(llvm::Triple::riscv64);
719 OptSpecifier OptEq, OptSpecifier OptNeg) {
720 if (!Args.hasFlag(OptEq, OptNeg,
false))
723 const Arg *A = Args.getLastArg(OptEq);
724 StringRef LTOName = A->getValue();
732 D.Diag(diag::err_drv_unsupported_option_argument)
733 << A->getSpelling() << A->getValue();
740void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
742 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
744 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
745 options::OPT_fno_offload_lto);
748 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
749 options::OPT_fno_openmp_target_jit,
false)) {
750 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
751 options::OPT_fno_offload_lto))
753 Diag(diag::err_drv_incompatible_options)
754 << A->getSpelling() <<
"-fopenmp-target-jit";
761 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
763 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
765 RuntimeName = A->getValue();
767 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
775 Diag(diag::err_drv_unsupported_option_argument)
776 << A->getSpelling() << A->getValue();
779 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
788 if (llvm::is_contained(SYCLAlias, TargetArch)) {
789 llvm::Triple TargetTriple;
790 TargetTriple.setArchName(TargetArch);
791 TargetTriple.setVendor(llvm::Triple::UnknownVendor);
792 TargetTriple.setOS(llvm::Triple::UnknownOS);
795 return llvm::Triple(TargetArch);
801 for (
const auto &SYCLTriple : SYCLTriples) {
802 if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
803 SYCLTriple.isSPIROrSPIRV())
808 C.getDefaultToolChain().getTriple().isArch32Bit() ?
"spirv32"
810 SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple);
823 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
828 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
831 C.getInputArgs().hasArg(options::OPT_hip_link) ||
832 C.getInputArgs().hasArg(options::OPT_hipstdpar);
833 bool UseLLVMOffload =
C.getInputArgs().hasArg(
834 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
835 if (IsCuda && IsHIP) {
836 Diag(clang::diag::err_drv_mix_cuda_hip);
839 if (IsCuda && !UseLLVMOffload) {
841 const llvm::Triple &HostTriple = HostTC->
getTriple();
849 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
851 CudaTC = std::make_unique<toolchains::CudaToolChain>(
852 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
857 if (CudaInstallation.
isValid())
860 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
861 }
else if (IsHIP && !UseLLVMOffload) {
862 if (
auto *OMPTargetArg =
863 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
864 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
865 << OMPTargetArg->getSpelling() <<
"HIP";
873 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
875 C.addOffloadDeviceToolChain(HIPTC, OFK);
883 bool IsOpenMPOffloading =
884 ((IsCuda || IsHIP) && UseLLVMOffload) ||
885 (
C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
886 options::OPT_fno_openmp,
false) &&
887 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
888 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ)));
889 if (IsOpenMPOffloading) {
895 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
899 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
900 llvm::StringMap<StringRef> FoundNormalizedTriples;
901 std::multiset<StringRef> OpenMPTriples;
906 if (Arg *OpenMPTargets =
907 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
908 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
909 Diag(clang::diag::warn_drv_empty_joined_argument)
910 << OpenMPTargets->getAsString(
C.getInputArgs());
913 for (StringRef
T : OpenMPTargets->getValues())
914 OpenMPTriples.insert(
T);
915 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
916 ((!IsHIP && !IsCuda) || UseLLVMOffload)) {
926 llvm::DenseSet<StringRef> Archs;
928 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
929 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
935 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
936 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
941 if (!AMDTriple && !NVPTXTriple) {
942 for (StringRef Arch :
947 for (StringRef Arch : Archs) {
950 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
951 }
else if (AMDTriple &&
954 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
956 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
963 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
968 for (
const auto &TripleAndArchs : DerivedArchs)
969 OpenMPTriples.insert(TripleAndArchs.first());
972 for (StringRef Val : OpenMPTriples) {
974 std::string NormalizedName = TT.normalize();
977 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
978 if (Duplicate != FoundNormalizedTriples.end()) {
979 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
980 << Val << Duplicate->second;
986 FoundNormalizedTriples[NormalizedName] = Val;
989 if (TT.getArch() == llvm::Triple::UnknownArch)
990 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
995 if (TT.isNVPTX() || TT.isAMDGCN() || TT.isSPIRV()) {
998 assert(HostTC &&
"Host toolchain should be always defined.");
1000 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
1003 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
1004 *
this, TT, *HostTC,
C.getInputArgs());
1005 else if (TT.isAMDGCN())
1006 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
1007 *
this, TT, *HostTC,
C.getInputArgs());
1008 else if (TT.isSPIRV())
1009 DeviceTC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(
1010 *
this, TT, *HostTC,
C.getInputArgs());
1012 assert(DeviceTC &&
"Device toolchain not defined.");
1015 TC = DeviceTC.get();
1017 TC = &getToolChain(
C.getInputArgs(), TT);
1019 auto It = DerivedArchs.find(TT.getTriple());
1020 if (It != DerivedArchs.end())
1021 KnownArchs[TC] = It->second;
1024 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
1025 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1030 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1031 options::OPT_fno_sycl,
false);
1033 auto argSYCLIncompatible = [&](OptSpecifier OptId) {
1036 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(OptId))
1037 Diag(clang::diag::err_drv_argument_not_allowed_with)
1038 << IncompatArg->getSpelling() <<
"-fsycl";
1041 argSYCLIncompatible(options::OPT_static_libstdcxx);
1043 argSYCLIncompatible(options::OPT_ffreestanding);
1054 for (
const auto &TargetTriple : UniqueSYCLTriplesVec) {
1055 auto SYCLTC = &getOffloadingDeviceToolChain(
1066bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1071 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1075 if (!PathLIBEnv.empty()) {
1076 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1077 if (llvm::sys::fs::is_directory(PathLIBEnv))
1078 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1079 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1080 return readConfigFile(CustomizationFile, ExpCtx);
1081 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1086 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1087 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1088 return readConfigFile(CustomizationFile, ExpCtx);
1098 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1099 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1100 Copy->getValues() = Opt->getValues();
1101 if (Opt->isClaimed())
1103 Copy->setOwnsValues(Opt->getOwnsValues());
1104 Opt->setOwnsValues(
false);
1106 if (Opt->getAlias()) {
1107 const Arg *Alias = Opt->getAlias();
1108 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1109 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1110 Args.getArgString(Index), Index);
1111 AliasCopy->getValues() = Alias->getValues();
1112 AliasCopy->setOwnsValues(
false);
1113 if (Alias->isClaimed())
1115 Copy->setAlias(std::move(AliasCopy));
1119bool Driver::readConfigFile(StringRef
FileName,
1120 llvm::cl::ExpansionContext &ExpCtx) {
1124 Diag(diag::err_drv_cannot_open_config_file)
1125 <<
FileName << Status.getError().message();
1128 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1129 Diag(diag::err_drv_cannot_open_config_file)
1130 <<
FileName <<
"not a regular file";
1136 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1137 Diag(diag::err_drv_cannot_read_config_file)
1144 for (
const char *Opt : NewCfgFileArgs) {
1146 if (Opt[0] ==
'$' && Opt[1])
1147 NewCfgTailArgs.push_back(Opt + 1);
1149 NewCfgHeadArgs.push_back(Opt);
1154 llvm::sys::path::native(CfgFileName);
1155 bool ContainErrors =
false;
1156 auto NewHeadOptions = std::make_unique<InputArgList>(
1160 auto NewTailOptions = std::make_unique<InputArgList>(
1167 for (Arg *A : *NewHeadOptions)
1169 for (Arg *A : *NewTailOptions)
1172 if (!CfgOptionsHead)
1173 CfgOptionsHead = std::move(NewHeadOptions);
1176 for (
auto *Opt : *NewHeadOptions)
1180 if (!CfgOptionsTail)
1181 CfgOptionsTail = std::move(NewTailOptions);
1184 for (
auto *Opt : *NewTailOptions)
1188 ConfigFiles.push_back(std::string(CfgFileName));
1192bool Driver::loadConfigFiles() {
1193 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1194 llvm::cl::tokenizeConfigFile);
1195 ExpCtx.setVFS(&
getVFS());
1199 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1202 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1203 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1208 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1210 llvm::sys::fs::expand_tilde(
1211 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1212 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1221 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1224 if (loadDefaultConfigFiles(ExpCtx))
1230 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1233 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1234 CfgFilePath.assign(CfgFileName);
1235 if (llvm::sys::path::is_relative(CfgFilePath)) {
1236 if (
getVFS().makeAbsolute(CfgFilePath)) {
1237 Diag(diag::err_drv_cannot_open_config_file)
1238 << CfgFilePath <<
"cannot get absolute path";
1242 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1244 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1245 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1246 if (!SearchDir.empty())
1247 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1252 if (readConfigFile(CfgFilePath, ExpCtx))
1263 llvm::Triple Triple, std::string Suffix) {
1265 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1269 VersionTuple OSVersion = Triple.getOSVersion();
1270 if (!OSVersion.getMinor().has_value())
1273 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1277 if (OSVersion.getMajor() != 0) {
1278 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1279 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1285 Triple.setOSName(BaseOSName);
1286 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1289bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1292 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1296 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1299 std::string RealMode = getExecutableForDriverMode(Mode);
1300 llvm::Triple Triple;
1309 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1310 PrefixTriple.isOSUnknown())
1311 Triple = PrefixTriple;
1315 llvm::Triple RealTriple =
1317 if (Triple.str().empty()) {
1318 Triple = RealTriple;
1319 assert(!Triple.str().empty());
1324 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1340 "-" + RealMode +
".cfg"))
1341 return readConfigFile(CfgFilePath, ExpCtx);
1345 if (TryModeSuffix) {
1348 return readConfigFile(CfgFilePath, ExpCtx);
1353 std::string CfgFileName = RealMode +
".cfg";
1354 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1355 if (readConfigFile(CfgFilePath, ExpCtx))
1357 }
else if (TryModeSuffix) {
1359 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1360 readConfigFile(CfgFilePath, ExpCtx))
1366 return readConfigFile(CfgFilePath, ExpCtx);
1374 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1383 if (!DriverMode.empty())
1384 setDriverMode(DriverMode);
1390 CLOptions = std::make_unique<InputArgList>(
1395 ContainsError = loadConfigFiles();
1396 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1397 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1401 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1403 if (HasConfigFileHead)
1404 for (
auto *Opt : *CLOptions)
1405 if (!Opt->getOption().matches(options::OPT_config))
1409 if (
IsCLMode() && !ContainsError) {
1411 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1413 CLModePassThroughArgList.push_back(A->getValue());
1416 if (!CLModePassThroughArgList.empty()) {
1419 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1424 for (
auto *Opt : *CLModePassThroughOptions)
1430 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1431 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1432 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1436 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1437 if (!VFS->exists(IncludeDir))
1438 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1443 bool CCCPrintPhases;
1446 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1447 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1450 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1451 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1454 Args.ClaimAllArgs(options::OPT_pipe);
1462 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1464 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1465 CCCGenericGCCName = A->getValue();
1468 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1472 if (Args.hasArg(options::OPT_fproc_stat_report))
1479 llvm::Triple
T(TargetTriple);
1480 T.setOS(llvm::Triple::Win32);
1481 T.setVendor(llvm::Triple::PC);
1482 T.setEnvironment(llvm::Triple::MSVC);
1483 T.setObjectFormat(llvm::Triple::COFF);
1484 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1485 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1486 TargetTriple =
T.str();
1489 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1490 StringRef TargetProfile = A->getValue();
1493 TargetTriple = *Triple;
1495 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1499 if (Args.hasArg(options::OPT_spirv)) {
1500 llvm::Triple
T(TargetTriple);
1501 T.setArch(llvm::Triple::spirv);
1502 T.setOS(llvm::Triple::Vulkan);
1505 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1506 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1507 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1508 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1510 auto TargetInfo = ValidTargets.find(A->getValue());
1513 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1515 Diag(diag::err_drv_invalid_value)
1516 << A->getAsString(Args) << A->getValue();
1521 TargetTriple =
T.str();
1524 Diag(diag::err_drv_dxc_missing_target_profile);
1528 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1529 TargetTriple = A->getValue();
1530 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1531 Dir =
Dir = A->getValue();
1532 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1536 if (std::optional<std::string> CompilerPathValue =
1537 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1538 StringRef CompilerPath = *CompilerPathValue;
1539 while (!CompilerPath.empty()) {
1540 std::pair<StringRef, StringRef> Split =
1541 CompilerPath.split(llvm::sys::EnvPathSeparator);
1542 PrefixDirs.push_back(std::string(Split.first));
1543 CompilerPath = Split.second;
1546 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1548 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1551 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1554 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1555 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1556 .Case(
"cwd", SaveTempsCwd)
1557 .Case(
"obj", SaveTempsObj)
1558 .Default(SaveTempsCwd);
1561 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1562 options::OPT_offload_device_only,
1563 options::OPT_offload_host_device)) {
1564 if (A->getOption().matches(options::OPT_offload_host_only))
1565 Offload = OffloadHost;
1566 else if (A->getOption().matches(options::OPT_offload_device_only))
1567 Offload = OffloadDevice;
1569 Offload = OffloadHostDevice;
1575 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1576 StringRef
Name = A->getValue();
1577 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1578 .Case(
"off", EmbedNone)
1579 .Case(
"all", EmbedBitcode)
1580 .Case(
"bitcode", EmbedBitcode)
1581 .Case(
"marker", EmbedMarker)
1584 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1587 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1591 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1592 llvm::sys::fs::remove(A->getValue());
1598 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1600 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1601 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1602 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1603 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1604 Std->containsValue(
"c++latest"));
1607 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1608 options::OPT_fmodule_header)) {
1610 ModulesModeCXX20 =
true;
1611 if (A->getOption().matches(options::OPT_fmodule_header))
1614 StringRef ArgName = A->getValue();
1615 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1620 Diags.
Report(diag::err_drv_invalid_value)
1621 << A->getAsString(Args) << ArgName;
1627 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1628 std::make_unique<InputArgList>(std::move(Args));
1631 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1639 if (!Triple.isWasm()) {
1640 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1641 StringRef TripleObjectFormat =
1642 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1643 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1644 TripleVersionName != TripleObjectFormat) {
1645 Diags.
Report(diag::err_drv_triple_version_invalid)
1647 ContainsError =
true;
1652 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1653 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1654 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1662 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1663 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1665 case llvm::Triple::arm:
1666 case llvm::Triple::armeb:
1667 case llvm::Triple::thumb:
1668 case llvm::Triple::thumbeb:
1669 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1670 Diag(diag::warn_target_unrecognized_env)
1672 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1675 case llvm::Triple::aarch64:
1676 case llvm::Triple::aarch64_be:
1677 case llvm::Triple::aarch64_32:
1678 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1679 Diag(diag::warn_target_unrecognized_env)
1681 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1698 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1699 if (HasConfigFileTail && Inputs.size()) {
1702 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1703 for (Arg *A : *CfgOptionsTail)
1704 TranslatedLinkerIns.append(A);
1705 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1714 if (TC.
getTriple().isOSBinFormatMachO())
1719 if (CCCPrintPhases) {
1730 llvm::opt::ArgStringList ASL;
1731 for (
const auto *A : Args) {
1735 while (A->getAlias())
1737 A->render(Args, ASL);
1740 for (
auto I = ASL.begin(),
E = ASL.end(); I !=
E; ++I) {
1741 if (I != ASL.begin())
1743 llvm::sys::printArg(OS, *I,
true);
1748bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1750 using namespace llvm::sys;
1751 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1752 "Only knows about .crash files on Darwin");
1757 path::home_directory(CrashDiagDir);
1758 if (CrashDiagDir.starts_with(
"/var/root"))
1760 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1768 fs::file_status FileStatus;
1769 TimePoint<> LastAccessTime;
1773 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1774 File != FileEnd && !EC;
File.increment(EC)) {
1778 if (fs::status(
File->path(), FileStatus))
1780 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1781 llvm::MemoryBuffer::getFile(
File->path());
1786 StringRef
Data = CrashFile.get()->getBuffer();
1787 if (!
Data.starts_with(
"Process:"))
1790 size_t ParentProcPos =
Data.find(
"Parent Process:");
1791 if (ParentProcPos == StringRef::npos)
1793 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1794 if (LineEnd == StringRef::npos)
1796 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1797 int OpenBracket = -1, CloseBracket = -1;
1798 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1799 if (ParentProcess[i] ==
'[')
1801 if (ParentProcess[i] ==
']')
1807 if (OpenBracket < 0 || CloseBracket < 0 ||
1808 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1809 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1819 const auto FileAccessTime = FileStatus.getLastModificationTime();
1820 if (FileAccessTime > LastAccessTime) {
1821 CrashFilePath.assign(
File->path());
1822 LastAccessTime = FileAccessTime;
1827 if (!CrashFilePath.empty()) {
1828 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1838 "\n********************\n\n"
1839 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1840 "Preprocessed source(s) and associated run script(s) are located at:";
1848 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1852 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1853 Level = llvm::StringSwitch<unsigned>(A->getValue())
1855 .Case(
"compiler", 1)
1867 ArgStringList SavedTemps;
1869 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1870 if (!IsLLD || Level < 2)
1877 SavedTemps = std::move(
C.getTempFiles());
1878 assert(!
C.getTempFiles().size());
1895 C.initCompilationForDiagnostics();
1901 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1902 StringRef ReproduceOption =
1903 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1906 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1910 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1912 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1913 Diag(clang::diag::note_drv_command_failed_diag_msg)
1914 <<
"\n\n********************";
1916 Report->TemporaryFiles.push_back(TmpName);
1924 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1925 bool IgnoreInput =
false;
1931 }
else if (!strcmp(it->second->getValue(),
"-")) {
1932 Diag(clang::diag::note_drv_command_failed_diag_msg)
1933 <<
"Error generating preprocessed source(s) - "
1934 "ignoring input from stdin.";
1939 it = Inputs.erase(it);
1946 if (Inputs.empty()) {
1947 Diag(clang::diag::note_drv_command_failed_diag_msg)
1948 <<
"Error generating preprocessed source(s) - "
1949 "no preprocessable inputs.";
1955 llvm::StringSet<> ArchNames;
1956 for (
const Arg *A :
C.getArgs()) {
1957 if (A->getOption().matches(options::OPT_arch)) {
1958 StringRef ArchName = A->getValue();
1959 ArchNames.insert(ArchName);
1962 if (ArchNames.size() > 1) {
1963 Diag(clang::diag::note_drv_command_failed_diag_msg)
1964 <<
"Error generating preprocessed source(s) - cannot generate "
1965 "preprocessed source with multiple -arch options.";
1971 const ToolChain &TC =
C.getDefaultToolChain();
1972 if (TC.
getTriple().isOSBinFormatMachO())
1981 Diag(clang::diag::note_drv_command_failed_diag_msg)
1982 <<
"Error generating preprocessed source(s).";
1988 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1991 if (!FailingCommands.empty()) {
1992 Diag(clang::diag::note_drv_command_failed_diag_msg)
1993 <<
"Error generating preprocessed source(s).";
1997 const ArgStringList &TempFiles =
C.getTempFiles();
1998 if (TempFiles.empty()) {
1999 Diag(clang::diag::note_drv_command_failed_diag_msg)
2000 <<
"Error generating preprocessed source(s).";
2008 for (
const char *TempFile : TempFiles) {
2009 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2011 Report->TemporaryFiles.push_back(TempFile);
2012 if (ReproCrashFilename.empty()) {
2013 ReproCrashFilename = TempFile;
2014 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2016 if (StringRef(TempFile).ends_with(
".cache")) {
2019 VFS = llvm::sys::path::filename(TempFile);
2020 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2024 for (
const char *TempFile : SavedTemps)
2025 C.addTempFile(TempFile);
2031 llvm::sys::path::replace_extension(Script,
"sh");
2033 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2034 llvm::sys::fs::FA_Write,
2035 llvm::sys::fs::OF_Text);
2037 Diag(clang::diag::note_drv_command_failed_diag_msg)
2038 <<
"Error generating run script: " << Script <<
" " << EC.message();
2041 <<
"# Driver args: ";
2043 ScriptOS <<
"# Original command: ";
2044 Cmd.Print(ScriptOS,
"\n",
true);
2045 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
2046 if (!AdditionalInformation.empty())
2047 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2050 Report->TemporaryFiles.push_back(std::string(Script));
2051 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2055 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2057 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2058 Diag(clang::diag::note_drv_command_failed_diag_msg)
2059 << ReproCrashFilename.str();
2061 llvm::sys::path::append(CrashDiagDir,
Name);
2062 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2063 Diag(clang::diag::note_drv_command_failed_diag_msg)
2064 <<
"Crash backtrace is located in";
2065 Diag(clang::diag::note_drv_command_failed_diag_msg)
2066 << CrashDiagDir.str();
2067 Diag(clang::diag::note_drv_command_failed_diag_msg)
2068 <<
"(choose the .crash file that corresponds to your crash)";
2072 Diag(clang::diag::note_drv_command_failed_diag_msg)
2073 <<
"\n\n********************";
2081 if (
Cmd.getResponseFileSupport().ResponseKind ==
2083 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
2084 Cmd.getArguments()))
2088 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
2094 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2095 if (
C.getArgs().hasArg(options::OPT_v))
2096 C.getJobs().Print(llvm::errs(),
"\n",
true);
2098 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2108 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2109 C.getJobs().Print(llvm::errs(),
"\n",
true);
2118 for (
auto &Job :
C.getJobs())
2119 setUpResponseFiles(
C, Job);
2121 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2124 if (FailingCommands.empty())
2130 for (
const auto &CmdPair : FailingCommands) {
2131 int CommandRes = CmdPair.first;
2132 const Command *FailingCommand = CmdPair.second;
2137 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2141 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2146 if (CommandRes == EX_IOERR) {
2163 Diag(clang::diag::err_drv_command_signalled)
2166 Diag(clang::diag::err_drv_command_failed)
2174 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2176 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2190 const ToolChain &TC =
C.getDefaultToolChain();
2194 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2197 OS <<
"Thread model: " << A->getValue();
2203 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2208 if (!llvm::cl::getCompilerBuildConfig().empty())
2209 llvm::cl::printBuildConfig(OS);
2212 for (
auto ConfigFile : ConfigFiles)
2213 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2226 if (PassedFlags ==
"")
2230 std::vector<std::string> SuggestedCompletions;
2231 std::vector<std::string> Flags;
2243 const bool HasSpace = PassedFlags.ends_with(
",");
2247 StringRef TargetFlags = PassedFlags;
2248 while (TargetFlags !=
"") {
2250 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2251 Flags.push_back(std::string(CurFlag));
2256 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2259 const llvm::opt::OptTable &Opts =
getOpts();
2261 Cur = Flags.at(Flags.size() - 1);
2263 if (Flags.size() >= 2) {
2264 Prev = Flags.at(Flags.size() - 2);
2265 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2268 if (SuggestedCompletions.empty())
2269 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2276 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2277 llvm::outs() <<
'\n';
2283 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2287 SuggestedCompletions = Opts.findByPrefix(
2288 Cur, VisibilityMask,
2295 if (S.starts_with(Cur))
2296 SuggestedCompletions.push_back(std::string(S));
2303 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2304 if (
int X = A.compare_insensitive(B))
2306 return A.compare(B) > 0;
2309 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2316 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2317 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2321 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2324 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2328 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2333 if (
C.getArgs().hasArg(options::OPT_help) ||
2334 C.getArgs().hasArg(options::OPT__help_hidden)) {
2335 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2339 if (
C.getArgs().hasArg(options::OPT__version)) {
2345 if (
C.getArgs().hasArg(options::OPT_v) ||
2346 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2347 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2348 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2349 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2351 SuppressMissingInputWarning =
true;
2354 if (
C.getArgs().hasArg(options::OPT_v)) {
2356 llvm::errs() <<
"System configuration file directory: "
2359 llvm::errs() <<
"User configuration file directory: "
2363 const ToolChain &TC =
C.getDefaultToolChain();
2365 if (
C.getArgs().hasArg(options::OPT_v))
2368 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2373 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2374 llvm::outs() <<
"programs: =";
2375 bool separator =
false;
2379 llvm::outs() << llvm::sys::EnvPathSeparator;
2380 llvm::outs() <<
Path;
2385 llvm::outs() << llvm::sys::EnvPathSeparator;
2386 llvm::outs() <<
Path;
2389 llvm::outs() <<
"\n";
2392 StringRef sysroot =
C.getSysRoot();
2396 llvm::outs() << llvm::sys::EnvPathSeparator;
2399 llvm::outs() << sysroot <<
Path.substr(1);
2401 llvm::outs() <<
Path;
2403 llvm::outs() <<
"\n";
2407 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2413 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2414 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2415 llvm::outs() << *RuntimePath <<
'\n';
2421 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2423 for (std::size_t I = 0; I != Flags.size(); I += 2)
2424 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2430 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2431 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2435 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2436 StringRef ProgName = A->getValue();
2439 if (! ProgName.empty())
2442 llvm::outs() <<
"\n";
2446 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2447 StringRef PassedFlags = A->getValue();
2452 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2466 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2469 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2475 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2482 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2485 std::set<llvm::StringRef> SortedFlags;
2486 for (
const auto &FlagEntry : ExpandedFlags)
2487 SortedFlags.insert(FlagEntry.getKey());
2488 for (
auto Flag : SortedFlags)
2489 llvm::outs() << Flag <<
'\n';
2493 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2496 llvm::outs() <<
".\n";
2499 assert(Suffix.front() ==
'/');
2500 llvm::outs() << Suffix.substr(1) <<
"\n";
2506 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2511 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2513 llvm::outs() << Triple.getTriple() <<
"\n";
2517 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2518 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2535 std::map<Action *, unsigned> &Ids,
2537 if (
auto It = Ids.find(A); It != Ids.end())
2541 llvm::raw_string_ostream os(str);
2543 auto getSibIndent = [](
int K) -> Twine {
2547 Twine SibIndent = Indent + getSibIndent(Kind);
2551 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2553 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2554 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2555 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2556 bool IsFirst =
true;
2557 OA->doOnEachDependence(
2559 assert(TC &&
"Unknown host toolchain");
2571 os <<
":" << BoundArch;
2574 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2582 const char *Prefix =
"{";
2583 for (
Action *PreRequisite : *AL) {
2584 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2595 std::string offload_str;
2596 llvm::raw_string_ostream offload_os(offload_str);
2597 if (!isa<OffloadAction>(A)) {
2600 offload_os <<
", (" << S;
2607 auto getSelfIndent = [](
int K) -> Twine {
2611 unsigned Id = Ids.size();
2613 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2622 std::map<Action *, unsigned> Ids;
2623 for (
Action *A :
C.getActions())
2630 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2631 isa<AssembleJobAction>(A))
2639 DerivedArgList &Args =
C.getArgs();
2641 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2644 llvm::StringSet<> ArchNames;
2646 for (Arg *A : Args) {
2647 if (A->getOption().matches(options::OPT_arch)) {
2650 llvm::Triple::ArchType Arch =
2652 if (Arch == llvm::Triple::UnknownArch) {
2653 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2658 if (ArchNames.insert(A->getValue()).second)
2659 Archs.push_back(A->getValue());
2673 for (
Action* Act : SingleActions) {
2681 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2685 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2690 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2691 Actions.append(Inputs.begin(), Inputs.end());
2693 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2696 Arg *A = Args.getLastArg(options::OPT_g_Group);
2697 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2698 !A->getOption().matches(options::OPT_gstabs);
2706 if (Act->getType() == types::TY_Image) {
2708 Inputs.push_back(Actions.back());
2715 if (Args.hasArg(options::OPT_verify_debug_info)) {
2716 Action* LastAction = Actions.back();
2719 LastAction, types::TY_Nothing));
2738 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2739 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2751 std::string Nearest;
2752 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2753 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2754 <<
Value << Nearest;
2793 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2796 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2804 return types::TY_CXXUHeader;
2806 return types::TY_CXXSHeader;
2810 llvm_unreachable(
"should not be called in this case");
2812 return types::TY_CXXHUHeader;
2818 const llvm::opt::OptTable &Opts =
getOpts();
2822 types::ID InputType = types::TY_Nothing;
2823 Arg *InputTypeArg =
nullptr;
2826 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2827 options::OPT__SLASH_TP)) {
2828 InputTypeArg = TCTP;
2829 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2834 bool ShowNote =
false;
2836 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2838 Diag(clang::diag::warn_drv_overriding_option)
2839 <<
Previous->getSpelling() << A->getSpelling();
2845 Diag(clang::diag::note_drv_t_option_is_global);
2850 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2851 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2852 if (LastXArg && LastInputArg &&
2853 LastInputArg->getIndex() < LastXArg->getIndex())
2854 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2857 for (Arg *A : Args) {
2858 if (A->getOption().
getKind() == Option::InputClass) {
2859 const char *
Value = A->getValue();
2863 if (InputType == types::TY_Nothing) {
2866 InputTypeArg->claim();
2869 if (memcmp(
Value,
"-", 2) == 0) {
2871 Ty = types::TY_Fortran;
2873 Ty = types::TY_HLSL;
2882 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2883 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2884 : clang::diag::err_drv_unknown_stdin_type);
2893 if (
const char *Ext = strrchr(
Value,
'.'))
2902 Ty = types::TY_Object;
2913 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2914 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2915 << getTypeName(OldTy) << getTypeName(Ty);
2920 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2921 Ty == types::TY_Object)
2922 Ty = types::TY_LLVM_BC;
2930 if (Ty != types::TY_Object) {
2931 if (Args.hasArg(options::OPT_ObjC))
2932 Ty = types::TY_ObjC;
2933 else if (Args.hasArg(options::OPT_ObjCXX))
2934 Ty = types::TY_ObjCXX;
2941 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
2945 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2946 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2949 const char *Ext = strrchr(
Value,
'.');
2951 Ty = types::TY_Object;
2955 InputTypeArg->claim();
2959 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
2960 Args.hasArgNoClaim(options::OPT_hipstdpar))
2964 Inputs.push_back(std::make_pair(Ty, A));
2966 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2967 StringRef
Value = A->getValue();
2970 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2971 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2974 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2975 StringRef
Value = A->getValue();
2978 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2979 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2985 Inputs.push_back(std::make_pair(types::TY_Object, A));
2987 }
else if (A->getOption().matches(options::OPT_x)) {
2996 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2997 InputType = types::TY_Object;
3004 }
else if (A->getOption().getID() == options::OPT_U) {
3005 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3006 StringRef Val = A->getValue(0);
3007 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3009 Diag(diag::warn_slash_u_filename) << Val;
3010 Diag(diag::note_use_dashdash);
3014 if (
CCCIsCPP() && Inputs.empty()) {
3018 Inputs.push_back(std::make_pair(types::TY_C, A));
3025class OffloadingActionBuilder final {
3027 bool IsValid =
false;
3033 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3036 std::map<Action *, const Arg *> HostActionToInputArgMap;
3039 class DeviceActionBuilder {
3043 enum ActionBuilderReturnCode {
3062 DerivedArgList &Args;
3071 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3074 :
C(
C), Args(Args), Inputs(Inputs),
3075 AssociatedOffloadKind(AssociatedOffloadKind) {}
3076 virtual ~DeviceActionBuilder() {}
3081 virtual ActionBuilderReturnCode
3085 return ABRT_Inactive;
3090 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
3091 return ABRT_Inactive;
3095 virtual void appendTopLevelActions(
ActionList &AL) {}
3098 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3111 virtual bool canUseBundlerUnbundler()
const {
return false; }
3115 bool isValid() {
return !ToolChains.empty(); }
3119 return AssociatedOffloadKind;
3125 class CudaActionBuilderBase :
public DeviceActionBuilder {
3129 bool CompileHostOnly =
false;
3130 bool CompileDeviceOnly =
false;
3132 bool EmitAsm =
false;
3142 TargetID(
const char *
ID) :
ID(
ID) {}
3143 operator const char *() {
return ID; }
3144 operator StringRef() {
return StringRef(
ID); }
3153 Action *CudaFatBinary =
nullptr;
3156 bool IsActive =
false;
3159 bool Relocatable =
false;
3162 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3166 enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
3167 UseCUIDKind UseCUID = CUID_Hash;
3170 StringRef FixedCUID;
3173 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
3176 : DeviceActionBuilder(
C, Args, Inputs, OFKind) {
3178 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3179 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3180 options::OPT_fno_gpu_rdc,
false);
3183 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3190 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3191 assert(!GpuArchList.empty() &&
3192 "We should have at least one GPU architecture.");
3196 if (!(IA->getType() == types::TY_CUDA ||
3197 IA->getType() == types::TY_HIP ||
3198 IA->getType() == types::TY_PP_HIP)) {
3201 return ABRT_Inactive;
3207 std::string CUID = FixedCUID.str();
3209 if (UseCUID == CUID_Random)
3210 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
3212 else if (UseCUID == CUID_Hash) {
3214 llvm::MD5::MD5Result Hash;
3216 llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
3218 Hasher.update(RealPath);
3219 for (
auto *A : Args) {
3220 if (A->getOption().matches(options::OPT_INPUT))
3222 Hasher.update(A->getAsString(Args));
3225 CUID = llvm::utohexstr(Hash.low(),
true);
3230 if (CompileHostOnly)
3231 return ABRT_Success;
3234 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3235 : types::TY_CUDA_DEVICE;
3236 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3237 CudaDeviceActions.push_back(
3238 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3241 return ABRT_Success;
3245 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3249 if (UA->getType() == types::TY_Object && !Relocatable)
3250 return ABRT_Inactive;
3252 CudaDeviceActions.clear();
3253 auto *IA = cast<InputAction>(UA->getInputs().back());
3254 std::string
FileName = IA->getInputArg().getAsString(Args);
3260 const StringRef LibFileExt =
".lib";
3261 if (IA->getType() == types::TY_Object &&
3262 (!llvm::sys::path::has_extension(
FileName) ||
3264 llvm::sys::path::extension(
FileName).drop_front()) !=
3266 llvm::sys::path::extension(
FileName) == LibFileExt))
3267 return ABRT_Inactive;
3269 for (
auto Arch : GpuArchList) {
3270 CudaDeviceActions.push_back(UA);
3271 UA->registerDependentActionInfo(ToolChains[0], Arch,
3272 AssociatedOffloadKind);
3275 return ABRT_Success;
3278 return IsActive ? ABRT_Success : ABRT_Inactive;
3281 void appendTopLevelActions(
ActionList &AL)
override {
3283 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3285 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3290 if (CudaFatBinary) {
3291 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3292 CudaDeviceActions.clear();
3293 CudaFatBinary =
nullptr;
3297 if (CudaDeviceActions.empty())
3303 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3304 "Expecting one action per GPU architecture.");
3305 assert(ToolChains.size() == 1 &&
3306 "Expecting to have a single CUDA toolchain.");
3307 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I)
3308 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3310 CudaDeviceActions.clear();
3315 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3317 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3335 assert(HostTC &&
"No toolchain for host compilation.");
3337 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3341 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3346 ToolChains.push_back(
3351 CompileHostOnly =
C.getDriver().offloadHostOnly();
3352 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3353 EmitAsm = Args.getLastArg(options::OPT_S);
3354 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3355 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3356 StringRef UseCUIDStr = A->getValue();
3357 UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3358 .Case(
"hash", CUID_Hash)
3359 .Case(
"random", CUID_Random)
3360 .Case(
"none", CUID_None)
3361 .Default(CUID_Invalid);
3362 if (UseCUID == CUID_Invalid) {
3363 C.getDriver().Diag(diag::err_drv_invalid_value)
3364 << A->getAsString(Args) << UseCUIDStr;
3365 C.setContainsError();
3371 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3372 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3373 options::OPT_no_offload_arch_EQ)) {
3374 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3379 std::set<StringRef> GpuArchs;
3381 for (Arg *A : Args) {
3382 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3383 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3387 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3388 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3391 }
else if (ArchStr ==
"native") {
3392 const ToolChain &TC = *ToolChains.front();
3393 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3396 << llvm::Triple::getArchTypeName(TC.
getArch())
3397 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3401 for (
auto GPU : *GPUsOrErr) {
3402 GpuArchs.insert(Args.MakeArgString(GPU));
3405 ArchStr = getCanonicalOffloadArch(ArchStr);
3406 if (ArchStr.empty()) {
3408 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3409 GpuArchs.insert(ArchStr);
3410 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3411 GpuArchs.erase(ArchStr);
3413 llvm_unreachable(
"Unexpected option.");
3419 if (ConflictingArchs) {
3420 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3421 << ConflictingArchs->first << ConflictingArchs->second;
3422 C.setContainsError();
3427 for (
auto Arch : GpuArchs)
3428 GpuArchList.push_back(Arch.data());
3433 if (GpuArchList.empty()) {
3434 if (ToolChains.front()->getTriple().isSPIRV()) {
3435 if (ToolChains.front()->getTriple().getVendor() == llvm::Triple::AMD)
3436 GpuArchList.push_back(OffloadArch::AMDGCNSPIRV);
3438 GpuArchList.push_back(OffloadArch::Generic);
3440 GpuArchList.push_back(DefaultOffloadArch);
3450 class CudaActionBuilder final :
public CudaActionBuilderBase {
3452 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3454 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3455 DefaultOffloadArch = OffloadArch::CudaDefault;
3458 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3461 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3467 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3469 const std::set<StringRef> &GpuArchs)
override {
3470 return std::nullopt;
3473 ActionBuilderReturnCode
3476 PhasesTy &Phases)
override {
3478 return ABRT_Inactive;
3482 if (CudaDeviceActions.empty())
3483 return ABRT_Success;
3485 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3486 "Expecting one action per GPU architecture.");
3487 assert(!CompileHostOnly &&
3488 "Not expecting CUDA actions in host-only compilation.");
3498 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3501 for (
auto Ph : Phases) {
3506 if (Ph > FinalPhase)
3509 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3519 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3523 Action *AssembleAction = CudaDeviceActions[I];
3524 assert(AssembleAction->
getType() == types::TY_Object);
3525 assert(AssembleAction->
getInputs().size() == 1);
3533 DeviceActions.push_back(
3539 if (!DeviceActions.empty()) {
3541 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3543 if (!CompileDeviceOnly) {
3544 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3548 CudaFatBinary =
nullptr;
3553 CudaDeviceActions.clear();
3557 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3562 return ABRT_Success;
3566 "instructions should only occur "
3567 "before the backend phase!");
3570 for (
Action *&A : CudaDeviceActions)
3571 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3573 return ABRT_Success;
3578 class HIPActionBuilder final :
public CudaActionBuilderBase {
3586 std::optional<bool> BundleOutput;
3587 std::optional<bool> EmitReloc;
3592 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3594 DefaultOffloadArch = OffloadArch::HIPDefault;
3596 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3597 options::OPT_fno_hip_emit_relocatable)) {
3598 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3599 options::OPT_fno_hip_emit_relocatable,
false);
3603 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3604 <<
"-fhip-emit-relocatable"
3608 if (!CompileDeviceOnly) {
3609 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3610 <<
"-fhip-emit-relocatable"
3611 <<
"--cuda-device-only";
3616 if (Args.hasArg(options::OPT_gpu_bundle_output,
3617 options::OPT_no_gpu_bundle_output))
3618 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3619 options::OPT_no_gpu_bundle_output,
true) &&
3620 (!EmitReloc || !*EmitReloc);
3623 bool canUseBundlerUnbundler()
const override {
return true; }
3625 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3626 llvm::StringMap<bool> Features;
3630 (IdStr ==
"amdgcnspirv")
3631 ? llvm::Triple(
"spirv64-amd-amdhsa")
3635 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3636 C.setContainsError();
3640 return Args.MakeArgStringRef(CanId);
3643 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3645 const std::set<StringRef> &GpuArchs)
override {
3649 ActionBuilderReturnCode
3652 PhasesTy &Phases)
override {
3654 return ABRT_Inactive;
3660 if (CudaDeviceActions.empty())
3661 return ABRT_Success;
3664 CudaDeviceActions.size() == GpuArchList.size()) &&
3665 "Expecting one action per GPU architecture.");
3666 assert(!CompileHostOnly &&
3667 "Not expecting HIP actions in host-only compilation.");
3669 bool ShouldLink = !EmitReloc || !*EmitReloc;
3672 !EmitAsm && ShouldLink) {
3678 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3679 if (
C.getDriver().isUsingOffloadLTO()) {
3683 AL.push_back(CudaDeviceActions[I]);
3686 CudaDeviceActions[I] =
3693 if (ToolChains.front()->getTriple().isSPIRV()) {
3696 types::ID Output = Args.hasArg(options::OPT_S)
3698 : types::TY_LLVM_BC;
3704 AssociatedOffloadKind);
3705 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3707 AssociatedOffloadKind);
3708 AL.push_back(AssembleAction);
3711 CudaDeviceActions[I] =
3722 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3723 AssociatedOffloadKind);
3725 DDep, CudaDeviceActions[I]->getType());
3728 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3731 types::TY_HIP_FATBIN);
3733 if (!CompileDeviceOnly) {
3734 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3735 AssociatedOffloadKind);
3738 CudaFatBinary =
nullptr;
3743 CudaDeviceActions.clear();
3746 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3749 return ABRT_Success;
3755 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3756 auto LI = DeviceLinkerInputs.begin();
3757 for (
auto *A : CudaDeviceActions) {
3764 CudaDeviceActions.clear();
3765 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3769 for (
Action *&A : CudaDeviceActions)
3770 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3771 AssociatedOffloadKind);
3773 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3775 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3777 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3778 AssociatedOffloadKind);
3780 DDep, CudaDeviceActions[I]->getType());
3784 CudaDeviceActions.clear();
3787 return (CompileDeviceOnly &&
3788 (CurPhase == FinalPhase ||
3794 void appendLinkDeviceActions(
ActionList &AL)
override {
3795 if (DeviceLinkerInputs.size() == 0)
3798 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3799 "Linker inputs and GPU arch list sizes do not match.");
3805 for (
auto &LI : DeviceLinkerInputs) {
3807 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3811 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3815 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3816 GpuArchList[I], AssociatedOffloadKind);
3818 DeviceLinkDeps, DeviceLinkAction->getType()));
3821 DeviceLinkerInputs.clear();
3824 if (Args.hasArg(options::OPT_emit_llvm)) {
3833 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3836 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3837 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3838 AssociatedOffloadKind);
3841 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3847 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3863 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3871 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3874 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3882 unsigned ValidBuilders = 0u;
3883 unsigned ValidBuildersSupportingBundling = 0u;
3884 for (
auto *SB : SpecializedBuilders) {
3885 IsValid = IsValid && !SB->initialize();
3888 if (SB->isValid()) {
3890 if (SB->canUseBundlerUnbundler())
3891 ++ValidBuildersSupportingBundling;
3895 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3898 ~OffloadingActionBuilder() {
3899 for (
auto *SB : SpecializedBuilders)
3904 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3905 assert(HostAction &&
"Invalid host action");
3906 assert(InputArg &&
"Invalid input argument");
3907 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3908 assert(
Loc->second == InputArg &&
3909 "host action mapped to multiple input arguments");
3918 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3920 DeviceActionBuilder::PhasesTy &Phases) {
3924 if (SpecializedBuilders.empty())
3927 assert(HostAction &&
"Invalid host action!");
3928 recordHostAction(HostAction, InputArg);
3933 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3934 unsigned InactiveBuilders = 0u;
3935 unsigned IgnoringBuilders = 0u;
3936 for (
auto *SB : SpecializedBuilders) {
3937 if (!SB->isValid()) {
3942 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3947 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3952 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3953 OffloadKind |= SB->getAssociatedOffloadKind();
3958 if (IgnoringBuilders &&
3959 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3976 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3977 const Arg *InputArg) {
3981 recordHostAction(HostAction, InputArg);
3989 if (CanUseBundler && isa<InputAction>(HostAction) &&
3990 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3992 HostAction->
getType() == types::TY_PP_HIP)) {
3993 auto UnbundlingHostAction =
3998 HostAction = UnbundlingHostAction;
3999 recordHostAction(HostAction, InputArg);
4002 assert(HostAction &&
"Invalid host action!");
4005 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4006 for (
auto *SB : SpecializedBuilders) {
4010 auto RetCode = SB->addDeviceDependences(HostAction);
4014 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4015 "Host dependence not expected to be ignored.!");
4019 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4020 OffloadKind |= SB->getAssociatedOffloadKind();
4025 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4035 const Arg *InputArg) {
4037 recordHostAction(HostAction, InputArg);
4041 for (
auto *SB : SpecializedBuilders) {
4044 SB->appendTopLevelActions(OffloadAL);
4051 if (CanUseBundler && HostAction &&
4052 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4054 OffloadAL.push_back(HostAction);
4058 assert(HostAction == AL.back() &&
"Host action not in the list??");
4060 recordHostAction(HostAction, InputArg);
4061 AL.back() = HostAction;
4063 AL.append(OffloadAL.begin(), OffloadAL.end());
4073 void appendDeviceLinkActions(
ActionList &AL) {
4074 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4077 SB->appendLinkDeviceActions(AL);
4081 Action *makeHostLinkAction() {
4084 appendDeviceLinkActions(DeviceAL);
4085 if (DeviceAL.empty())
4090 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4093 HA = SB->appendLinkHostActions(DeviceAL);
4110 for (
auto *SB : SpecializedBuilders) {
4114 SB->appendLinkDependences(DDeps);
4118 unsigned ActiveOffloadKinds = 0u;
4119 for (
auto &I : InputArgToOffloadKindMap)
4120 ActiveOffloadKinds |= I.second;
4132 for (
auto *A : HostAction->
inputs()) {
4133 auto ArgLoc = HostActionToInputArgMap.find(A);
4134 if (ArgLoc == HostActionToInputArgMap.end())
4136 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4137 if (OFKLoc == InputArgToOffloadKindMap.end())
4149 nullptr, ActiveOffloadKinds);
4155void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4156 const InputList &Inputs,
4160 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4161 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4162 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4163 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4164 Args.eraseArg(options::OPT__SLASH_Yc);
4165 Args.eraseArg(options::OPT__SLASH_Yu);
4166 YcArg = YuArg =
nullptr;
4168 if (YcArg && Inputs.size() > 1) {
4169 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4170 Args.eraseArg(options::OPT__SLASH_Yc);
4178 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4179 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4180 Args.AddFlagArg(
nullptr,
4181 getOpts().getOption(options::OPT_frtlib_add_rpath));
4184 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4185 Diag(clang::diag::err_drv_emit_llvm_link);
4186 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4188 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4189 .starts_with_insensitive(
"lld"))
4190 Diag(clang::diag::err_drv_lto_without_lld);
4196 if (!Args.hasArg(options::OPT_dumpdir)) {
4197 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4198 Arg *Arg = Args.MakeSeparateArg(
4199 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4201 (FinalOutput ? FinalOutput->getValue()
4213 Args.eraseArg(options::OPT__SLASH_Fp);
4214 Args.eraseArg(options::OPT__SLASH_Yc);
4215 Args.eraseArg(options::OPT__SLASH_Yu);
4216 YcArg = YuArg =
nullptr;
4219 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4220 for (
auto &I : Inputs) {
4222 const Arg *InputArg = I.second;
4227 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4231 if (InitialPhase > FinalPhase) {
4232 if (InputArg->isClaimed())
4239 if (Args.hasArg(options::OPT_Qunused_arguments))
4245 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4246 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4250 (Args.getLastArg(options::OPT__SLASH_EP,
4251 options::OPT__SLASH_P) ||
4252 Args.getLastArg(options::OPT_E) ||
4253 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4255 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4256 << InputArg->getAsString(Args) << !!FinalPhaseArg
4257 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4259 Diag(clang::diag::warn_drv_input_file_unused)
4260 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4262 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4275 Actions.push_back(ClangClPch);
4287 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4288 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4294 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4296 if (!SuppressMissingInputWarning && Inputs.empty()) {
4297 Diag(clang::diag::err_drv_no_input_files);
4302 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4303 StringRef
V = A->getValue();
4304 if (Inputs.size() > 1 && !
V.empty() &&
4305 !llvm::sys::path::is_separator(
V.back())) {
4307 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4308 << A->getSpelling() <<
V;
4309 Args.eraseArg(options::OPT__SLASH_Fo);
4314 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4315 StringRef
V = A->getValue();
4316 if (Inputs.size() > 1 && !
V.empty() &&
4317 !llvm::sys::path::is_separator(
V.back())) {
4319 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4320 << A->getSpelling() <<
V;
4321 Args.eraseArg(options::OPT__SLASH_Fa);
4326 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4327 if (A->getValue()[0] ==
'\0') {
4329 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4330 Args.eraseArg(options::OPT__SLASH_o);
4334 handleArguments(
C, Args, Inputs, Actions);
4336 bool UseNewOffloadingDriver =
4339 Args.hasFlag(options::OPT_foffload_via_llvm,
4340 options::OPT_fno_offload_via_llvm,
false) ||
4341 Args.hasFlag(options::OPT_offload_new_driver,
4342 options::OPT_no_offload_new_driver,
4346 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4347 !UseNewOffloadingDriver
4348 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4356 for (
auto &I : Inputs) {
4358 const Arg *InputArg = I.second;
4371 if (!UseNewOffloadingDriver)
4372 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4378 if (!UseNewOffloadingDriver)
4379 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4380 Current, InputArg, Phase, PL.back(), FullPL);
4386 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4389 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4390 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4392 LinkerInputs.push_back(Current);
4402 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4403 MergerInputs.push_back(Current);
4421 if (NewCurrent == Current)
4424 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4427 Current = NewCurrent;
4431 if (UseNewOffloadingDriver)
4435 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4439 if (Current->getType() == types::TY_Nothing)
4445 Actions.push_back(Current);
4448 if (!UseNewOffloadingDriver)
4449 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4451 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4457 if (LinkerInputs.empty()) {
4460 if (!UseNewOffloadingDriver)
4461 OffloadBuilder->appendDeviceLinkActions(Actions);
4464 if (!LinkerInputs.empty()) {
4465 if (!UseNewOffloadingDriver)
4466 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4467 LinkerInputs.push_back(Wrapper);
4472 }
else if (UseNewOffloadingDriver ||
4473 Args.hasArg(options::OPT_offload_link)) {
4480 if (!UseNewOffloadingDriver)
4481 LA = OffloadBuilder->processHostLinkAction(LA);
4482 Actions.push_back(LA);
4486 if (!MergerInputs.empty())
4490 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4497 for (
auto &I : Inputs) {
4499 const Arg *InputArg = I.second;
4504 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4505 InputType == types::TY_Asm)
4510 for (
auto Phase : PhaseList) {
4514 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4519 if (InputType == types::TY_Object)
4526 assert(Phase == PhaseList.back() &&
4527 "merging must be final compilation step.");
4528 MergerInputs.push_back(Current);
4537 Actions.push_back(Current);
4541 if (!MergerInputs.empty())
4546 for (
auto Opt : {options::OPT_print_supported_cpus,
4547 options::OPT_print_supported_extensions,
4548 options::OPT_print_enabled_extensions}) {
4555 if (Arg *A = Args.getLastArg(Opt)) {
4556 if (Opt == options::OPT_print_supported_extensions &&
4557 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4558 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4559 !
C.getDefaultToolChain().getTriple().isARM()) {
4560 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4561 <<
"--print-supported-extensions";
4564 if (Opt == options::OPT_print_enabled_extensions &&
4565 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4566 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4567 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4568 <<
"--print-enabled-extensions";
4575 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4578 for (
auto &I : Inputs)
4584 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4588 if (TC.requiresValidation(Args)) {
4589 Action *LastAction = Actions.back();
4591 LastAction, types::TY_DX_CONTAINER));
4596 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4602 const llvm::opt::DerivedArgList &Args,
4604 const llvm::Triple &Triple,
4605 bool SuppressError =
false) {
4610 if (!SuppressError && Triple.isNVPTX() &&
4612 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4613 <<
"CUDA" << ArchStr;
4615 }
else if (!SuppressError && Triple.isAMDGPU() &&
4617 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4618 <<
"HIP" << ArchStr;
4626 llvm::StringMap<bool> Features;
4632 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4633 C.setContainsError();
4645static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4647 llvm::Triple Triple) {
4648 if (!Triple.isAMDGPU())
4649 return std::nullopt;
4651 std::set<StringRef> ArchSet;
4652 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4656llvm::DenseSet<StringRef>
4659 bool SuppressError)
const {
4661 TC = &
C.getDefaultToolChain();
4664 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4665 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4666 options::OPT_no_offload_arch_EQ)) {
4667 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4669 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4671 :
"--no-offload-arch");
4674 if (KnownArchs.contains(TC))
4675 return KnownArchs.lookup(TC);
4677 llvm::DenseSet<StringRef> Archs;
4678 for (
auto *Arg : Args) {
4680 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4681 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4684 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4685 unsigned Prev = Index;
4686 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4687 if (!ExtractedArg || Index > Prev + 1) {
4688 TC->
getDriver().
Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
4689 << Arg->getAsString(Args);
4692 Arg = ExtractedArg.get();
4697 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4698 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4699 if (Arch ==
"native" || Arch.empty()) {
4703 llvm::consumeError(GPUsOrErr.takeError());
4706 << llvm::Triple::getArchTypeName(TC->
getArch())
4707 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4711 for (
auto ArchStr : *GPUsOrErr) {
4718 C, Args, Arch, TC->
getTriple(), SuppressError);
4719 if (ArchStr.empty())
4721 Archs.insert(ArchStr);
4724 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4725 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4726 if (Arch ==
"all") {
4730 C, Args, Arch, TC->
getTriple(), SuppressError);
4731 if (ArchStr.empty())
4733 Archs.erase(ArchStr);
4739 if (
auto ConflictingArchs =
4741 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4742 << ConflictingArchs->first << ConflictingArchs->second;
4743 C.setContainsError();
4750 if (Archs.empty()) {
4756 Archs.insert(StringRef());
4758 Archs.insert(StringRef());
4760 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4761 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4768 llvm::opt::DerivedArgList &Args,
4770 Action *HostAction)
const {
4775 !(isa<CompileJobAction>(HostAction) ||
4789 auto TCRange =
C.getOffloadToolChains(Kind);
4790 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4791 ToolChains.push_back(TI->second);
4793 if (ToolChains.empty())
4797 const Arg *InputArg = Input.second;
4806 for (
const ToolChain *TC : ToolChains) {
4810 for (StringRef Arch : Sorted)
4811 TCAndArchs.push_back(std::make_pair(TC, Arch));
4814 for (
unsigned I = 0,
E = TCAndArchs.size(); I !=
E; ++I)
4815 DeviceActions.push_back(
C.MakeAction<
InputAction>(*InputArg, InputType));
4817 if (DeviceActions.empty())
4823 HostAction->
getType() != types::TY_Nothing &&
4833 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4842 auto TCAndArch = TCAndArchs.begin();
4843 for (
Action *&A : DeviceActions) {
4844 if (A->
getType() == types::TY_Nothing)
4852 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4854 HostAction->
getType() != types::TY_Nothing) {
4861 TCAndArch->second.data(), Kind);
4863 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4872 for (
Action *&A : DeviceActions) {
4873 if ((A->
getType() != types::TY_Object &&
4874 A->
getType() != types::TY_LTO_BC) ||
4876 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4882 auto TCAndArch = TCAndArchs.begin();
4883 for (
Action *A : DeviceActions) {
4884 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4886 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4891 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4893 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4901 bool ShouldBundleHIP =
4903 Args.hasFlag(options::OPT_gpu_bundle_output,
4904 options::OPT_no_gpu_bundle_output,
true) &&
4905 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4906 !llvm::any_of(OffloadActions,
4913 if (OffloadActions.empty())
4918 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4922 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4926 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4931 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4940 nullptr,
C.getActiveOffloadKinds());
4949 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4950 return A->
getType() == types::TY_Nothing;
4951 }) && isa<CompileJobAction>(HostAction);
4954 nullptr, SingleDeviceOutput ? DDep : DDeps);
4955 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4961 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4971 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
4977 llvm_unreachable(
"link action invalid here.");
4979 llvm_unreachable(
"ifsmerge action invalid here.");
4984 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4985 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4986 OutputTy = types::TY_Dependencies;
4991 if (!Args.hasFlag(options::OPT_frewrite_includes,
4992 options::OPT_fno_rewrite_includes,
false) &&
4993 !Args.hasFlag(options::OPT_frewrite_imports,
4994 options::OPT_fno_rewrite_imports,
false) &&
4995 !Args.hasFlag(options::OPT_fdirectives_only,
4996 options::OPT_fno_directives_only,
false) &&
5000 "Cannot preprocess this input type!");
5006 if (Args.hasArg(options::OPT_extract_api))
5013 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
5014 !Args.getLastArg(options::OPT__precompile))
5019 "Cannot precompile this input type!");
5023 const char *ModName =
nullptr;
5024 if (OutputTy == types::TY_PCH) {
5025 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5026 ModName = A->getValue();
5028 OutputTy = types::TY_ModuleFile;
5031 if (Args.hasArg(options::OPT_fsyntax_only)) {
5033 OutputTy = types::TY_Nothing;
5039 if (Args.hasArg(options::OPT_fsyntax_only))
5041 if (Args.hasArg(options::OPT_rewrite_objc))
5043 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5045 types::TY_RewrittenLegacyObjC);
5046 if (Args.hasArg(options::OPT__analyze))
5048 if (Args.hasArg(options::OPT__migrate))
5050 if (Args.hasArg(options::OPT_emit_ast))
5052 if (Args.hasArg(options::OPT_emit_cir))
5054 if (Args.hasArg(options::OPT_module_file_info))
5056 if (Args.hasArg(options::OPT_verify_pch))
5058 if (Args.hasArg(options::OPT_extract_api))
5065 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5066 !Args.hasArg(options::OPT_emit_llvm))
5067 Output = types::TY_PP_Asm;
5068 else if (Args.hasArg(options::OPT_S))
5069 Output = types::TY_LTO_IR;
5071 Output = types::TY_LTO_BC;
5076 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5079 if (Args.hasArg(options::OPT_emit_llvm) ||
5084 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5088 Args.hasArg(options::OPT_S) &&
5092 !Args.hasFlag(options::OPT_offload_new_driver,
5093 options::OPT_no_offload_new_driver,
5096 : types::TY_LLVM_BC;
5105 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5109 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5111 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5131 unsigned NumOutputs = 0;
5132 unsigned NumIfsOutputs = 0;
5133 for (
const Action *A :
C.getActions()) {
5134 if (A->
getType() != types::TY_Nothing &&
5135 A->
getType() != types::TY_DX_CONTAINER &&
5137 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5139 0 == NumIfsOutputs++) ||
5144 A->
getType() == types::TY_Nothing &&
5145 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5146 NumOutputs += A->
size();
5149 if (NumOutputs > 1) {
5150 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5151 FinalOutput =
nullptr;
5155 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5158 llvm::StringSet<> ArchNames;
5159 if (RawTriple.isOSBinFormatMachO())
5160 for (
const Arg *A :
C.getArgs())
5161 if (A->getOption().matches(options::OPT_arch))
5162 ArchNames.insert(A->getValue());
5165 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5166 for (
Action *A :
C.getActions()) {
5173 const char *LinkingOutput =
nullptr;
5174 if (isa<LipoJobAction>(A)) {
5176 LinkingOutput = FinalOutput->getValue();
5184 ArchNames.size() > 1,
5185 LinkingOutput, CachedResults,
5192 for (
auto &J :
C.getJobs())
5193 J.InProcess =
false;
5196 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
5197 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5198 Cmd.getProcessStatistics();
5202 const char *LinkingOutput =
nullptr;
5204 LinkingOutput = FinalOutput->getValue();
5205 else if (!
Cmd.getOutputFilenames().empty())
5206 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
5211 using namespace llvm;
5213 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
5214 <<
"output=" << LinkingOutput;
5215 outs() <<
", total="
5216 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5218 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5219 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5223 llvm::raw_string_ostream Out(Buffer);
5224 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
5227 llvm::sys::printArg(Out, LinkingOutput, true);
5228 Out <<
',' << ProcStat->TotalTime.count() <<
','
5229 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5233 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5234 llvm::sys::fs::OF_Append |
5235 llvm::sys::fs::OF_Text);
5240 llvm::errs() <<
"ERROR: Cannot lock file "
5241 << CCPrintStatReportFilename <<
": "
5242 << toString(L.takeError()) <<
"\n";
5253 if (Diags.hasErrorOccurred() ||
5254 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5258 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5260 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5263 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5264 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5266 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5270 return strstr(J.getCreator().getShortName(),
"assembler");
5272 for (Arg *A :
C.getArgs()) {
5276 if (!A->isClaimed()) {
5282 const Option &Opt = A->getOption();
5283 if (Opt.getKind() == Option::FlagClass) {
5284 bool DuplicateClaimed =
false;
5286 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5287 if (AA->isClaimed()) {
5288 DuplicateClaimed =
true;
5293 if (DuplicateClaimed)
5299 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5301 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5306 !
C.getActions().empty()) {
5307 Diag(diag::err_drv_unsupported_opt_for_target)
5308 << A->getSpelling() << getTargetTriple();
5310 Diag(clang::diag::warn_drv_unused_argument)
5311 << A->getAsString(
C.getArgs());
5321class ToolSelector final {
5332 bool IsHostSelector;
5343 bool CanBeCollapsed =
true) {
5345 if (Inputs.size() != 1)
5348 Action *CurAction = *Inputs.begin();
5349 if (CanBeCollapsed &&
5355 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5359 if (!IsHostSelector) {
5360 if (OA->hasSingleDeviceDependence(
true)) {
5362 OA->getSingleDeviceDependence(
true);
5363 if (CanBeCollapsed &&
5366 SavedOffloadAction.push_back(OA);
5367 return dyn_cast<JobAction>(CurAction);
5369 }
else if (OA->hasHostDependence()) {
5370 CurAction = OA->getHostDependence();
5371 if (CanBeCollapsed &&
5374 SavedOffloadAction.push_back(OA);
5375 return dyn_cast<JobAction>(CurAction);
5380 return dyn_cast<JobAction>(CurAction);
5384 bool canCollapseAssembleAction()
const {
5385 return TC.useIntegratedAs() && !SaveTemps &&
5386 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5387 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5388 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5389 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5393 bool canCollapsePreprocessorAction()
const {
5394 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5395 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5396 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5401 struct JobActionInfo final {
5411 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5413 unsigned ElementNum) {
5414 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5415 for (
unsigned I = 0; I < ElementNum; ++I)
5416 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5417 ActionInfo[I].SavedOffloadAction.end());
5433 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5435 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5436 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5437 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5438 if (!AJ || !BJ || !CJ)
5442 const Tool *
T = TC.SelectTool(*CJ);
5449 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5455 const Tool *BT = TC.SelectTool(*BJ);
5460 if (!
T->hasIntegratedAssembler())
5463 Inputs = CJ->getInputs();
5464 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5471 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5473 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5474 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5479 const Tool *
T = TC.SelectTool(*BJ);
5483 if (!
T->hasIntegratedAssembler())
5486 Inputs = BJ->getInputs();
5487 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5494 if (ActionInfo.size() < 2)
5496 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5497 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5506 bool InputIsBitcode =
true;
5507 for (
size_t i = 1; i < ActionInfo.size(); i++)
5508 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5509 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5510 InputIsBitcode =
false;
5513 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5517 const Tool *
T = TC.SelectTool(*CJ);
5524 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5527 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5530 Inputs = CJ->getInputs();
5531 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5542 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5548 for (
Action *A : Inputs) {
5549 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5550 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5551 NewInputs.push_back(A);
5557 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5558 PreprocessJobOffloadActions.end());
5559 NewInputs.append(PJ->input_begin(), PJ->input_end());
5567 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5569 assert(BaseAction &&
"Invalid base action.");
5586 ActionChain.back().JA = BaseAction;
5587 while (ActionChain.back().JA) {
5588 const Action *CurAction = ActionChain.back().JA;
5591 ActionChain.resize(ActionChain.size() + 1);
5592 JobActionInfo &AI = ActionChain.back();
5596 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5600 ActionChain.pop_back();
5608 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5609 CollapsedOffloadAction);
5611 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5613 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5619 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5631 StringRef BoundArch,
5633 std::string TriplePlusArch = TC->
getTriple().normalize();
5634 if (!BoundArch.empty()) {
5635 TriplePlusArch +=
"-";
5636 TriplePlusArch += BoundArch;
5638 TriplePlusArch +=
"-";
5640 return TriplePlusArch;
5645 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5646 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5649 std::pair<const Action *, std::string> ActionTC = {
5651 auto CachedResult = CachedResults.find(ActionTC);
5652 if (CachedResult != CachedResults.end()) {
5653 return CachedResult->second;
5656 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5657 CachedResults, TargetDeviceOffloadKind);
5658 CachedResults[ActionTC] =
Result;
5663 const JobAction *JA,
const char *BaseInput,
5666 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5670 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5671 Path = A->getValue();
5672 if (llvm::sys::fs::is_directory(
Path)) {
5674 llvm::sys::path::replace_extension(Tmp,
"json");
5675 llvm::sys::path::append(
Path, llvm::sys::path::filename(Tmp));
5678 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5681 Path = DumpDir->getValue();
5682 Path += llvm::sys::path::filename(BaseInput);
5686 llvm::sys::path::replace_extension(
Path,
"json");
5688 const char *ResultFile =
C.getArgs().MakeArgString(
Path);
5689 C.addTimeTraceFile(ResultFile, JA);
5690 C.addResultFile(ResultFile, JA);
5695 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5696 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5699 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5702 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5735 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5737 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5738 const char *DepBoundArch) {
5741 LinkingOutput, CachedResults,
5751 OA->doOnEachDependence(
5752 BuildingForOffloadDevice,
5755 C, DepA, DepTC, DepBoundArch,
false,
5756 !!DepBoundArch, LinkingOutput, CachedResults,
5760 A = BuildingForOffloadDevice
5761 ? OA->getSingleDeviceDependence(
true)
5762 : OA->getHostDependence();
5766 std::pair<const Action *, std::string> ActionTC = {
5767 OA->getHostDependence(),
5769 auto It = CachedResults.find(ActionTC);
5770 if (It != CachedResults.end()) {
5772 Inputs.append(OffloadDependencesInputInfo);
5777 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5780 const Arg &Input = IA->getInputArg();
5782 if (Input.getOption().matches(options::OPT_INPUT)) {
5783 const char *
Name = Input.getValue();
5793 if (!ArchName.empty())
5794 TC = &getToolChain(
C.getArgs(),
5796 C.getArgs(), ArchName));
5798 TC = &
C.getDefaultToolChain();
5801 MultipleArchs, LinkingOutput, CachedResults,
5802 TargetDeviceOffloadKind);
5808 const JobAction *JA = cast<JobAction>(A);
5813 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5820 for (
const auto *OA : CollapsedOffloadActions)
5821 cast<OffloadAction>(OA)->doOnEachDependence(
5822 BuildingForOffloadDevice,
5825 C, DepA, DepTC, DepBoundArch,
false,
5826 !!DepBoundArch, LinkingOutput, CachedResults,
5832 for (
const Action *Input : Inputs) {
5836 bool SubJobAtTopLevel =
5837 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5839 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5844 const char *BaseInput = InputInfos[0].getBaseInput();
5845 for (
auto &Info : InputInfos) {
5846 if (Info.isFilename()) {
5847 BaseInput = Info.getBaseInput();
5854 if (JA->
getType() == types::TY_dSYM)
5855 BaseInput = InputInfos[0].getFilename();
5858 if (!OffloadDependencesInputInfo.empty())
5859 InputInfos.append(OffloadDependencesInputInfo.begin(),
5860 OffloadDependencesInputInfo.end());
5863 llvm::Triple EffectiveTriple;
5865 const ArgList &Args =
5867 if (InputInfos.size() != 1) {
5871 EffectiveTriple = llvm::Triple(
5879 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5883 for (
auto &UI : UA->getDependentActionsInfo()) {
5885 "Unbundling with no offloading??");
5892 UI.DependentOffloadKind,
5893 UI.DependentToolChain->getTriple().normalize(),
5904 UnbundlingResults.push_back(CurI);
5913 Arch = UI.DependentBoundArch;
5918 UI.DependentOffloadKind)}] = {
5924 std::pair<const Action *, std::string> ActionTC = {
5926 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5927 "Result does not exist??");
5928 Result = CachedResults[ActionTC].front();
5929 }
else if (JA->
getType() == types::TY_Nothing)
5936 isa<OffloadPackagerJobAction>(A) ||
5940 AtTopLevel, MultipleArchs,
5943 if (
T->canEmitIR() && OffloadingPrefix.empty())
5948 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5949 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5950 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5951 llvm::errs() << InputInfos[i].getAsString();
5953 llvm::errs() <<
", ";
5955 if (UnbundlingResults.empty())
5956 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5958 llvm::errs() <<
"], outputs: [";
5959 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5960 llvm::errs() << UnbundlingResults[i].getAsString();
5962 llvm::errs() <<
", ";
5964 llvm::errs() <<
"] \n";
5967 if (UnbundlingResults.empty())
5968 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
5970 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
5971 Args, LinkingOutput);
5977 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5978 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5990 if (ArgValue.empty()) {
5993 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
5995 llvm::sys::path::append(
Filename, BaseName);
5998 if (!llvm::sys::path::has_extension(ArgValue)) {
6003 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6008 llvm::sys::path::replace_extension(
Filename, Extension);
6011 return Args.MakeArgString(
Filename.c_str());
6015 if (isa<PreprocessJobAction>(JA))
6017 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
6019 if (isa<OffloadBundlingJobAction>(JA) &&
6026 StringRef Suffix,
bool MultipleArchs,
6027 StringRef BoundArch,
6028 bool NeedUniqueDirectory)
const {
6030 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6031 std::optional<std::string> CrashDirectory =
6033 ? std::string(A->getValue())
6034 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6035 if (CrashDirectory) {
6036 if (!
getVFS().exists(*CrashDirectory))
6037 llvm::sys::fs::create_directories(*CrashDirectory);
6039 llvm::sys::path::append(
Path, Prefix);
6040 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6041 if (std::error_code EC =
6042 llvm::sys::fs::createUniqueFile(
Path + Middle + Suffix, TmpName)) {
6043 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6047 if (MultipleArchs && !BoundArch.empty()) {
6048 if (NeedUniqueDirectory) {
6050 llvm::sys::path::append(TmpName,
6051 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6061 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6076 const char *BaseInput) {
6077 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
6078 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6079 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6084 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6088 const char *BaseInput,
6089 StringRef OrigBoundArch,
bool AtTopLevel,
6091 StringRef OffloadingPrefix)
const {
6092 std::string BoundArch = OrigBoundArch.str();
6093 if (is_style_windows(llvm::sys::path::Style::native)) {
6096 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
6099 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6101 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
6102 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6103 return C.addResultFile(FinalOutput->getValue(), &JA);
6107 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6108 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
6109 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6111 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6112 NameArg = A->getValue();
6113 return C.addResultFile(
6123 if (JA.
getType() == types::TY_ModuleFile &&
6124 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6128 if (JA.
getType() == types::TY_PP_Asm &&
6129 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6130 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6133 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6136 if (JA.
getType() == types::TY_Object &&
6137 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
6138 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6141 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6145 if (JA.
getType() == types::TY_PP_Asm &&
6146 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6147 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6149 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6150 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6151 return C.addResultFile(
6156 if (JA.
getType() == types::TY_API_INFO &&
6157 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6158 C.getArgs().hasArg(options::OPT_o))
6159 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6160 <<
C.getArgs().getLastArgValue(options::OPT_o);
6167 bool SpecifiedModuleOutput =
6168 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6169 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6170 if (MultipleArchs && SpecifiedModuleOutput)
6171 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6175 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
6176 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6177 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
6183 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6185 StringRef
Name = llvm::sys::path::filename(BaseInput);
6186 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6187 const char *Suffix =
6192 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6193 bool NeedUniqueDirectory =
6196 Triple.isOSDarwin();
6197 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6198 NeedUniqueDirectory);
6206 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
6207 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6212 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6213 llvm::sys::path::filename(BasePath));
6214 BaseName = ExternalPath;
6215 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
6216 BaseName = BasePath;
6218 BaseName = llvm::sys::path::filename(BasePath);
6221 const char *NamedOutput;
6223 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6224 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6228 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6232 }
else if (JA.
getType() == types::TY_Image &&
6233 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6234 options::OPT__SLASH_o)) {
6238 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6242 }
else if (JA.
getType() == types::TY_Image) {
6252 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6253 options::OPT_fno_gpu_rdc,
false);
6254 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6255 if (UseOutExtension) {
6257 llvm::sys::path::replace_extension(Output,
"");
6259 Output += OffloadingPrefix;
6260 if (MultipleArchs && !BoundArch.empty()) {
6262 Output.append(BoundArch);
6264 if (UseOutExtension)
6266 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6269 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6270 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6271 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6274 .getLastArg(options::OPT__SLASH_o)
6279 const char *Suffix =
6281 assert(Suffix &&
"All types used for output should have a suffix.");
6283 std::string::size_type End = std::string::npos;
6285 End = BaseName.rfind(
'.');
6287 Suffixed += OffloadingPrefix;
6288 if (MultipleArchs && !BoundArch.empty()) {
6290 Suffixed.append(BoundArch);
6295 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6296 const llvm::opt::DerivedArgList &Args) {
6301 return isa<CompileJobAction>(JA) &&
6303 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6308 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6309 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6310 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6314 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6318 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6319 JA.
getType() != types::TY_PCH) {
6320 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6322 llvm::sys::path::remove_filename(TempPath);
6323 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6324 llvm::sys::path::append(TempPath, OutputFileName);
6325 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6331 bool SameFile =
false;
6333 llvm::sys::fs::current_path(
Result);
6334 llvm::sys::path::append(
Result, BaseName);
6335 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6338 StringRef
Name = llvm::sys::path::filename(BaseInput);
6339 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6343 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6349 llvm::sys::path::remove_filename(BasePath);
6350 if (BasePath.empty())
6351 BasePath = NamedOutput;
6353 llvm::sys::path::append(BasePath, NamedOutput);
6354 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6357 return C.addResultFile(NamedOutput, &JA);
6363 -> std::optional<std::string> {
6366 for (
const auto &
Dir :
P) {
6370 llvm::sys::path::append(
P,
Name);
6371 if (llvm::sys::fs::exists(Twine(
P)))
6372 return std::string(
P);
6374 return std::nullopt;
6381 llvm::sys::path::append(R,
Name);
6382 if (llvm::sys::fs::exists(Twine(R)))
6383 return std::string(R);
6386 llvm::sys::path::append(
P,
Name);
6387 if (llvm::sys::fs::exists(Twine(
P)))
6388 return std::string(
P);
6391 llvm::sys::path::append(
D,
"..",
Name);
6392 if (llvm::sys::fs::exists(Twine(
D)))
6393 return std::string(
D);
6402 llvm::sys::path::append(R2,
"..",
"..",
Name);
6403 if (llvm::sys::fs::exists(Twine(R2)))
6404 return std::string(R2);
6406 return std::string(
Name);
6409void Driver::generatePrefixedToolNames(
6413 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6414 Names.emplace_back(
Tool);
6418 llvm::sys::path::append(Dir, Name);
6419 if (llvm::sys::fs::can_execute(Twine(Dir)))
6421 llvm::sys::path::remove_filename(Dir);
6427 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6432 if (llvm::sys::fs::is_directory(PrefixDir)) {
6435 return std::string(
P);
6438 if (llvm::sys::fs::can_execute(Twine(
P)))
6439 return std::string(
P);
6444 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6452 for (
const auto &
Path : List) {
6455 return std::string(
P);
6459 if (llvm::ErrorOr<std::string>
P =
6460 llvm::sys::findProgramByName(TargetSpecificExecutable))
6464 return std::string(
Name);
6469 std::string error =
"<NOT PRESENT>";
6473 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6490 llvm::sys::path::remove_filename(path);
6491 llvm::sys::path::append(path,
"libc++.modules.json");
6492 if (TC.
getVFS().exists(path))
6493 return static_cast<std::string
>(path);
6498 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6501 return evaluate(
"libc++.a").value_or(error);
6514 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix,
Path);
6516 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6520 return std::string(
Path);
6525 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix,
Path);
6527 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6531 return std::string(
Path);
6536 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6540 Output = FpArg->getValue();
6544 if (!llvm::sys::path::has_extension(Output))
6547 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6548 Output = YcArg->getValue();
6551 llvm::sys::path::replace_extension(Output,
".pch");
6553 return std::string(Output);
6556const ToolChain &Driver::getToolChain(
const ArgList &Args,
6557 const llvm::Triple &
Target)
const {
6559 auto &TC = ToolChains[
Target.str()];
6561 switch (
Target.getOS()) {
6562 case llvm::Triple::AIX:
6563 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6565 case llvm::Triple::Haiku:
6566 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6568 case llvm::Triple::Darwin:
6569 case llvm::Triple::MacOSX:
6570 case llvm::Triple::IOS:
6571 case llvm::Triple::TvOS:
6572 case llvm::Triple::WatchOS:
6573 case llvm::Triple::XROS:
6574 case llvm::Triple::DriverKit:
6575 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6577 case llvm::Triple::DragonFly:
6578 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6580 case llvm::Triple::OpenBSD:
6581 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6583 case llvm::Triple::NetBSD:
6584 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6586 case llvm::Triple::FreeBSD:
6588 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6591 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6593 case llvm::Triple::Linux:
6594 case llvm::Triple::ELFIAMCU:
6595 if (
Target.getArch() == llvm::Triple::hexagon)
6596 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6598 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6599 !
Target.hasEnvironment())
6600 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6603 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6605 else if (
Target.getArch() == llvm::Triple::ve)
6606 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6607 else if (
Target.isOHOSFamily())
6608 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6610 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6612 case llvm::Triple::NaCl:
6613 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6615 case llvm::Triple::Fuchsia:
6616 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6618 case llvm::Triple::Solaris:
6619 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6621 case llvm::Triple::CUDA:
6622 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6624 case llvm::Triple::AMDHSA:
6625 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6627 case llvm::Triple::AMDPAL:
6628 case llvm::Triple::Mesa3D:
6629 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6631 case llvm::Triple::UEFI:
6632 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6634 case llvm::Triple::Win32:
6635 switch (
Target.getEnvironment()) {
6637 if (
Target.isOSBinFormatELF())
6638 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6639 else if (
Target.isOSBinFormatMachO())
6640 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6642 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6644 case llvm::Triple::GNU:
6645 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6647 case llvm::Triple::Itanium:
6648 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6651 case llvm::Triple::MSVC:
6652 case llvm::Triple::UnknownEnvironment:
6653 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6654 .starts_with_insensitive(
"bfd"))
6655 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6659 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6663 case llvm::Triple::PS4:
6664 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6666 case llvm::Triple::PS5:
6667 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6669 case llvm::Triple::Hurd:
6670 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6672 case llvm::Triple::LiteOS:
6673 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6675 case llvm::Triple::ZOS:
6676 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6678 case llvm::Triple::Vulkan:
6679 case llvm::Triple::ShaderModel:
6680 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6685 switch (
Target.getArch()) {
6686 case llvm::Triple::tce:
6687 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6689 case llvm::Triple::tcele:
6690 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6692 case llvm::Triple::hexagon:
6693 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6696 case llvm::Triple::lanai:
6697 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6699 case llvm::Triple::xcore:
6700 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6702 case llvm::Triple::wasm32:
6703 case llvm::Triple::wasm64:
6704 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6706 case llvm::Triple::avr:
6707 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6709 case llvm::Triple::msp430:
6711 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6713 case llvm::Triple::riscv32:
6714 case llvm::Triple::riscv64:
6717 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6719 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6721 case llvm::Triple::ve:
6722 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6724 case llvm::Triple::spirv32:
6725 case llvm::Triple::spirv64:
6726 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6728 case llvm::Triple::csky:
6729 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6733 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6734 else if (
Target.isOSBinFormatELF())
6735 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6736 else if (
Target.isAppleMachO())
6737 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6738 else if (
Target.isOSBinFormatMachO())
6739 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6741 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6749const ToolChain &Driver::getOffloadingDeviceToolChain(
6750 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6759 switch (TargetDeviceOffloadKind) {
6761 if (((
Target.getArch() == llvm::Triple::amdgcn ||
6762 Target.getArch() == llvm::Triple::spirv64) &&
6763 Target.getVendor() == llvm::Triple::AMD &&
6764 Target.getOS() == llvm::Triple::AMDHSA) ||
6765 !Args.hasArgNoClaim(options::OPT_offload_EQ))
6766 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6768 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6769 Target.getVendor() == llvm::Triple::UnknownVendor &&
6770 Target.getOS() == llvm::Triple::UnknownOS)
6771 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6776 if (
Target.isSPIROrSPIRV())
6777 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, HostTC,
6784 assert(TC &&
"Could not create offloading device tool chain.");
6790 if (JA.
size() != 1 ||
6795 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6796 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6797 !isa<ExtractAPIJobAction>(JA))
6805 if (JA.
size() != 1 ||
6810 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6811 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
6819 if (Args.hasArg(options::OPT_emit_static_lib))
6830 unsigned &Micro,
bool &HadExtra) {
6833 Major = Minor = Micro = 0;
6837 if (Str.consumeInteger(10, Major))
6841 if (!Str.consume_front(
"."))
6844 if (Str.consumeInteger(10, Minor))
6848 if (!Str.consume_front(
"."))
6851 if (Str.consumeInteger(10, Micro))
6869 unsigned CurDigit = 0;
6870 while (CurDigit < Digits.size()) {
6872 if (Str.consumeInteger(10, Digit))
6874 Digits[CurDigit] = Digit;
6877 if (!Str.consume_front(
"."))
6886llvm::opt::Visibility
6887Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6900const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6916 llvm_unreachable(
"Unhandled Mode");
6920 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6925 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6926 options::OPT_fno_save_optimization_record,
false))
6930 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6931 options::OPT_fno_save_optimization_record,
false))
6935 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6936 options::OPT_fno_save_optimization_record,
false))
6940 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6941 options::OPT_fno_save_optimization_record,
false))
6948 static StringRef OptName =
6950 llvm::StringRef Opt;
6951 for (StringRef Arg : Args) {
6952 if (!Arg.starts_with(OptName))
6958 return Opt.consume_front(OptName) ? Opt :
"";
6965 llvm::BumpPtrAllocator &Alloc,
6966 llvm::vfs::FileSystem *FS) {
6975 for (
const char *F : Args) {
6976 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6978 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6979 RSPQuoting = Windows;
6987 llvm::cl::TokenizerCallback Tokenizer;
6989 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6991 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6993 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6996 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6997 ECtx.setMarkEOLs(MarkEOLs);
7001 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7005 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7006 [](
const char *A) {
return A !=
nullptr; });
7007 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7010 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7011 Args.resize(newEnd - Args.begin());
7015 return llvm::Error::success();
7019 return SavedStrings.insert(S).first->getKeyData();
7052 llvm::StringSet<> &SavedStrings) {
7055 if (Edit[0] ==
'^') {
7056 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7057 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7058 Args.insert(Args.begin() + 1, Str);
7059 }
else if (Edit[0] ==
'+') {
7060 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7061 OS <<
"### Adding argument " << Str <<
" at end\n";
7062 Args.push_back(Str);
7063 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7064 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7065 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7066 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7067 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7069 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7071 if (Args[i] ==
nullptr)
7073 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7075 if (Repl != Args[i]) {
7076 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7080 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7081 auto Option = Edit.substr(1);
7082 for (
unsigned i = 1; i < Args.size();) {
7083 if (Option == Args[i]) {
7084 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7085 Args.erase(Args.begin() + i);
7086 if (Edit[0] ==
'X') {
7087 if (i < Args.size()) {
7088 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7089 Args.erase(Args.begin() + i);
7091 OS <<
"### Invalid X edit, end of command line!\n";
7096 }
else if (Edit[0] ==
'O') {
7097 for (
unsigned i = 1; i < Args.size();) {
7098 const char *A = Args[i];
7102 if (A[0] ==
'-' && A[1] ==
'O' &&
7103 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7104 (
'0' <= A[2] && A[2] <=
'9'))))) {
7105 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7106 Args.erase(Args.begin() + i);
7110 OS <<
"### Adding argument " << Edit <<
" at end\n";
7111 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7113 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7118 const char *OverrideStr,
7119 llvm::StringSet<> &SavedStrings,
7122 OS = &llvm::nulls();
7124 if (OverrideStr[0] ==
'#') {
7126 OS = &llvm::nulls();
7129 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
7133 const char *S = OverrideStr;
7135 const char *End = ::strchr(S,
' ');
7137 End = S + strlen(S);
static std::optional< llvm::Triple > getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args)
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 llvm::Triple getSYCLDeviceTriple(StringRef TargetArch)
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 const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
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 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 unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
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 std::optional< llvm::Triple > getNVIDIAOffloadTargetTriple(const Driver &D, const ArgList &Args, const llvm::Triple &HostTriple)
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args, OptSpecifier OptEq, OptSpecifier OptNeg)
static Arg * MakeInputArg(DerivedArgList &Args, const OptTable &Opts, StringRef Value, bool Claim=true)
static const char BugReporMsg[]
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static std::optional< llvm::Triple > getOffloadTargetTriple(const Driver &D, const ArgList &Args)
static void appendOneArg(InputArgList &Args, const Arg *Opt)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
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
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
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.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
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.
const ToolChain * getOffloadingToolChain() const
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.
const char * getClassName() const
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.
unsigned getOffloadingHostActiveKinds() const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
A class to find a viable CUDA installation.
void WarnIfUnsupportedVersion()
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...
std::string SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
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,...
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.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
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.
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.
static std::string GetResourcesPath(StringRef BinaryPath)
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
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.
bool HandleImmediateArgs(Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
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.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
const llvm::opt::OptTable & getOpts() const
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 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.
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
std::pair< types::ID, const llvm::opt::Arg * > InputTy
An input type and its arguments.
bool isUsingOffloadLTO() const
Returns true if we are performing any kind of offload LTO.
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 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,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
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.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
bool getCheckInputsExist() const
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.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
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.
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.
Set a ToolChain's effective triple.
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.
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...
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,...
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 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.
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.
static bool IsAMDOffloadArch(OffloadArch A)
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 ...
@ Result
The result type of a method or function.
static bool IsNVIDIAOffloadArch(OffloadArch A)
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch 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.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
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.