58#include "clang/Config/config.h"
70#include "llvm/ADT/ArrayRef.h"
71#include "llvm/ADT/STLExtras.h"
72#include "llvm/ADT/SmallSet.h"
73#include "llvm/ADT/StringExtras.h"
74#include "llvm/ADT/StringRef.h"
75#include "llvm/ADT/StringSet.h"
76#include "llvm/ADT/StringSwitch.h"
77#include "llvm/Config/llvm-config.h"
78#include "llvm/MC/TargetRegistry.h"
79#include "llvm/Option/Arg.h"
80#include "llvm/Option/ArgList.h"
81#include "llvm/Option/OptSpecifier.h"
82#include "llvm/Option/OptTable.h"
83#include "llvm/Option/Option.h"
84#include "llvm/Support/CommandLine.h"
85#include "llvm/Support/ErrorHandling.h"
86#include "llvm/Support/ExitCodes.h"
87#include "llvm/Support/FileSystem.h"
88#include "llvm/Support/FormatVariadic.h"
89#include "llvm/Support/MD5.h"
90#include "llvm/Support/Path.h"
91#include "llvm/Support/PrettyStackTrace.h"
92#include "llvm/Support/Process.h"
93#include "llvm/Support/Program.h"
94#include "llvm/Support/StringSaver.h"
95#include "llvm/Support/VirtualFileSystem.h"
96#include "llvm/Support/raw_ostream.h"
97#include "llvm/TargetParser/Host.h"
108using namespace clang;
112 const ArgList &Args) {
113 auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
117 switch (OffloadTargets.size()) {
119 D.
Diag(diag::err_drv_only_one_offload_target_supported);
122 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) <<
"";
127 return llvm::Triple(OffloadTargets[0]);
130static std::optional<llvm::Triple>
132 const llvm::Triple &HostTriple) {
133 if (!Args.hasArg(options::OPT_offload_EQ)) {
134 return llvm::Triple(HostTriple.isArch64Bit() ?
"nvptx64-nvidia-cuda"
135 :
"nvptx-nvidia-cuda");
138 if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
139 TT->getArch() == llvm::Triple::spirv64)) {
140 if (Args.hasArg(options::OPT_emit_llvm))
142 D.
Diag(diag::err_drv_cuda_offload_only_emit_bc);
145 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
148static std::optional<llvm::Triple>
150 if (!Args.hasArg(options::OPT_offload_EQ)) {
151 return llvm::Triple(
"amdgcn-amd-amdhsa");
156 if (TT->getArch() == llvm::Triple::amdgcn &&
157 TT->getVendor() == llvm::Triple::AMD &&
158 TT->getOS() == llvm::Triple::AMDHSA)
160 if (TT->getArch() == llvm::Triple::spirv64)
162 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
168 StringRef CustomResourceDir) {
174 std::string
Dir = std::string(llvm::sys::path::parent_path(BinaryPath));
177 if (CustomResourceDir !=
"") {
178 llvm::sys::path::append(
P, CustomResourceDir);
185 P = llvm::sys::path::parent_path(
Dir);
186 llvm::sys::path::append(
P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
187 CLANG_VERSION_MAJOR_STRING);
190 return std::string(
P.str());
196 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
197 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
200 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
201 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
202 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
203 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
204 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
205 CheckInputsExist(
true), ProbePrecompiled(
true),
206 SuppressMissingInputWarning(
false) {
209 this->VFS = llvm::vfs::getRealFileSystem();
215 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
218 llvm::sys::path::append(
P,
SysRoot);
222#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
225#if defined(CLANG_CONFIG_FILE_USER_DIR)
228 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
237void Driver::setDriverMode(StringRef
Value) {
238 static const std::string OptName =
239 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
240 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
241 .Case(
"gcc", GCCMode)
242 .Case(
"g++", GXXMode)
243 .Case(
"cpp", CPPMode)
245 .Case(
"flang", FlangMode)
246 .Case(
"dxc", DXCMode)
250 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
255 bool &ContainsError) {
256 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
257 ContainsError =
false;
259 unsigned IncludedFlagsBitmask;
260 unsigned ExcludedFlagsBitmask;
261 std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
262 getIncludeExcludeOptionFlagMasks(IsClCompatMode);
269 unsigned MissingArgIndex, MissingArgCount;
271 getOpts().ParseArgs(ArgStrings, MissingArgIndex, MissingArgCount,
272 IncludedFlagsBitmask, ExcludedFlagsBitmask);
275 if (MissingArgCount) {
276 Diag(diag::err_drv_missing_argument)
277 << Args.getArgString(MissingArgIndex) << MissingArgCount;
284 for (
const Arg *A : Args) {
287 auto ArgString = A->getAsString(Args);
290 ArgString, Nearest, IncludedFlagsBitmask,
292 DiagID = diag::err_drv_unsupported_opt;
293 Diag(DiagID) << ArgString;
295 DiagID = diag::err_drv_unsupported_opt_with_suggestion;
296 Diag(DiagID) << ArgString << Nearest;
304 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
305 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
307 diag::warn_drv_empty_joined_argument,
312 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
314 auto ArgString = A->getAsString(Args);
316 if (
getOpts().findNearest(ArgString, Nearest, IncludedFlagsBitmask,
317 ExcludedFlagsBitmask) > 1) {
320 DiagID = diag::err_drv_unknown_argument_with_suggestion;
321 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
323 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
324 : diag::err_drv_unknown_argument;
325 Diags.
Report(DiagID) << ArgString;
329 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
330 : diag::err_drv_unknown_argument_with_suggestion;
331 Diags.
Report(DiagID) << ArgString << Nearest;
337 for (
const Arg *A : Args.filtered(options::OPT_o)) {
338 if (ArgStrings[A->getIndex()] == A->getSpelling())
342 std::string ArgString = ArgStrings[A->getIndex()];
344 if (
getOpts().findExact(
"-" + ArgString, Nearest, IncludedFlagsBitmask,
345 ExcludedFlagsBitmask))
346 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
347 << A->getAsString(Args) << Nearest;
357 Arg **FinalPhaseArg)
const {
358 Arg *PhaseArg =
nullptr;
362 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
372 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
373 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
374 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
375 options::OPT_fmodule_header_EQ))) {
378 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
379 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
380 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
381 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
382 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
383 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
384 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
385 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
386 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
390 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
394 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
397 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
405 *FinalPhaseArg = PhaseArg;
411 StringRef
Value,
bool Claim =
true) {
412 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
413 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
414 Args.AddSynthesizedArg(A);
420DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
421 const llvm::opt::OptTable &Opts =
getOpts();
422 DerivedArgList *DAL =
new DerivedArgList(Args);
424 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
425 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
426 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
427 bool IgnoreUnused =
false;
428 for (Arg *A : Args) {
432 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
436 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
437 IgnoreUnused =
false;
447 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
448 A->getOption().matches(options::OPT_Xlinker)) &&
449 A->containsValue(
"--no-demangle")) {
451 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
454 for (StringRef Val : A->getValues())
455 if (Val !=
"--no-demangle")
456 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
464 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
465 (A->getValue(0) == StringRef(
"-MD") ||
466 A->getValue(0) == StringRef(
"-MMD"))) {
468 if (A->getValue(0) == StringRef(
"-MD"))
469 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
471 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
472 if (A->getNumValues() == 2)
473 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
478 if (A->getOption().matches(options::OPT_l)) {
479 StringRef
Value = A->getValue();
482 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
484 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
489 if (
Value ==
"cc_kext") {
490 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
496 if (A->getOption().matches(options::OPT__DASH_DASH)) {
498 for (StringRef Val : A->getValues())
507 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
508 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
512#if defined(HOST_LINK_VERSION)
513 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
514 strlen(HOST_LINK_VERSION) > 0) {
515 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
517 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
529 StringRef TargetTriple,
531 StringRef DarwinArchName =
"") {
533 if (
const Arg *A = Args.getLastArg(options::OPT_target))
534 TargetTriple = A->getValue();
536 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
541 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
545 if (
Target.isOSBinFormatMachO()) {
547 if (!DarwinArchName.empty()) {
553 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
554 StringRef ArchName = A->getValue();
561 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
562 options::OPT_mbig_endian)) {
563 if (A->getOption().matches(options::OPT_mlittle_endian)) {
564 llvm::Triple LE =
Target.getLittleEndianArchVariant();
565 if (LE.getArch() != llvm::Triple::UnknownArch)
568 llvm::Triple BE =
Target.getBigEndianArchVariant();
569 if (BE.getArch() != llvm::Triple::UnknownArch)
575 if (
Target.getArch() == llvm::Triple::tce ||
576 Target.getOS() == llvm::Triple::Minix)
581 if (std::optional<std::string> ObjectModeValue =
582 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
583 StringRef ObjectMode = *ObjectModeValue;
584 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
586 if (ObjectMode.equals(
"64")) {
587 AT =
Target.get64BitArchVariant().getArch();
588 }
else if (ObjectMode.equals(
"32")) {
589 AT =
Target.get32BitArchVariant().getArch();
591 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
594 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
600 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
602 D.
Diag(diag::err_drv_unsupported_opt_for_target)
603 << A->getAsString(Args) <<
Target.str();
606 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
607 options::OPT_m32, options::OPT_m16,
608 options::OPT_maix32, options::OPT_maix64);
610 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
612 if (A->getOption().matches(options::OPT_m64) ||
613 A->getOption().matches(options::OPT_maix64)) {
614 AT =
Target.get64BitArchVariant().getArch();
615 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
616 Target.setEnvironment(llvm::Triple::GNU);
617 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
618 Target.setEnvironment(llvm::Triple::Musl);
619 }
else if (A->getOption().matches(options::OPT_mx32) &&
620 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
621 AT = llvm::Triple::x86_64;
622 if (
Target.getEnvironment() == llvm::Triple::Musl)
623 Target.setEnvironment(llvm::Triple::MuslX32);
625 Target.setEnvironment(llvm::Triple::GNUX32);
626 }
else if (A->getOption().matches(options::OPT_m32) ||
627 A->getOption().matches(options::OPT_maix32)) {
628 AT =
Target.get32BitArchVariant().getArch();
629 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
630 Target.setEnvironment(llvm::Triple::GNU);
631 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
632 Target.setEnvironment(llvm::Triple::Musl);
633 }
else if (A->getOption().matches(options::OPT_m16) &&
634 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
635 AT = llvm::Triple::x86;
636 Target.setEnvironment(llvm::Triple::CODE16);
639 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
641 if (
Target.isWindowsGNUEnvironment())
647 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
648 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
649 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
652 if (A && !A->getOption().matches(options::OPT_m32))
653 D.
Diag(diag::err_drv_argument_not_allowed_with)
654 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
656 Target.setArch(llvm::Triple::x86);
657 Target.setArchName(
"i586");
658 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
659 Target.setEnvironmentName(
"");
660 Target.setOS(llvm::Triple::ELFIAMCU);
661 Target.setVendor(llvm::Triple::UnknownVendor);
662 Target.setVendorName(
"intel");
668 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
669 StringRef ABIName = A->getValue();
670 if (ABIName ==
"32") {
672 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
673 Target.getEnvironment() == llvm::Triple::GNUABIN32)
674 Target.setEnvironment(llvm::Triple::GNU);
675 }
else if (ABIName ==
"n32") {
677 if (
Target.getEnvironment() == llvm::Triple::GNU ||
678 Target.getEnvironment() == llvm::Triple::GNUABI64)
679 Target.setEnvironment(llvm::Triple::GNUABIN32);
680 }
else if (ABIName ==
"64") {
682 if (
Target.getEnvironment() == llvm::Triple::GNU ||
683 Target.getEnvironment() == llvm::Triple::GNUABIN32)
684 Target.setEnvironment(llvm::Triple::GNUABI64);
692 if ((A = Args.getLastArg(options::OPT_march_EQ))) {
693 StringRef ArchName = A->getValue();
694 if (ArchName.startswith_insensitive(
"rv32"))
695 Target.setArch(llvm::Triple::riscv32);
696 else if (ArchName.startswith_insensitive(
"rv64"))
697 Target.setArch(llvm::Triple::riscv64);
708 OptSpecifier OptEq, OptSpecifier OptNeg) {
709 if (!Args.hasFlag(OptEq, OptNeg,
false))
712 const Arg *A = Args.getLastArg(OptEq);
713 StringRef LTOName = A->getValue();
721 D.
Diag(diag::err_drv_unsupported_option_argument)
722 << A->getSpelling() << A->getValue();
729void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
731 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
733 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
734 options::OPT_fno_offload_lto);
737 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
738 options::OPT_fno_openmp_target_jit,
false)) {
739 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
740 options::OPT_fno_offload_lto))
742 Diag(diag::err_drv_incompatible_options)
743 << A->getSpelling() <<
"-fopenmp-target-jit";
750 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
752 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
754 RuntimeName = A->getValue();
756 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
764 Diag(diag::err_drv_unsupported_option_argument)
765 << A->getSpelling() << A->getValue();
768 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
783 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
788 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
791 C.getInputArgs().hasArg(options::OPT_hip_link);
792 if (IsCuda && IsHIP) {
793 Diag(clang::diag::err_drv_mix_cuda_hip);
798 const llvm::Triple &HostTriple = HostTC->
getTriple();
806 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
808 CudaTC = std::make_unique<toolchains::CudaToolChain>(
809 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
811 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
813 if (
auto *OMPTargetArg =
814 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
815 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
816 << OMPTargetArg->getSpelling() <<
"HIP";
824 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
826 assert(HIPTC &&
"Could not create offloading device tool chain.");
827 C.addOffloadDeviceToolChain(HIPTC, OFK);
835 bool IsOpenMPOffloading =
836 C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
837 options::OPT_fno_openmp,
false) &&
838 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
839 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ));
840 if (IsOpenMPOffloading) {
846 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
850 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
851 llvm::StringMap<StringRef> FoundNormalizedTriples;
857 if (Arg *OpenMPTargets =
858 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
859 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
860 Diag(clang::diag::warn_drv_empty_joined_argument)
861 << OpenMPTargets->getAsString(
C.getInputArgs());
864 llvm::copy(OpenMPTargets->getValues(), std::back_inserter(OpenMPTriples));
865 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
878 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
879 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
885 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
886 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
891 if (!AMDTriple && !NVPTXTriple) {
892 for (StringRef Arch :
897 for (StringRef Arch : Archs) {
900 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
901 }
else if (AMDTriple &&
904 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
906 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
913 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
918 for (
const auto &TripleAndArchs : DerivedArchs)
919 OpenMPTriples.push_back(TripleAndArchs.first());
922 for (StringRef Val : OpenMPTriples) {
924 std::string NormalizedName = TT.normalize();
927 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
928 if (Duplicate != FoundNormalizedTriples.end()) {
929 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
930 << Val << Duplicate->second;
936 FoundNormalizedTriples[NormalizedName] = Val;
939 if (TT.getArch() == llvm::Triple::UnknownArch)
940 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
945 if (TT.isNVPTX() || TT.isAMDGCN()) {
948 assert(HostTC &&
"Host toolchain should be always defined.");
950 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
953 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
954 *
this, TT, *HostTC,
C.getInputArgs());
955 else if (TT.isAMDGCN())
956 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
957 *
this, TT, *HostTC,
C.getInputArgs());
959 assert(DeviceTC &&
"Device toolchain not defined.");
964 TC = &getToolChain(
C.getInputArgs(), TT);
966 if (DerivedArchs.contains(TT.getTriple()))
967 KnownArchs[TC] = DerivedArchs[TT.getTriple()];
970 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
971 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
981 const Arg *BaseArg) {
985 unsigned Index = Args.MakeIndex(Opt->getSpelling());
986 Arg *Copy =
new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index),
988 Copy->getValues() = Opt->getValues();
989 if (Opt->isClaimed())
991 Copy->setOwnsValues(Opt->getOwnsValues());
992 Opt->setOwnsValues(
false);
996bool Driver::readConfigFile(StringRef FileName,
997 llvm::cl::ExpansionContext &ExpCtx) {
999 auto Status =
getVFS().status(FileName);
1001 Diag(diag::err_drv_cannot_open_config_file)
1002 << FileName << Status.getError().message();
1005 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1006 Diag(diag::err_drv_cannot_open_config_file)
1007 << FileName <<
"not a regular file";
1013 if (llvm::Error Err = ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
1014 Diag(diag::err_drv_cannot_read_config_file)
1015 << FileName <<
toString(std::move(Err));
1021 llvm::sys::path::native(CfgFileName);
1023 std::unique_ptr<InputArgList> NewOptions = std::make_unique<InputArgList>(
1030 for (Arg *A : *NewOptions)
1034 CfgOptions = std::move(NewOptions);
1037 for (
auto *Opt : *NewOptions) {
1038 const Arg *BaseArg = &Opt->getBaseArg();
1044 ConfigFiles.push_back(std::string(CfgFileName));
1048bool Driver::loadConfigFiles() {
1049 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1050 llvm::cl::tokenizeConfigFile);
1051 ExpCtx.setVFS(&
getVFS());
1055 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1058 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1059 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1064 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1066 llvm::sys::fs::expand_tilde(
1067 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1068 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1077 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1080 if (loadDefaultConfigFiles(ExpCtx))
1086 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1089 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1090 CfgFilePath.assign(CfgFileName);
1091 if (llvm::sys::path::is_relative(CfgFilePath)) {
1092 if (
getVFS().makeAbsolute(CfgFilePath)) {
1093 Diag(diag::err_drv_cannot_open_config_file)
1094 << CfgFilePath <<
"cannot get absolute path";
1098 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1100 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1101 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1102 if (!SearchDir.empty())
1103 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1108 if (readConfigFile(CfgFilePath, ExpCtx))
1117bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1120 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1124 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1127 std::string RealMode = getExecutableForDriverMode(Mode);
1137 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1138 PrefixTriple.isOSUnknown())
1139 Triple = PrefixTriple.str();
1143 if (Triple.empty()) {
1144 llvm::Triple RealTriple =
1146 Triple = RealTriple.str();
1147 assert(!Triple.empty());
1162 std::string CfgFileName = Triple +
'-' + RealMode +
".cfg";
1163 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1164 return readConfigFile(CfgFilePath, ExpCtx);
1168 if (TryModeSuffix) {
1170 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1171 return readConfigFile(CfgFilePath, ExpCtx);
1176 CfgFileName = RealMode +
".cfg";
1177 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1178 if (readConfigFile(CfgFilePath, ExpCtx))
1180 }
else if (TryModeSuffix) {
1182 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1183 readConfigFile(CfgFilePath, ExpCtx))
1188 CfgFileName = Triple +
".cfg";
1189 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1190 return readConfigFile(CfgFilePath, ExpCtx);
1198 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1207 if (!DriverMode.empty())
1208 setDriverMode(DriverMode);
1214 CLOptions = std::make_unique<InputArgList>(
1219 ContainsError = loadConfigFiles();
1220 bool HasConfigFile = !ContainsError && (CfgOptions.get() !=
nullptr);
1223 InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
1224 : std::move(*CLOptions));
1227 for (
auto *Opt : *CLOptions) {
1228 if (Opt->getOption().matches(options::OPT_config))
1230 const Arg *BaseArg = &Opt->getBaseArg();
1237 if (
IsCLMode() && !ContainsError) {
1239 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1241 CLModePassThroughArgList.push_back(A->getValue());
1244 if (!CLModePassThroughArgList.empty()) {
1247 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1251 for (
auto *Opt : *CLModePassThroughOptions) {
1258 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1259 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1260 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1263 bool CCCPrintPhases;
1266 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1267 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1270 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1271 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1274 Args.ClaimAllArgs(options::OPT_pipe);
1282 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1284 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1285 CCCGenericGCCName = A->getValue();
1288 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1292 if (Args.hasArg(options::OPT_fproc_stat_report))
1299 llvm::Triple T(TargetTriple);
1300 T.setOS(llvm::Triple::Win32);
1301 T.setVendor(llvm::Triple::PC);
1302 T.setEnvironment(llvm::Triple::MSVC);
1303 T.setObjectFormat(llvm::Triple::COFF);
1304 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1305 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1306 TargetTriple = T.str();
1309 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1310 StringRef TargetProfile = A->getValue();
1313 TargetTriple = *Triple;
1315 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1319 Diag(diag::err_drv_dxc_missing_target_profile);
1323 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1324 TargetTriple = A->getValue();
1325 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1327 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1331 if (std::optional<std::string> CompilerPathValue =
1332 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1333 StringRef CompilerPath = *CompilerPathValue;
1334 while (!CompilerPath.empty()) {
1335 std::pair<StringRef, StringRef> Split =
1336 CompilerPath.split(llvm::sys::EnvPathSeparator);
1337 PrefixDirs.push_back(std::string(Split.first));
1338 CompilerPath = Split.second;
1341 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1343 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1346 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1349 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1350 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1351 .Case(
"cwd", SaveTempsCwd)
1352 .Case(
"obj", SaveTempsObj)
1353 .Default(SaveTempsCwd);
1356 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1357 options::OPT_offload_device_only,
1358 options::OPT_offload_host_device)) {
1359 if (A->getOption().matches(options::OPT_offload_host_only))
1360 Offload = OffloadHost;
1361 else if (A->getOption().matches(options::OPT_offload_device_only))
1362 Offload = OffloadDevice;
1364 Offload = OffloadHostDevice;
1370 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1371 StringRef
Name = A->getValue();
1372 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1373 .Case(
"off", EmbedNone)
1374 .Case(
"all", EmbedBitcode)
1375 .Case(
"bitcode", EmbedBitcode)
1376 .Case(
"marker", EmbedMarker)
1379 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1382 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1386 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1387 llvm::sys::fs::remove(A->getValue());
1393 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1395 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1396 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2b") ||
1397 Std->containsValue(
"c++2a") ||
Std->containsValue(
"c++latest"));
1400 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1401 options::OPT_fmodule_header)) {
1403 ModulesModeCXX20 =
true;
1404 if (A->getOption().matches(options::OPT_fmodule_header))
1407 StringRef ArgName = A->getValue();
1408 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1413 Diags.
Report(diag::err_drv_invalid_value)
1414 << A->getAsString(Args) << ArgName;
1420 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1421 std::make_unique<InputArgList>(std::move(Args));
1424 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1431 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1432 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1433 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1447 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1454 if (TC.
getTriple().isOSBinFormatMachO())
1459 if (CCCPrintPhases) {
1470 llvm::opt::ArgStringList ASL;
1471 for (
const auto *A : Args) {
1475 while (A->getAlias())
1477 A->render(Args, ASL);
1480 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1481 if (I != ASL.begin())
1483 llvm::sys::printArg(OS, *I,
true);
1488bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1490 using namespace llvm::sys;
1491 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1492 "Only knows about .crash files on Darwin");
1497 path::home_directory(CrashDiagDir);
1498 if (CrashDiagDir.startswith(
"/var/root"))
1500 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1508 fs::file_status FileStatus;
1509 TimePoint<> LastAccessTime;
1513 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1514 File != FileEnd && !EC;
File.increment(EC)) {
1515 StringRef FileName = path::filename(
File->path());
1516 if (!FileName.startswith(
Name))
1518 if (fs::status(
File->path(), FileStatus))
1520 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1521 llvm::MemoryBuffer::getFile(
File->path());
1526 StringRef
Data = CrashFile.get()->getBuffer();
1527 if (!
Data.startswith(
"Process:"))
1530 size_t ParentProcPos =
Data.find(
"Parent Process:");
1531 if (ParentProcPos == StringRef::npos)
1533 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1534 if (LineEnd == StringRef::npos)
1536 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1537 int OpenBracket = -1, CloseBracket = -1;
1538 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1539 if (ParentProcess[i] ==
'[')
1541 if (ParentProcess[i] ==
']')
1547 if (OpenBracket < 0 || CloseBracket < 0 ||
1548 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1549 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1559 const auto FileAccessTime = FileStatus.getLastModificationTime();
1560 if (FileAccessTime > LastAccessTime) {
1561 CrashFilePath.assign(
File->path());
1562 LastAccessTime = FileAccessTime;
1567 if (!CrashFilePath.empty()) {
1568 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1578 "\n********************\n\n"
1579 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1580 "Preprocessed source(s) and associated run script(s) are located at:";
1588 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1592 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1593 Level = llvm::StringSwitch<unsigned>(A->getValue())
1595 .Case(
"compiler", 1)
1607 ArgStringList SavedTemps;
1609 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1610 if (!IsLLD || Level < 2)
1617 SavedTemps = std::move(
C.getTempFiles());
1618 assert(!
C.getTempFiles().size());
1635 C.initCompilationForDiagnostics();
1641 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1642 StringRef ReproduceOption =
1643 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1646 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1650 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1652 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1653 Diag(clang::diag::note_drv_command_failed_diag_msg)
1654 <<
"\n\n********************";
1664 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1665 bool IgnoreInput =
false;
1671 }
else if (!strcmp(it->second->getValue(),
"-")) {
1672 Diag(clang::diag::note_drv_command_failed_diag_msg)
1673 <<
"Error generating preprocessed source(s) - "
1674 "ignoring input from stdin.";
1679 it = Inputs.erase(it);
1686 if (Inputs.empty()) {
1687 Diag(clang::diag::note_drv_command_failed_diag_msg)
1688 <<
"Error generating preprocessed source(s) - "
1689 "no preprocessable inputs.";
1695 llvm::StringSet<> ArchNames;
1696 for (
const Arg *A :
C.getArgs()) {
1697 if (A->getOption().matches(options::OPT_arch)) {
1698 StringRef ArchName = A->getValue();
1699 ArchNames.insert(ArchName);
1702 if (ArchNames.size() > 1) {
1703 Diag(clang::diag::note_drv_command_failed_diag_msg)
1704 <<
"Error generating preprocessed source(s) - cannot generate "
1705 "preprocessed source with multiple -arch options.";
1711 const ToolChain &TC =
C.getDefaultToolChain();
1712 if (TC.
getTriple().isOSBinFormatMachO())
1721 Diag(clang::diag::note_drv_command_failed_diag_msg)
1722 <<
"Error generating preprocessed source(s).";
1728 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1731 if (!FailingCommands.empty()) {
1732 Diag(clang::diag::note_drv_command_failed_diag_msg)
1733 <<
"Error generating preprocessed source(s).";
1737 const ArgStringList &TempFiles =
C.getTempFiles();
1738 if (TempFiles.empty()) {
1739 Diag(clang::diag::note_drv_command_failed_diag_msg)
1740 <<
"Error generating preprocessed source(s).";
1748 for (
const char *TempFile : TempFiles) {
1749 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
1752 if (ReproCrashFilename.empty()) {
1753 ReproCrashFilename = TempFile;
1754 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
1756 if (StringRef(TempFile).endswith(
".cache")) {
1759 VFS = llvm::sys::path::filename(TempFile);
1760 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
1764 for (
const char *TempFile : SavedTemps)
1765 C.addTempFile(TempFile);
1771 llvm::sys::path::replace_extension(Script,
"sh");
1773 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
1774 llvm::sys::fs::FA_Write,
1775 llvm::sys::fs::OF_Text);
1777 Diag(clang::diag::note_drv_command_failed_diag_msg)
1778 <<
"Error generating run script: " << Script <<
" " << EC.message();
1781 <<
"# Driver args: ";
1783 ScriptOS <<
"# Original command: ";
1784 Cmd.Print(ScriptOS,
"\n",
true);
1785 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
1786 if (!AdditionalInformation.empty())
1787 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
1791 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
1795 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
1797 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
1798 Diag(clang::diag::note_drv_command_failed_diag_msg)
1799 << ReproCrashFilename.str();
1801 llvm::sys::path::append(CrashDiagDir,
Name);
1802 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
1803 Diag(clang::diag::note_drv_command_failed_diag_msg)
1804 <<
"Crash backtrace is located in";
1805 Diag(clang::diag::note_drv_command_failed_diag_msg)
1806 << CrashDiagDir.str();
1807 Diag(clang::diag::note_drv_command_failed_diag_msg)
1808 <<
"(choose the .crash file that corresponds to your crash)";
1812 for (
const auto &A :
C.getArgs().filtered(options::OPT_frewrite_map_file_EQ))
1813 Diag(clang::diag::note_drv_command_failed_diag_msg) << A->getValue();
1815 Diag(clang::diag::note_drv_command_failed_diag_msg)
1816 <<
"\n\n********************";
1824 if (
Cmd.getResponseFileSupport().ResponseKind ==
1826 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
1827 Cmd.getArguments()))
1831 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
1837 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
1838 if (
C.getArgs().hasArg(options::OPT_v))
1839 C.getJobs().Print(llvm::errs(),
"\n",
true);
1841 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
1851 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
1852 C.getJobs().Print(llvm::errs(),
"\n",
true);
1861 for (
auto &Job :
C.getJobs())
1862 setUpResponseFiles(
C, Job);
1864 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1867 if (FailingCommands.empty())
1873 for (
const auto &CmdPair : FailingCommands) {
1874 int CommandRes = CmdPair.first;
1875 const Command *FailingCommand = CmdPair.second;
1880 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
1884 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
1889 if (CommandRes == EX_IOERR) {
1906 Diag(clang::diag::err_drv_command_signalled)
1909 Diag(clang::diag::err_drv_command_failed)
1917 unsigned IncludedFlagsBitmask;
1918 unsigned ExcludedFlagsBitmask;
1919 std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
1920 getIncludeExcludeOptionFlagMasks(
IsCLMode());
1924 ExcludedFlagsBitmask |= HelpHidden;
1931 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
1933 IncludedFlagsBitmask, ExcludedFlagsBitmask,
1945 const ToolChain &TC =
C.getDefaultToolChain();
1949 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
1952 OS <<
"Thread model: " << A->getValue();
1961 for (
auto ConfigFile : ConfigFiles)
1962 OS <<
"Configuration file: " << ConfigFile <<
'\n';
1975 if (PassedFlags ==
"")
1979 std::vector<std::string> SuggestedCompletions;
1980 std::vector<std::string> Flags;
1982 unsigned int DisableFlags =
1993 const bool HasSpace = PassedFlags.endswith(
",");
1997 StringRef TargetFlags = PassedFlags;
1998 while (TargetFlags !=
"") {
2000 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2001 Flags.push_back(std::string(CurFlag));
2006 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2007 DisableFlags &= ~options::NoDriverOption;
2009 const llvm::opt::OptTable &Opts =
getOpts();
2011 Cur = Flags.at(Flags.size() - 1);
2013 if (Flags.size() >= 2) {
2014 Prev = Flags.at(Flags.size() - 2);
2015 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2018 if (SuggestedCompletions.empty())
2019 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2026 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2027 llvm::outs() <<
'\n';
2033 if (SuggestedCompletions.empty() && !Cur.endswith(
"=")) {
2037 SuggestedCompletions = Opts.findByPrefix(Cur, DisableFlags);
2043 if (S.startswith(Cur))
2044 SuggestedCompletions.push_back(std::string(S));
2051 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2052 if (
int X = A.compare_insensitive(B))
2054 return A.compare(B) > 0;
2057 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2064 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2065 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2069 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2072 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2076 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2081 if (
C.getArgs().hasArg(options::OPT_help) ||
2082 C.getArgs().hasArg(options::OPT__help_hidden)) {
2083 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2087 if (
C.getArgs().hasArg(options::OPT__version)) {
2093 if (
C.getArgs().hasArg(options::OPT_v) ||
2094 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2095 C.getArgs().hasArg(options::OPT_print_supported_cpus)) {
2097 SuppressMissingInputWarning =
true;
2100 if (
C.getArgs().hasArg(options::OPT_v)) {
2102 llvm::errs() <<
"System configuration file directory: "
2105 llvm::errs() <<
"User configuration file directory: "
2109 const ToolChain &TC =
C.getDefaultToolChain();
2111 if (
C.getArgs().hasArg(options::OPT_v))
2114 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2119 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2120 llvm::outs() <<
"programs: =";
2121 bool separator =
false;
2125 llvm::outs() << llvm::sys::EnvPathSeparator;
2126 llvm::outs() << Path;
2131 llvm::outs() << llvm::sys::EnvPathSeparator;
2132 llvm::outs() << Path;
2135 llvm::outs() <<
"\n";
2138 StringRef sysroot =
C.getSysRoot();
2142 llvm::outs() << llvm::sys::EnvPathSeparator;
2145 llvm::outs() << sysroot << Path.substr(1);
2147 llvm::outs() << Path;
2149 llvm::outs() <<
"\n";
2153 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2154 std::string RuntimePath;
2157 if (
getVFS().exists(Path)) {
2162 if (!RuntimePath.empty())
2163 llvm::outs() << RuntimePath <<
'\n';
2169 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2171 for (std::size_t I = 0; I != Flags.size(); I += 2)
2172 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2178 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2179 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2183 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2184 StringRef ProgName = A->getValue();
2187 if (! ProgName.empty())
2190 llvm::outs() <<
"\n";
2194 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2195 StringRef PassedFlags = A->getValue();
2200 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2206 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2209 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2215 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2221 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2224 llvm::outs() <<
".\n";
2227 assert(Suffix.front() ==
'/');
2228 llvm::outs() << Suffix.substr(1) <<
"\n";
2233 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2238 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2240 llvm::outs() << Triple.getTriple() <<
"\n";
2244 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2245 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2262 std::map<Action *, unsigned> &Ids,
2268 llvm::raw_string_ostream os(str);
2270 auto getSibIndent = [](
int K) -> Twine {
2274 Twine SibIndent = Indent + getSibIndent(Kind);
2278 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2280 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2281 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2282 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2283 bool IsFirst =
true;
2284 OA->doOnEachDependence(
2286 assert(TC &&
"Unknown host toolchain");
2298 os <<
":" << BoundArch;
2301 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2309 const char *Prefix =
"{";
2310 for (
Action *PreRequisite : *AL) {
2311 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2322 std::string offload_str;
2323 llvm::raw_string_ostream offload_os(offload_str);
2324 if (!isa<OffloadAction>(A)) {
2327 offload_os <<
", (" << S;
2334 auto getSelfIndent = [](
int K) -> Twine {
2338 unsigned Id = Ids.size();
2340 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2349 std::map<Action *, unsigned> Ids;
2350 for (
Action *A :
C.getActions())
2357 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2358 isa<AssembleJobAction>(A))
2366 DerivedArgList &Args =
C.getArgs();
2368 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2371 llvm::StringSet<> ArchNames;
2373 for (Arg *A : Args) {
2374 if (A->getOption().matches(options::OPT_arch)) {
2377 llvm::Triple::ArchType Arch =
2379 if (Arch == llvm::Triple::UnknownArch) {
2380 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2385 if (ArchNames.insert(A->getValue()).second)
2386 Archs.push_back(A->getValue());
2400 for (
Action* Act : SingleActions) {
2408 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2412 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2417 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2418 Actions.append(Inputs.begin(), Inputs.end());
2420 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2423 Arg *A = Args.getLastArg(options::OPT_g_Group);
2424 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2425 !A->getOption().matches(options::OPT_gstabs);
2433 if (Act->getType() == types::TY_Image) {
2435 Inputs.push_back(Actions.back());
2442 if (Args.hasArg(options::OPT_verify_debug_info)) {
2443 Action* LastAction = Actions.back();
2446 LastAction, types::TY_Nothing));
2465 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2466 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2478 unsigned IncludedFlagsBitmask;
2479 unsigned ExcludedFlagsBitmask;
2480 std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
2481 getIncludeExcludeOptionFlagMasks(
IsCLMode());
2482 std::string Nearest;
2483 if (
getOpts().findNearest(
Value, Nearest, IncludedFlagsBitmask,
2484 ExcludedFlagsBitmask) <= 1) {
2485 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2486 <<
Value << Nearest;
2525 if (
IsCLMode() && Ty == types::TY_Object && !
Value.startswith(
"/"))
2528 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2536 return types::TY_CXXUHeader;
2538 return types::TY_CXXSHeader;
2542 llvm_unreachable(
"should not be called in this case");
2544 return types::TY_CXXHUHeader;
2550 const llvm::opt::OptTable &Opts =
getOpts();
2554 types::ID InputType = types::TY_Nothing;
2555 Arg *InputTypeArg =
nullptr;
2558 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2559 options::OPT__SLASH_TP)) {
2560 InputTypeArg = TCTP;
2561 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2566 bool ShowNote =
false;
2568 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2570 Diag(clang::diag::warn_drv_overriding_flag_option)
2571 <<
Previous->getSpelling() << A->getSpelling();
2577 Diag(clang::diag::note_drv_t_option_is_global);
2582 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2583 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2584 if (LastXArg && LastInputArg &&
2585 LastInputArg->getIndex() < LastXArg->getIndex())
2586 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2590 if (
auto *A = Args.getLastArg(options::OPT_x))
2591 Diag(diag::err_drv_unsupported_opt_with_suggestion)
2592 << A->getAsString(Args) <<
"/TC' or '/TP";
2595 for (Arg *A : Args) {
2596 if (A->getOption().
getKind() == Option::InputClass) {
2597 const char *
Value = A->getValue();
2601 if (InputType == types::TY_Nothing) {
2604 InputTypeArg->claim();
2607 if (memcmp(
Value,
"-", 2) == 0) {
2609 Ty = types::TY_Fortran;
2618 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2619 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2620 : clang::diag::err_drv_unknown_stdin_type);
2629 if (
const char *Ext = strrchr(
Value,
'.'))
2638 Ty = types::TY_Object;
2649 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2650 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2651 << getTypeName(OldTy) << getTypeName(Ty);
2656 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2657 Ty == types::TY_Object)
2658 Ty = types::TY_LLVM_BC;
2666 if (Ty != types::TY_Object) {
2667 if (Args.hasArg(options::OPT_ObjC))
2668 Ty = types::TY_ObjC;
2669 else if (Args.hasArg(options::OPT_ObjCXX))
2670 Ty = types::TY_ObjCXX;
2677 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
2681 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2682 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2685 const char *Ext = strrchr(
Value,
'.');
2687 Ty = types::TY_Object;
2691 InputTypeArg->claim();
2696 Inputs.push_back(std::make_pair(Ty, A));
2698 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2699 StringRef
Value = A->getValue();
2702 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2703 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2706 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2707 StringRef
Value = A->getValue();
2710 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2711 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2717 Inputs.push_back(std::make_pair(types::TY_Object, A));
2719 }
else if (A->getOption().matches(options::OPT_x)) {
2728 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2729 InputType = types::TY_Object;
2736 }
else if (A->getOption().getID() == options::OPT_U) {
2737 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
2738 StringRef Val = A->getValue(0);
2739 if (Val.find_first_of(
"/\\") != StringRef::npos) {
2741 Diag(diag::warn_slash_u_filename) << Val;
2742 Diag(diag::note_use_dashdash);
2746 if (
CCCIsCPP() && Inputs.empty()) {
2750 Inputs.push_back(std::make_pair(types::TY_C, A));
2757class OffloadingActionBuilder final {
2759 bool IsValid =
false;
2765 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
2768 std::map<Action *, const Arg *> HostActionToInputArgMap;
2771 class DeviceActionBuilder {
2775 enum ActionBuilderReturnCode {
2794 DerivedArgList &Args;
2803 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
2806 :
C(
C), Args(Args), Inputs(Inputs),
2807 AssociatedOffloadKind(AssociatedOffloadKind) {}
2808 virtual ~DeviceActionBuilder() {}
2813 virtual ActionBuilderReturnCode
2817 return ABRT_Inactive;
2822 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
2823 return ABRT_Inactive;
2827 virtual void appendTopLevelActions(
ActionList &AL) {}
2830 virtual void appendLinkDeviceActions(
ActionList &AL) {}
2843 virtual bool canUseBundlerUnbundler()
const {
return false; }
2847 bool isValid() {
return !ToolChains.empty(); }
2851 return AssociatedOffloadKind;
2857 class CudaActionBuilderBase :
public DeviceActionBuilder {
2861 bool CompileHostOnly =
false;
2862 bool CompileDeviceOnly =
false;
2864 bool EmitAsm =
false;
2874 TargetID(
const char *ID) :
ID(
ID) {}
2875 operator const char *() {
return ID; }
2876 operator StringRef() {
return StringRef(ID); }
2885 Action *CudaFatBinary =
nullptr;
2888 bool IsActive =
false;
2891 bool Relocatable =
false;
2894 CudaArch DefaultCudaArch = CudaArch::UNKNOWN;
2898 enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
2899 UseCUIDKind UseCUID = CUID_Hash;
2902 StringRef FixedCUID;
2905 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
2908 : DeviceActionBuilder(
C, Args, Inputs, OFKind) {}
2910 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
2917 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
2918 assert(!GpuArchList.empty() &&
2919 "We should have at least one GPU architecture.");
2923 if (!(IA->getType() == types::TY_CUDA ||
2924 IA->getType() == types::TY_HIP ||
2925 IA->getType() == types::TY_PP_HIP)) {
2928 return ABRT_Inactive;
2934 if (CompileHostOnly)
2935 return ABRT_Success;
2938 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
2939 : types::TY_CUDA_DEVICE;
2940 std::string CUID = FixedCUID.str();
2942 if (UseCUID == CUID_Random)
2943 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
2945 else if (UseCUID == CUID_Hash) {
2947 llvm::MD5::MD5Result Hash;
2949 llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
2951 Hasher.update(RealPath);
2952 for (
auto *A : Args) {
2953 if (A->getOption().matches(options::OPT_INPUT))
2955 Hasher.update(A->getAsString(Args));
2958 CUID = llvm::utohexstr(Hash.low(),
true);
2963 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
2964 CudaDeviceActions.push_back(
2965 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
2968 return ABRT_Success;
2972 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
2976 if (UA->getType() == types::TY_Object && !Relocatable)
2977 return ABRT_Inactive;
2979 CudaDeviceActions.clear();
2980 auto *IA = cast<InputAction>(UA->getInputs().back());
2981 std::string FileName = IA->getInputArg().getAsString(Args);
2987 const StringRef LibFileExt =
".lib";
2988 if (IA->getType() == types::TY_Object &&
2989 (!llvm::sys::path::has_extension(FileName) ||
2991 llvm::sys::path::extension(FileName).drop_front()) !=
2993 llvm::sys::path::extension(FileName) == LibFileExt))
2994 return ABRT_Inactive;
2996 for (
auto Arch : GpuArchList) {
2997 CudaDeviceActions.push_back(UA);
2998 UA->registerDependentActionInfo(ToolChains[0], Arch,
2999 AssociatedOffloadKind);
3002 return ABRT_Success;
3005 return IsActive ? ABRT_Success : ABRT_Inactive;
3008 void appendTopLevelActions(
ActionList &AL)
override {
3010 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3012 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3017 if (CudaFatBinary) {
3018 AddTopLevel(CudaFatBinary, CudaArch::UNUSED);
3019 CudaDeviceActions.clear();
3020 CudaFatBinary =
nullptr;
3024 if (CudaDeviceActions.empty())
3030 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3031 "Expecting one action per GPU architecture.");
3032 assert(ToolChains.size() == 1 &&
3033 "Expecting to have a single CUDA toolchain.");
3034 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3035 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3037 CudaDeviceActions.clear();
3042 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3044 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3061 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3062 options::OPT_fno_gpu_rdc,
false);
3065 assert(HostTC &&
"No toolchain for host compilation.");
3067 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3071 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3076 ToolChains.push_back(
3081 CompileHostOnly =
C.getDriver().offloadHostOnly();
3082 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3083 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3084 EmitAsm = Args.getLastArg(options::OPT_S);
3085 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3086 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3087 StringRef UseCUIDStr = A->getValue();
3088 UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3089 .Case(
"hash", CUID_Hash)
3090 .Case(
"random", CUID_Random)
3091 .Case(
"none", CUID_None)
3092 .Default(CUID_Invalid);
3093 if (UseCUID == CUID_Invalid) {
3094 C.getDriver().Diag(diag::err_drv_invalid_value)
3095 << A->getAsString(Args) << UseCUIDStr;
3096 C.setContainsError();
3102 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3103 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3104 options::OPT_no_offload_arch_EQ)) {
3105 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3110 std::set<StringRef> GpuArchs;
3112 for (Arg *A : Args) {
3113 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3114 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3118 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3119 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3122 }
else if (ArchStr ==
"native") {
3123 const ToolChain &TC = *ToolChains.front();
3124 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3127 << llvm::Triple::getArchTypeName(TC.
getArch())
3128 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3132 for (
auto GPU : *GPUsOrErr) {
3133 GpuArchs.insert(Args.MakeArgString(GPU));
3136 ArchStr = getCanonicalOffloadArch(ArchStr);
3137 if (ArchStr.empty()) {
3139 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3140 GpuArchs.insert(ArchStr);
3141 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3142 GpuArchs.erase(ArchStr);
3144 llvm_unreachable(
"Unexpected option.");
3150 if (ConflictingArchs) {
3151 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3152 << ConflictingArchs->first << ConflictingArchs->second;
3153 C.setContainsError();
3158 for (
auto Arch : GpuArchs)
3159 GpuArchList.push_back(Arch.data());
3164 if (GpuArchList.empty()) {
3165 if (ToolChains.front()->getTriple().isSPIRV())
3166 GpuArchList.push_back(CudaArch::Generic);
3168 GpuArchList.push_back(DefaultCudaArch);
3177 class CudaActionBuilder final :
public CudaActionBuilderBase {
3179 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3181 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3182 DefaultCudaArch = CudaArch::SM_35;
3185 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3188 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3194 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3196 const std::set<StringRef> &GpuArchs)
override {
3197 return std::nullopt;
3200 ActionBuilderReturnCode
3203 PhasesTy &Phases)
override {
3205 return ABRT_Inactive;
3209 if (CudaDeviceActions.empty())
3210 return ABRT_Success;
3212 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3213 "Expecting one action per GPU architecture.");
3214 assert(!CompileHostOnly &&
3215 "Not expecting CUDA actions in host-only compilation.");
3225 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3228 for (
auto Ph : Phases) {
3233 if (Ph > FinalPhase)
3236 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3246 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3250 Action *AssembleAction = CudaDeviceActions[I];
3251 assert(AssembleAction->
getType() == types::TY_Object);
3252 assert(AssembleAction->
getInputs().size() == 1);
3260 DeviceActions.push_back(
3266 if (!DeviceActions.empty()) {
3268 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3270 if (!CompileDeviceOnly) {
3271 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3275 CudaFatBinary =
nullptr;
3280 CudaDeviceActions.clear();
3284 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3289 return ABRT_Success;
3293 "instructions should only occur "
3294 "before the backend phase!");
3297 for (
Action *&A : CudaDeviceActions)
3298 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3300 return ABRT_Success;
3305 class HIPActionBuilder final :
public CudaActionBuilderBase {
3313 std::optional<bool> BundleOutput;
3318 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3319 DefaultCudaArch = CudaArch::GFX906;
3320 if (Args.hasArg(options::OPT_gpu_bundle_output,
3321 options::OPT_no_gpu_bundle_output))
3322 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3323 options::OPT_no_gpu_bundle_output,
true);
3326 bool canUseBundlerUnbundler()
const override {
return true; }
3328 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3329 llvm::StringMap<bool> Features;
3336 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3337 C.setContainsError();
3341 return Args.MakeArgStringRef(CanId);
3344 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3346 const std::set<StringRef> &GpuArchs)
override {
3350 ActionBuilderReturnCode
3353 PhasesTy &Phases)
override {
3355 return ABRT_Inactive;
3361 if (CudaDeviceActions.empty())
3362 return ABRT_Success;
3365 CudaDeviceActions.size() == GpuArchList.size()) &&
3366 "Expecting one action per GPU architecture.");
3367 assert(!CompileHostOnly &&
3368 "Not expecting HIP actions in host-only compilation.");
3377 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3378 if (
C.getDriver().isUsingLTO(
true)) {
3382 AL.push_back(CudaDeviceActions[I]);
3385 CudaDeviceActions[I] =
3392 if (ToolChains.front()->getTriple().isSPIRV()) {
3395 types::ID Output = Args.hasArg(options::OPT_S)
3397 : types::TY_LLVM_BC;
3403 AssociatedOffloadKind);
3404 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3406 AssociatedOffloadKind);
3407 AL.push_back(AssembleAction);
3410 CudaDeviceActions[I] =
3421 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3422 AssociatedOffloadKind);
3424 DDep, CudaDeviceActions[I]->getType());
3427 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3430 types::TY_HIP_FATBIN);
3432 if (!CompileDeviceOnly) {
3433 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3434 AssociatedOffloadKind);
3437 CudaFatBinary =
nullptr;
3442 CudaDeviceActions.clear();
3445 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3452 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3453 auto LI = DeviceLinkerInputs.begin();
3454 for (
auto *A : CudaDeviceActions) {
3461 CudaDeviceActions.clear();
3462 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3466 for (
Action *&A : CudaDeviceActions)
3467 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3468 AssociatedOffloadKind);
3470 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3472 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3474 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3475 AssociatedOffloadKind);
3477 DDep, CudaDeviceActions[I]->getType());
3481 CudaDeviceActions.clear();
3484 return (CompileDeviceOnly && CurPhase == FinalPhase) ? ABRT_Ignore_Host
3488 void appendLinkDeviceActions(
ActionList &AL)
override {
3489 if (DeviceLinkerInputs.size() == 0)
3492 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3493 "Linker inputs and GPU arch list sizes do not match.");
3499 for (
auto &LI : DeviceLinkerInputs) {
3501 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3505 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3509 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3510 GpuArchList[I], AssociatedOffloadKind);
3512 DeviceLinkDeps, DeviceLinkAction->getType()));
3515 DeviceLinkerInputs.clear();
3518 if (Args.hasArg(options::OPT_emit_llvm)) {
3527 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3530 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3531 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3532 AssociatedOffloadKind);
3535 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3541 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3557 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3565 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3568 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3576 unsigned ValidBuilders = 0u;
3577 unsigned ValidBuildersSupportingBundling = 0u;
3578 for (
auto *SB : SpecializedBuilders) {
3579 IsValid = IsValid && !SB->initialize();
3582 if (SB->isValid()) {
3584 if (SB->canUseBundlerUnbundler())
3585 ++ValidBuildersSupportingBundling;
3589 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3592 ~OffloadingActionBuilder() {
3593 for (
auto *SB : SpecializedBuilders)
3598 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3599 assert(HostAction &&
"Invalid host action");
3600 assert(InputArg &&
"Invalid input argument");
3601 auto Loc = HostActionToInputArgMap.find(HostAction);
3602 if (Loc == HostActionToInputArgMap.end())
3603 HostActionToInputArgMap[HostAction] = InputArg;
3604 assert(HostActionToInputArgMap[HostAction] == InputArg &&
3605 "host action mapped to multiple input arguments");
3613 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3615 DeviceActionBuilder::PhasesTy &Phases) {
3619 if (SpecializedBuilders.empty())
3622 assert(HostAction &&
"Invalid host action!");
3623 recordHostAction(HostAction, InputArg);
3628 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3629 unsigned InactiveBuilders = 0u;
3630 unsigned IgnoringBuilders = 0u;
3631 for (
auto *SB : SpecializedBuilders) {
3632 if (!SB->isValid()) {
3638 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3643 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3648 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3649 OffloadKind |= SB->getAssociatedOffloadKind();
3654 if (IgnoringBuilders &&
3655 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3672 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3673 const Arg *InputArg) {
3677 recordHostAction(HostAction, InputArg);
3685 if (CanUseBundler && isa<InputAction>(HostAction) &&
3686 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3688 HostAction->
getType() == types::TY_PP_HIP)) {
3689 auto UnbundlingHostAction =
3694 HostAction = UnbundlingHostAction;
3695 recordHostAction(HostAction, InputArg);
3698 assert(HostAction &&
"Invalid host action!");
3701 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3702 for (
auto *SB : SpecializedBuilders) {
3706 auto RetCode = SB->addDeviceDependences(HostAction);
3710 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3711 "Host dependence not expected to be ignored.!");
3715 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3716 OffloadKind |= SB->getAssociatedOffloadKind();
3721 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
3731 const Arg *InputArg) {
3733 recordHostAction(HostAction, InputArg);
3737 for (
auto *SB : SpecializedBuilders) {
3740 SB->appendTopLevelActions(OffloadAL);
3747 if (CanUseBundler && HostAction &&
3748 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
3750 OffloadAL.push_back(HostAction);
3754 assert(HostAction == AL.back() &&
"Host action not in the list??");
3756 recordHostAction(HostAction, InputArg);
3757 AL.back() = HostAction;
3759 AL.append(OffloadAL.begin(), OffloadAL.end());
3769 void appendDeviceLinkActions(
ActionList &AL) {
3770 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3773 SB->appendLinkDeviceActions(AL);
3777 Action *makeHostLinkAction() {
3780 appendDeviceLinkActions(DeviceAL);
3781 if (DeviceAL.empty())
3786 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3789 HA = SB->appendLinkHostActions(DeviceAL);
3806 for (
auto *SB : SpecializedBuilders) {
3810 SB->appendLinkDependences(DDeps);
3814 unsigned ActiveOffloadKinds = 0u;
3815 for (
auto &I : InputArgToOffloadKindMap)
3816 ActiveOffloadKinds |= I.second;
3828 for (
auto *A : HostAction->
inputs()) {
3829 auto ArgLoc = HostActionToInputArgMap.find(A);
3830 if (ArgLoc == HostActionToInputArgMap.end())
3832 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
3833 if (OFKLoc == InputArgToOffloadKindMap.end())
3845 nullptr, ActiveOffloadKinds);
3851void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
3852 const InputList &Inputs,
3856 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3857 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3858 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3859 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3860 Args.eraseArg(options::OPT__SLASH_Yc);
3861 Args.eraseArg(options::OPT__SLASH_Yu);
3862 YcArg = YuArg =
nullptr;
3864 if (YcArg && Inputs.size() > 1) {
3865 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3866 Args.eraseArg(options::OPT__SLASH_Yc);
3875 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
3876 Diag(clang::diag::err_drv_emit_llvm_link);
3878 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
3879 .equals_insensitive(
"lld"))
3880 Diag(clang::diag::err_drv_lto_without_lld);
3887 Args.eraseArg(options::OPT__SLASH_Fp);
3888 Args.eraseArg(options::OPT__SLASH_Yc);
3889 Args.eraseArg(options::OPT__SLASH_Yu);
3890 YcArg = YuArg =
nullptr;
3893 unsigned LastPLSize = 0;
3894 for (
auto &I : Inputs) {
3896 const Arg *InputArg = I.second;
3899 LastPLSize = PL.size();
3904 if (InitialPhase > FinalPhase) {
3905 if (InputArg->isClaimed())
3912 if (Args.hasArg(options::OPT_Qunused_arguments))
3918 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
3919 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
3923 (Args.getLastArg(options::OPT__SLASH_EP,
3924 options::OPT__SLASH_P) ||
3925 Args.getLastArg(options::OPT_E) ||
3926 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
3928 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
3929 << InputArg->getAsString(Args) << !!FinalPhaseArg
3930 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
3932 Diag(clang::diag::warn_drv_input_file_unused)
3933 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
3935 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
3948 Actions.push_back(ClangClPch);
3962 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
3963 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
3969 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
3971 if (!SuppressMissingInputWarning && Inputs.empty()) {
3972 Diag(clang::diag::err_drv_no_input_files);
3977 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
3978 StringRef
V = A->getValue();
3979 if (Inputs.size() > 1 && !
V.empty() &&
3980 !llvm::sys::path::is_separator(
V.back())) {
3982 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3983 << A->getSpelling() <<
V;
3984 Args.eraseArg(options::OPT__SLASH_Fo);
3989 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
3990 StringRef
V = A->getValue();
3991 if (Inputs.size() > 1 && !
V.empty() &&
3992 !llvm::sys::path::is_separator(
V.back())) {
3994 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
3995 << A->getSpelling() <<
V;
3996 Args.eraseArg(options::OPT__SLASH_Fa);
4001 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4002 if (A->getValue()[0] ==
'\0') {
4004 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4005 Args.eraseArg(options::OPT__SLASH_o);
4009 handleArguments(
C, Args, Inputs, Actions);
4011 bool UseNewOffloadingDriver =
4013 Args.hasFlag(options::OPT_offload_new_driver,
4014 options::OPT_no_offload_new_driver,
false);
4017 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4018 !UseNewOffloadingDriver
4019 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4027 for (
auto &I : Inputs) {
4029 const Arg *InputArg = I.second;
4042 if (!UseNewOffloadingDriver)
4043 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4049 if (!UseNewOffloadingDriver)
4050 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4051 Current, InputArg, Phase, PL.back(), FullPL);
4057 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4059 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4060 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))))
4061 LinkerInputs.push_back(Current);
4071 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4072 MergerInputs.push_back(Current);
4090 if (NewCurrent == Current)
4093 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4096 Current = NewCurrent;
4100 if (!UseNewOffloadingDriver)
4101 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4106 if (UseNewOffloadingDriver)
4109 if (Current->getType() == types::TY_Nothing)
4115 Actions.push_back(Current);
4118 if (!UseNewOffloadingDriver)
4119 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4121 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4127 if (LinkerInputs.empty()) {
4130 if (!UseNewOffloadingDriver)
4131 OffloadBuilder->appendDeviceLinkActions(Actions);
4134 if (!LinkerInputs.empty()) {
4135 if (!UseNewOffloadingDriver)
4136 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4137 LinkerInputs.push_back(Wrapper);
4142 }
else if (UseNewOffloadingDriver ||
4143 Args.hasArg(options::OPT_offload_link)) {
4150 if (!UseNewOffloadingDriver)
4151 LA = OffloadBuilder->processHostLinkAction(LA);
4152 Actions.push_back(LA);
4156 if (!MergerInputs.empty())
4160 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4167 for (
auto &I : Inputs) {
4169 const Arg *InputArg = I.second;
4174 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4175 InputType == types::TY_Asm)
4180 for (
auto Phase : PhaseList) {
4184 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4189 if (InputType == types::TY_Object)
4196 assert(Phase == PhaseList.back() &&
4197 "merging must be final compilation step.");
4198 MergerInputs.push_back(Current);
4207 Actions.push_back(Current);
4211 if (!MergerInputs.empty())
4218 if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) {
4224 for (
auto &I : Inputs)
4229 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4233 if (TC.requiresValidation(Args)) {
4234 Action *LastAction = Actions.back();
4236 LastAction, types::TY_DX_CONTAINER));
4241 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4247 const llvm::opt::DerivedArgList &Args,
4249 const llvm::Triple &Triple,
4250 bool SuppressError =
false) {
4254 if (!SuppressError && Triple.isNVPTX() &&
4256 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4257 <<
"CUDA" << ArchStr;
4259 }
else if (!SuppressError && Triple.isAMDGPU() &&
4261 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4262 <<
"HIP" << ArchStr;
4270 llvm::StringMap<bool> Features;
4276 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4277 C.setContainsError();
4289static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4293 return std::nullopt;
4295 std::set<StringRef> ArchSet;
4296 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4303 bool SuppressError)
const {
4305 TC = &
C.getDefaultToolChain();
4308 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4309 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4310 options::OPT_no_offload_arch_EQ)) {
4311 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4313 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4315 :
"--no-offload-arch");
4318 if (KnownArchs.contains(TC))
4319 return KnownArchs.lookup(TC);
4322 for (
auto *Arg : Args) {
4324 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4325 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4328 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4329 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4330 Arg = ExtractedArg.get();
4335 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4336 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4337 if (Arch ==
"native" || Arch.empty()) {
4341 llvm::consumeError(GPUsOrErr.takeError());
4344 << llvm::Triple::getArchTypeName(TC->
getArch())
4345 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4349 for (
auto ArchStr : *GPUsOrErr) {
4356 C, Args, Arch, TC->
getTriple(), SuppressError);
4357 if (ArchStr.empty())
4359 Archs.insert(ArchStr);
4362 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4363 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4364 if (Arch ==
"all") {
4368 C, Args, Arch, TC->
getTriple(), SuppressError);
4369 if (ArchStr.empty())
4371 Archs.erase(ArchStr);
4378 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4379 << ConflictingArchs->first << ConflictingArchs->second;
4380 C.setContainsError();
4387 if (Archs.empty()) {
4393 Archs.insert(StringRef());
4395 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4396 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4403 llvm::opt::DerivedArgList &Args,
4405 Action *HostAction)
const {
4410 !(isa<CompileJobAction>(HostAction) ||
4424 auto TCRange =
C.getOffloadToolChains(Kind);
4425 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4426 ToolChains.push_back(TI->second);
4428 if (ToolChains.empty())
4432 const Arg *InputArg = Input.second;
4443 TCAndArchs.push_back(std::make_pair(TC, Arch));
4445 for (
unsigned I = 0, E = TCAndArchs.size(); I != E; ++I)
4446 DeviceActions.push_back(
C.MakeAction<
InputAction>(*InputArg, InputType));
4448 if (DeviceActions.empty())
4455 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4459 auto TCAndArch = TCAndArchs.begin();
4460 for (
Action *&A : DeviceActions) {
4461 if (A->
getType() == types::TY_Nothing)
4469 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4471 HostAction->
getType() != types::TY_Nothing) {
4478 TCAndArch->second.data(), Kind);
4480 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4489 for (
Action *&A : DeviceActions) {
4490 if ((A->
getType() != types::TY_Object &&
4491 A->
getType() != types::TY_LTO_BC) ||
4493 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4499 auto TCAndArch = TCAndArchs.begin();
4500 for (
Action *A : DeviceActions) {
4501 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4503 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4512 if (OffloadActions.empty())
4517 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4521 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4525 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4530 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4539 nullptr,
C.getActiveOffloadKinds());
4544 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4545 return A->
getType() == types::TY_Nothing;
4546 }) && isa<CompileJobAction>(HostAction);
4549 nullptr, SingleDeviceOutput ? DDep : DDeps);
4550 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4556 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4567 llvm_unreachable(
"link action invalid here.");
4569 llvm_unreachable(
"ifsmerge action invalid here.");
4574 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4575 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4576 OutputTy = types::TY_Dependencies;
4581 if (!Args.hasFlag(options::OPT_frewrite_includes,
4582 options::OPT_fno_rewrite_includes,
false) &&
4583 !Args.hasFlag(options::OPT_frewrite_imports,
4584 options::OPT_fno_rewrite_imports,
false) &&
4585 !Args.hasFlag(options::OPT_fdirectives_only,
4586 options::OPT_fno_directives_only,
false) &&
4590 "Cannot preprocess this input type!");
4596 if (Args.hasArg(options::OPT_extract_api))
4601 "Cannot precompile this input type!");
4605 const char *ModName =
nullptr;
4606 if (OutputTy == types::TY_PCH) {
4607 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4608 ModName = A->getValue();
4610 OutputTy = types::TY_ModuleFile;
4613 if (Args.hasArg(options::OPT_fsyntax_only)) {
4615 OutputTy = types::TY_Nothing;
4621 if (Args.hasArg(options::OPT_fsyntax_only))
4623 if (Args.hasArg(options::OPT_rewrite_objc))
4625 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
4627 types::TY_RewrittenLegacyObjC);
4628 if (Args.hasArg(options::OPT__analyze))
4630 if (Args.hasArg(options::OPT__migrate))
4632 if (Args.hasArg(options::OPT_emit_ast))
4634 if (Args.hasArg(options::OPT_module_file_info))
4636 if (Args.hasArg(options::OPT_verify_pch))
4638 if (Args.hasArg(options::OPT_extract_api))
4645 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
4651 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
4654 if (Args.hasArg(options::OPT_emit_llvm) ||
4658 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4662 Args.hasArg(options::OPT_S) &&
4666 !Args.hasFlag(options::OPT_offload_new_driver,
4667 options::OPT_no_offload_new_driver,
false)))
4669 : types::TY_LLVM_BC;
4678 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4682 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4684 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
4704 unsigned NumOutputs = 0;
4705 unsigned NumIfsOutputs = 0;
4706 for (
const Action *A :
C.getActions()) {
4707 if (A->
getType() != types::TY_Nothing &&
4708 A->
getType() != types::TY_DX_CONTAINER &&
4710 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
4712 0 == NumIfsOutputs++) ||
4717 A->
getType() == types::TY_Nothing &&
4718 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
4719 NumOutputs += A->
size();
4722 if (NumOutputs > 1) {
4723 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
4724 FinalOutput =
nullptr;
4728 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
4729 if (RawTriple.isOSAIX()) {
4730 if (Arg *A =
C.getArgs().getLastArg(options::OPT_G))
4731 Diag(diag::err_drv_unsupported_opt_for_target)
4732 << A->getSpelling() << RawTriple.str();
4734 Diag(diag::err_drv_clang_unsupported) <<
"thinLTO on AIX";
4738 llvm::StringSet<> ArchNames;
4739 if (RawTriple.isOSBinFormatMachO())
4740 for (
const Arg *A :
C.getArgs())
4741 if (A->getOption().matches(options::OPT_arch))
4742 ArchNames.insert(A->getValue());
4745 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
4746 for (
Action *A :
C.getActions()) {
4753 const char *LinkingOutput =
nullptr;
4754 if (isa<LipoJobAction>(A)) {
4756 LinkingOutput = FinalOutput->getValue();
4764 ArchNames.size() > 1,
4765 LinkingOutput, CachedResults,
4772 for (
auto &J :
C.getJobs())
4773 J.InProcess =
false;
4776 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
4777 std::optional<llvm::sys::ProcessStatistics> ProcStat =
4778 Cmd.getProcessStatistics();
4782 const char *LinkingOutput =
nullptr;
4784 LinkingOutput = FinalOutput->getValue();
4785 else if (!
Cmd.getOutputFilenames().empty())
4786 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
4791 using namespace llvm;
4793 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
4794 <<
"output=" << LinkingOutput;
4795 outs() <<
", total="
4796 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
4798 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
4799 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
4803 llvm::raw_string_ostream Out(Buffer);
4804 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
4807 llvm::sys::printArg(Out, LinkingOutput, true);
4808 Out <<
',' << ProcStat->TotalTime.count() <<
','
4809 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
4813 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
4814 llvm::sys::fs::OF_Append |
4815 llvm::sys::fs::OF_Text);
4820 llvm::errs() <<
"ERROR: Cannot lock file "
4821 << CCPrintStatReportFilename <<
": "
4822 << toString(L.takeError()) <<
"\n";
4833 if (Diags.hasErrorOccurred() ||
4834 C.getArgs().hasArg(options::OPT_Qunused_arguments))
4838 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
4840 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
4843 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
4844 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
4846 for (Arg *A :
C.getArgs()) {
4850 if (!A->isClaimed()) {
4856 const Option &Opt = A->getOption();
4857 if (Opt.getKind() == Option::FlagClass) {
4858 bool DuplicateClaimed =
false;
4860 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
4861 if (AA->isClaimed()) {
4862 DuplicateClaimed =
true;
4867 if (DuplicateClaimed)
4873 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN))
4874 Diag(clang::diag::warn_drv_unused_argument)
4875 << A->getAsString(
C.getArgs());
4883class ToolSelector final {
4894 bool IsHostSelector;
4905 bool CanBeCollapsed =
true) {
4907 if (Inputs.size() != 1)
4910 Action *CurAction = *Inputs.begin();
4911 if (CanBeCollapsed &&
4917 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
4921 if (!IsHostSelector) {
4922 if (OA->hasSingleDeviceDependence(
true)) {
4924 OA->getSingleDeviceDependence(
true);
4925 if (CanBeCollapsed &&
4928 SavedOffloadAction.push_back(OA);
4929 return dyn_cast<JobAction>(CurAction);
4931 }
else if (OA->hasHostDependence()) {
4932 CurAction = OA->getHostDependence();
4933 if (CanBeCollapsed &&
4936 SavedOffloadAction.push_back(OA);
4937 return dyn_cast<JobAction>(CurAction);
4942 return dyn_cast<JobAction>(CurAction);
4946 bool canCollapseAssembleAction()
const {
4947 return TC.useIntegratedAs() && !SaveTemps &&
4948 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
4949 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
4950 !
C.getArgs().hasArg(options::OPT__SLASH_Fa);
4954 bool canCollapsePreprocessorAction()
const {
4955 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
4956 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
4957 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
4962 struct JobActionInfo final {
4972 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
4974 unsigned ElementNum) {
4975 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
4976 for (
unsigned I = 0; I < ElementNum; ++I)
4977 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
4978 ActionInfo[I].SavedOffloadAction.end());
4994 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
4996 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
4997 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
4998 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
4999 if (!AJ || !BJ || !CJ)
5003 const Tool *T = TC.SelectTool(*CJ);
5016 const Tool *BT = TC.SelectTool(*BJ);
5024 Inputs = CJ->getInputs();
5025 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5032 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5034 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5035 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5040 const Tool *T = TC.SelectTool(*BJ);
5047 Inputs = BJ->getInputs();
5048 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5055 if (ActionInfo.size() < 2)
5057 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5058 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5067 bool InputIsBitcode =
true;
5068 for (
size_t i = 1; i < ActionInfo.size(); i++)
5069 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5070 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5071 InputIsBitcode =
false;
5074 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5078 const Tool *T = TC.SelectTool(*CJ);
5091 Inputs = CJ->getInputs();
5092 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5109 for (
Action *A : Inputs) {
5110 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5111 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5112 NewInputs.push_back(A);
5118 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5119 PreprocessJobOffloadActions.end());
5120 NewInputs.append(PJ->input_begin(), PJ->input_end());
5128 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5130 assert(BaseAction &&
"Invalid base action.");
5147 ActionChain.back().JA = BaseAction;
5148 while (ActionChain.back().JA) {
5149 const Action *CurAction = ActionChain.back().JA;
5152 ActionChain.resize(ActionChain.size() + 1);
5153 JobActionInfo &AI = ActionChain.back();
5157 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5161 ActionChain.pop_back();
5169 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5170 CollapsedOffloadAction);
5172 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5174 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5180 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
5192 StringRef BoundArch,
5194 std::string TriplePlusArch = TC->
getTriple().normalize();
5195 if (!BoundArch.empty()) {
5196 TriplePlusArch +=
"-";
5197 TriplePlusArch += BoundArch;
5199 TriplePlusArch +=
"-";
5201 return TriplePlusArch;
5206 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5207 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5210 std::pair<const Action *, std::string> ActionTC = {
5212 auto CachedResult = CachedResults.find(ActionTC);
5213 if (CachedResult != CachedResults.end()) {
5214 return CachedResult->second;
5217 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5218 CachedResults, TargetDeviceOffloadKind);
5219 CachedResults[ActionTC] =
Result;
5225 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5226 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5229 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5232 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5265 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5267 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5268 const char *DepBoundArch) {
5271 LinkingOutput, CachedResults,
5281 OA->doOnEachDependence(
5282 BuildingForOffloadDevice,
5285 C, DepA, DepTC, DepBoundArch,
false,
5286 !!DepBoundArch, LinkingOutput, CachedResults,
5290 A = BuildingForOffloadDevice
5291 ? OA->getSingleDeviceDependence(
true)
5292 : OA->getHostDependence();
5296 std::pair<const Action *, std::string> ActionTC = {
5297 OA->getHostDependence(),
5299 if (CachedResults.find(ActionTC) != CachedResults.end()) {
5301 Inputs.append(OffloadDependencesInputInfo);
5306 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5309 const Arg &Input = IA->getInputArg();
5311 if (Input.getOption().matches(options::OPT_INPUT)) {
5312 const char *
Name = Input.getValue();
5322 if (!ArchName.empty())
5323 TC = &getToolChain(
C.getArgs(),
5325 C.getArgs(), ArchName));
5327 TC = &
C.getDefaultToolChain();
5330 MultipleArchs, LinkingOutput, CachedResults,
5331 TargetDeviceOffloadKind);
5337 const JobAction *JA = cast<JobAction>(A);
5342 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
5349 for (
const auto *OA : CollapsedOffloadActions)
5350 cast<OffloadAction>(OA)->doOnEachDependence(
5351 BuildingForOffloadDevice,
5354 C, DepA, DepTC, DepBoundArch,
false,
5355 !!DepBoundArch, LinkingOutput, CachedResults,
5361 for (
const Action *Input : Inputs) {
5365 bool SubJobAtTopLevel =
5366 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5368 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5373 const char *BaseInput = InputInfos[0].getBaseInput();
5374 for (
auto &Info : InputInfos) {
5375 if (Info.isFilename()) {
5376 BaseInput = Info.getBaseInput();
5383 if (JA->
getType() == types::TY_dSYM)
5384 BaseInput = InputInfos[0].getFilename();
5387 if (!OffloadDependencesInputInfo.empty())
5388 InputInfos.append(OffloadDependencesInputInfo.begin(),
5389 OffloadDependencesInputInfo.end());
5392 llvm::Triple EffectiveTriple;
5394 const ArgList &Args =
5396 if (InputInfos.size() != 1) {
5400 EffectiveTriple = llvm::Triple(
5408 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5412 for (
auto &UI : UA->getDependentActionsInfo()) {
5414 "Unbundling with no offloading??");
5421 UI.DependentOffloadKind,
5422 UI.DependentToolChain->getTriple().normalize(),
5433 UnbundlingResults.push_back(CurI);
5442 Arch = UI.DependentBoundArch;
5447 UI.DependentOffloadKind)}] = {
5453 std::pair<const Action *, std::string> ActionTC = {
5455 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5456 "Result does not exist??");
5457 Result = CachedResults[ActionTC].front();
5458 }
else if (JA->
getType() == types::TY_Nothing)
5465 isa<OffloadPackagerJobAction>(A) ||
5469 AtTopLevel, MultipleArchs,
5476 <<
" - \"" << T->
getName() <<
"\", inputs: [";
5477 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5478 llvm::errs() << InputInfos[i].getAsString();
5480 llvm::errs() <<
", ";
5482 if (UnbundlingResults.empty())
5483 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5485 llvm::errs() <<
"], outputs: [";
5486 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5487 llvm::errs() << UnbundlingResults[i].getAsString();
5489 llvm::errs() <<
", ";
5491 llvm::errs() <<
"] \n";
5494 if (UnbundlingResults.empty())
5501 C, *JA, UnbundlingResults, InputInfos,
5509 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5510 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5522 if (ArgValue.empty()) {
5525 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
5527 llvm::sys::path::append(
Filename, BaseName);
5530 if (!llvm::sys::path::has_extension(ArgValue)) {
5534 if (FileType == types::TY_Image &&
5535 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5540 llvm::sys::path::replace_extension(
Filename, Extension);
5543 return Args.MakeArgString(
Filename.c_str());
5547 if (isa<PreprocessJobAction>(JA))
5549 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
g