54#include "clang/Config/config.h"
66#include "llvm/ADT/ArrayRef.h"
67#include "llvm/ADT/STLExtras.h"
68#include "llvm/ADT/StringExtras.h"
69#include "llvm/ADT/StringRef.h"
70#include "llvm/ADT/StringSet.h"
71#include "llvm/ADT/StringSwitch.h"
72#include "llvm/Config/llvm-config.h"
73#include "llvm/MC/TargetRegistry.h"
74#include "llvm/Option/Arg.h"
75#include "llvm/Option/ArgList.h"
76#include "llvm/Option/OptSpecifier.h"
77#include "llvm/Option/OptTable.h"
78#include "llvm/Option/Option.h"
79#include "llvm/Support/CommandLine.h"
80#include "llvm/Support/ErrorHandling.h"
81#include "llvm/Support/ExitCodes.h"
82#include "llvm/Support/FileSystem.h"
83#include "llvm/Support/FormatVariadic.h"
84#include "llvm/Support/MD5.h"
85#include "llvm/Support/Path.h"
86#include "llvm/Support/PrettyStackTrace.h"
87#include "llvm/Support/Process.h"
88#include "llvm/Support/Program.h"
89#include "llvm/Support/StringSaver.h"
90#include "llvm/Support/VirtualFileSystem.h"
91#include "llvm/Support/raw_ostream.h"
92#include "llvm/TargetParser/Host.h"
104using namespace clang;
108 const ArgList &Args) {
109 auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
113 switch (OffloadTargets.size()) {
115 D.
Diag(diag::err_drv_only_one_offload_target_supported);
118 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) <<
"";
123 return llvm::Triple(OffloadTargets[0]);
126static std::optional<llvm::Triple>
128 const llvm::Triple &HostTriple) {
129 if (!Args.hasArg(options::OPT_offload_EQ)) {
130 return llvm::Triple(HostTriple.isArch64Bit() ?
"nvptx64-nvidia-cuda"
131 :
"nvptx-nvidia-cuda");
134 if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
135 TT->getArch() == llvm::Triple::spirv64)) {
136 if (Args.hasArg(options::OPT_emit_llvm))
138 D.
Diag(diag::err_drv_cuda_offload_only_emit_bc);
141 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
144static std::optional<llvm::Triple>
146 if (!Args.hasArg(options::OPT_offload_EQ)) {
147 return llvm::Triple(
"amdgcn-amd-amdhsa");
152 if (TT->getArch() == llvm::Triple::amdgcn &&
153 TT->getVendor() == llvm::Triple::AMD &&
154 TT->getOS() == llvm::Triple::AMDHSA)
156 if (TT->getArch() == llvm::Triple::spirv64)
158 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
164 StringRef CustomResourceDir) {
170 std::string
Dir = std::string(llvm::sys::path::parent_path(BinaryPath));
173 if (CustomResourceDir !=
"") {
174 llvm::sys::path::append(
P, CustomResourceDir);
181 P = llvm::sys::path::parent_path(
Dir);
184 llvm::sys::path::append(
P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
185 CLANG_VERSION_MAJOR_STRING);
188 return std::string(
P.str());
194 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
195 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
198 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
199 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
200 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
201 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
202 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
203 CheckInputsExist(
true), ProbePrecompiled(
true),
204 SuppressMissingInputWarning(
false) {
207 this->VFS = llvm::vfs::getRealFileSystem();
213 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
216 llvm::sys::path::append(
P,
SysRoot);
220#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
223#if defined(CLANG_CONFIG_FILE_USER_DIR)
226 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
235void Driver::setDriverMode(StringRef
Value) {
236 static StringRef OptName =
237 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
238 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
239 .Case(
"gcc", GCCMode)
240 .Case(
"g++", GXXMode)
241 .Case(
"cpp", CPPMode)
243 .Case(
"flang", FlangMode)
244 .Case(
"dxc", DXCMode)
248 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
252 bool UseDriverMode,
bool &ContainsError) {
253 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
254 ContainsError =
false;
256 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
257 unsigned MissingArgIndex, MissingArgCount;
258 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
259 MissingArgCount, VisibilityMask);
262 if (MissingArgCount) {
263 Diag(diag::err_drv_missing_argument)
264 << Args.getArgString(MissingArgIndex) << MissingArgCount;
271 for (
const Arg *A : Args) {
273 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
281 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
282 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
284 diag::warn_drv_empty_joined_argument,
289 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
291 auto ArgString = A->getAsString(Args);
293 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
295 getOpts().findExact(ArgString, Nearest,
297 DiagID = diag::err_drv_unknown_argument_with_suggestion;
298 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
300 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
301 : diag::err_drv_unknown_argument;
302 Diags.
Report(DiagID) << ArgString;
306 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
307 : diag::err_drv_unknown_argument_with_suggestion;
308 Diags.
Report(DiagID) << ArgString << Nearest;
314 for (
const Arg *A : Args.filtered(options::OPT_o)) {
315 if (ArgStrings[A->getIndex()] == A->getSpelling())
319 std::string ArgString = ArgStrings[A->getIndex()];
321 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
322 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
323 << A->getAsString(Args) << Nearest;
333 Arg **FinalPhaseArg)
const {
334 Arg *PhaseArg =
nullptr;
338 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
339 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
340 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
341 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
348 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
349 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
350 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
351 options::OPT_fmodule_header_EQ))) {
354 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
355 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
356 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
357 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
359 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
360 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
361 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
362 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
366 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
370 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
373 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
381 *FinalPhaseArg = PhaseArg;
387 StringRef
Value,
bool Claim =
true) {
388 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
389 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
390 Args.AddSynthesizedArg(A);
396DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
397 const llvm::opt::OptTable &Opts =
getOpts();
398 DerivedArgList *DAL =
new DerivedArgList(Args);
400 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
401 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
402 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
403 bool IgnoreUnused =
false;
404 for (Arg *A : Args) {
408 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
412 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
413 IgnoreUnused =
false;
423 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
424 A->getOption().matches(options::OPT_Xlinker)) &&
425 A->containsValue(
"--no-demangle")) {
427 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
430 for (StringRef Val : A->getValues())
431 if (Val !=
"--no-demangle")
432 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
440 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
441 (A->getValue(0) == StringRef(
"-MD") ||
442 A->getValue(0) == StringRef(
"-MMD"))) {
444 if (A->getValue(0) == StringRef(
"-MD"))
445 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
447 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
448 if (A->getNumValues() == 2)
449 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
454 if (A->getOption().matches(options::OPT_l)) {
455 StringRef
Value = A->getValue();
458 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
460 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
465 if (
Value ==
"cc_kext") {
466 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
472 if (A->getOption().matches(options::OPT__DASH_DASH)) {
474 for (StringRef Val : A->getValues())
483 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
484 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
487 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
488 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
492#if defined(HOST_LINK_VERSION)
493 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
494 strlen(HOST_LINK_VERSION) > 0) {
495 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
497 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
509 StringRef TargetTriple,
511 StringRef DarwinArchName =
"") {
513 if (
const Arg *A = Args.getLastArg(options::OPT_target))
514 TargetTriple = A->getValue();
516 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
521 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
525 if (
Target.isOSBinFormatMachO()) {
527 if (!DarwinArchName.empty()) {
534 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
535 StringRef ArchName = A->getValue();
542 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
543 options::OPT_mbig_endian)) {
544 llvm::Triple T = A->getOption().matches(options::OPT_mlittle_endian)
545 ?
Target.getLittleEndianArchVariant()
546 :
Target.getBigEndianArchVariant();
547 if (T.getArch() != llvm::Triple::UnknownArch) {
549 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
554 if (
Target.getArch() == llvm::Triple::tce)
559 if (std::optional<std::string> ObjectModeValue =
560 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
561 StringRef ObjectMode = *ObjectModeValue;
562 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
564 if (ObjectMode.equals(
"64")) {
565 AT =
Target.get64BitArchVariant().getArch();
566 }
else if (ObjectMode.equals(
"32")) {
567 AT =
Target.get32BitArchVariant().getArch();
569 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
572 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
578 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
580 D.
Diag(diag::err_drv_unsupported_opt_for_target)
581 << A->getAsString(Args) <<
Target.str();
584 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
585 options::OPT_m32, options::OPT_m16,
586 options::OPT_maix32, options::OPT_maix64);
588 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
590 if (A->getOption().matches(options::OPT_m64) ||
591 A->getOption().matches(options::OPT_maix64)) {
592 AT =
Target.get64BitArchVariant().getArch();
593 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
594 Target.setEnvironment(llvm::Triple::GNU);
595 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
596 Target.setEnvironment(llvm::Triple::Musl);
597 }
else if (A->getOption().matches(options::OPT_mx32) &&
598 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
599 AT = llvm::Triple::x86_64;
600 if (
Target.getEnvironment() == llvm::Triple::Musl)
601 Target.setEnvironment(llvm::Triple::MuslX32);
603 Target.setEnvironment(llvm::Triple::GNUX32);
604 }
else if (A->getOption().matches(options::OPT_m32) ||
605 A->getOption().matches(options::OPT_maix32)) {
606 AT =
Target.get32BitArchVariant().getArch();
607 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
608 Target.setEnvironment(llvm::Triple::GNU);
609 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
610 Target.setEnvironment(llvm::Triple::Musl);
611 }
else if (A->getOption().matches(options::OPT_m16) &&
612 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
613 AT = llvm::Triple::x86;
614 Target.setEnvironment(llvm::Triple::CODE16);
617 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
619 if (
Target.isWindowsGNUEnvironment())
625 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
626 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
627 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
630 if (A && !A->getOption().matches(options::OPT_m32))
631 D.
Diag(diag::err_drv_argument_not_allowed_with)
632 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
634 Target.setArch(llvm::Triple::x86);
635 Target.setArchName(
"i586");
636 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
637 Target.setEnvironmentName(
"");
638 Target.setOS(llvm::Triple::ELFIAMCU);
639 Target.setVendor(llvm::Triple::UnknownVendor);
640 Target.setVendorName(
"intel");
646 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
647 StringRef ABIName = A->getValue();
648 if (ABIName ==
"32") {
650 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
651 Target.getEnvironment() == llvm::Triple::GNUABIN32)
652 Target.setEnvironment(llvm::Triple::GNU);
653 }
else if (ABIName ==
"n32") {
655 if (
Target.getEnvironment() == llvm::Triple::GNU ||
656 Target.getEnvironment() == llvm::Triple::GNUABI64)
657 Target.setEnvironment(llvm::Triple::GNUABIN32);
658 }
else if (ABIName ==
"64") {
660 if (
Target.getEnvironment() == llvm::Triple::GNU ||
661 Target.getEnvironment() == llvm::Triple::GNUABIN32)
662 Target.setEnvironment(llvm::Triple::GNUABI64);
670 if (Args.hasArg(options::OPT_march_EQ) ||
671 Args.hasArg(options::OPT_mcpu_EQ)) {
673 if (ArchName.starts_with_insensitive(
"rv32"))
674 Target.setArch(llvm::Triple::riscv32);
675 else if (ArchName.starts_with_insensitive(
"rv64"))
676 Target.setArch(llvm::Triple::riscv64);
687 OptSpecifier OptEq, OptSpecifier OptNeg) {
688 if (!Args.hasFlag(OptEq, OptNeg,
false))
691 const Arg *A = Args.getLastArg(OptEq);
692 StringRef LTOName = A->getValue();
700 D.
Diag(diag::err_drv_unsupported_option_argument)
701 << A->getSpelling() << A->getValue();
708void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
710 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
712 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
713 options::OPT_fno_offload_lto);
716 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
717 options::OPT_fno_openmp_target_jit,
false)) {
718 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
719 options::OPT_fno_offload_lto))
721 Diag(diag::err_drv_incompatible_options)
722 << A->getSpelling() <<
"-fopenmp-target-jit";
729 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
731 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
733 RuntimeName = A->getValue();
735 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
743 Diag(diag::err_drv_unsupported_option_argument)
744 << A->getSpelling() << A->getValue();
747 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
762 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
767 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
770 C.getInputArgs().hasArg(options::OPT_hip_link) ||
771 C.getInputArgs().hasArg(options::OPT_hipstdpar);
772 if (IsCuda && IsHIP) {
773 Diag(clang::diag::err_drv_mix_cuda_hip);
778 const llvm::Triple &HostTriple = HostTC->
getTriple();
786 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
788 CudaTC = std::make_unique<toolchains::CudaToolChain>(
789 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
794 if (CudaInstallation.
isValid())
797 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
799 if (
auto *OMPTargetArg =
800 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
801 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
802 << OMPTargetArg->getSpelling() <<
"HIP";
810 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
812 assert(HIPTC &&
"Could not create offloading device tool chain.");
813 C.addOffloadDeviceToolChain(HIPTC, OFK);
821 bool IsOpenMPOffloading =
822 C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
823 options::OPT_fno_openmp,
false) &&
824 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
825 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ));
826 if (IsOpenMPOffloading) {
832 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
836 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
837 llvm::StringMap<StringRef> FoundNormalizedTriples;
838 std::multiset<StringRef> OpenMPTriples;
843 if (Arg *OpenMPTargets =
844 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
845 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
846 Diag(clang::diag::warn_drv_empty_joined_argument)
847 << OpenMPTargets->getAsString(
C.getInputArgs());
850 for (StringRef T : OpenMPTargets->getValues())
851 OpenMPTriples.insert(T);
852 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
865 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
866 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
872 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
873 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
878 if (!AMDTriple && !NVPTXTriple) {
879 for (StringRef Arch :
884 for (StringRef Arch : Archs) {
887 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
888 }
else if (AMDTriple &&
891 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
893 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
900 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
905 for (
const auto &TripleAndArchs : DerivedArchs)
906 OpenMPTriples.insert(TripleAndArchs.first());
909 for (StringRef Val : OpenMPTriples) {
911 std::string NormalizedName = TT.normalize();
914 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
915 if (Duplicate != FoundNormalizedTriples.end()) {
916 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
917 << Val << Duplicate->second;
923 FoundNormalizedTriples[NormalizedName] = Val;
926 if (TT.getArch() == llvm::Triple::UnknownArch)
927 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
932 if (TT.isNVPTX() || TT.isAMDGCN()) {
935 assert(HostTC &&
"Host toolchain should be always defined.");
937 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
940 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
941 *
this, TT, *HostTC,
C.getInputArgs());
942 else if (TT.isAMDGCN())
943 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
944 *
this, TT, *HostTC,
C.getInputArgs());
946 assert(DeviceTC &&
"Device toolchain not defined.");
951 TC = &getToolChain(
C.getInputArgs(), TT);
953 if (DerivedArchs.contains(TT.getTriple()))
954 KnownArchs[TC] = DerivedArchs[TT.getTriple()];
957 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
958 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
968 const Arg *BaseArg) {
972 unsigned Index = Args.MakeIndex(Opt->getSpelling());
973 Arg *
Copy =
new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index),
975 Copy->getValues() = Opt->getValues();
976 if (Opt->isClaimed())
978 Copy->setOwnsValues(Opt->getOwnsValues());
979 Opt->setOwnsValues(
false);
983bool Driver::readConfigFile(StringRef
FileName,
984 llvm::cl::ExpansionContext &ExpCtx) {
988 Diag(diag::err_drv_cannot_open_config_file)
989 <<
FileName << Status.getError().message();
992 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
993 Diag(diag::err_drv_cannot_open_config_file)
994 <<
FileName <<
"not a regular file";
1000 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgArgs)) {
1001 Diag(diag::err_drv_cannot_read_config_file)
1008 llvm::sys::path::native(CfgFileName);
1010 std::unique_ptr<InputArgList> NewOptions = std::make_unique<InputArgList>(
1017 for (Arg *A : *NewOptions)
1021 CfgOptions = std::move(NewOptions);
1024 for (
auto *Opt : *NewOptions) {
1025 const Arg *BaseArg = &Opt->getBaseArg();
1031 ConfigFiles.push_back(std::string(CfgFileName));
1035bool Driver::loadConfigFiles() {
1036 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1037 llvm::cl::tokenizeConfigFile);
1038 ExpCtx.setVFS(&
getVFS());
1042 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1045 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1046 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1051 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1053 llvm::sys::fs::expand_tilde(
1054 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1055 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1064 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1067 if (loadDefaultConfigFiles(ExpCtx))
1073 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1076 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1077 CfgFilePath.assign(CfgFileName);
1078 if (llvm::sys::path::is_relative(CfgFilePath)) {
1079 if (
getVFS().makeAbsolute(CfgFilePath)) {
1080 Diag(diag::err_drv_cannot_open_config_file)
1081 << CfgFilePath <<
"cannot get absolute path";
1085 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1087 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1088 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1089 if (!SearchDir.empty())
1090 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1095 if (readConfigFile(CfgFilePath, ExpCtx))
1104bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1107 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1111 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1114 std::string RealMode = getExecutableForDriverMode(Mode);
1124 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1125 PrefixTriple.isOSUnknown())
1126 Triple = PrefixTriple.str();
1130 if (Triple.empty()) {
1131 llvm::Triple RealTriple =
1133 Triple = RealTriple.str();
1134 assert(!Triple.empty());
1149 std::string CfgFileName = Triple +
'-' + RealMode +
".cfg";
1150 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1151 return readConfigFile(CfgFilePath, ExpCtx);
1155 if (TryModeSuffix) {
1157 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1158 return readConfigFile(CfgFilePath, ExpCtx);
1163 CfgFileName = RealMode +
".cfg";
1164 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1165 if (readConfigFile(CfgFilePath, ExpCtx))
1167 }
else if (TryModeSuffix) {
1169 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1170 readConfigFile(CfgFilePath, ExpCtx))
1175 CfgFileName = Triple +
".cfg";
1176 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1177 return readConfigFile(CfgFilePath, ExpCtx);
1185 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1194 if (!DriverMode.empty())
1195 setDriverMode(DriverMode);
1201 CLOptions = std::make_unique<InputArgList>(
1206 ContainsError = loadConfigFiles();
1207 bool HasConfigFile = !ContainsError && (CfgOptions.get() !=
nullptr);
1210 InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
1211 : std::move(*CLOptions));
1214 for (
auto *Opt : *CLOptions) {
1215 if (Opt->getOption().matches(options::OPT_config))
1217 const Arg *BaseArg = &Opt->getBaseArg();
1224 if (
IsCLMode() && !ContainsError) {
1226 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1228 CLModePassThroughArgList.push_back(A->getValue());
1231 if (!CLModePassThroughArgList.empty()) {
1234 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1239 for (
auto *Opt : *CLModePassThroughOptions) {
1246 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1247 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1248 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1251 bool CCCPrintPhases;
1254 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1255 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1258 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1259 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1262 Args.ClaimAllArgs(options::OPT_pipe);
1270 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1272 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1273 CCCGenericGCCName = A->getValue();
1276 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1280 if (Args.hasArg(options::OPT_fproc_stat_report))
1287 llvm::Triple T(TargetTriple);
1288 T.setOS(llvm::Triple::Win32);
1289 T.setVendor(llvm::Triple::PC);
1290 T.setEnvironment(llvm::Triple::MSVC);
1291 T.setObjectFormat(llvm::Triple::COFF);
1292 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1293 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1294 TargetTriple = T.str();
1297 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1298 StringRef TargetProfile = A->getValue();
1301 TargetTriple = *Triple;
1303 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1308 if (Args.hasArg(options::OPT_spirv)) {
1309 llvm::Triple T(TargetTriple);
1310 T.setArch(llvm::Triple::spirv);
1311 TargetTriple = T.str();
1314 Diag(diag::err_drv_dxc_missing_target_profile);
1318 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1319 TargetTriple = A->getValue();
1320 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1322 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1326 if (std::optional<std::string> CompilerPathValue =
1327 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1328 StringRef CompilerPath = *CompilerPathValue;
1329 while (!CompilerPath.empty()) {
1330 std::pair<StringRef, StringRef> Split =
1331 CompilerPath.split(llvm::sys::EnvPathSeparator);
1332 PrefixDirs.push_back(std::string(Split.first));
1333 CompilerPath = Split.second;
1336 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1338 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1341 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1344 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1345 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1346 .Case(
"cwd", SaveTempsCwd)
1347 .Case(
"obj", SaveTempsObj)
1348 .Default(SaveTempsCwd);
1351 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1352 options::OPT_offload_device_only,
1353 options::OPT_offload_host_device)) {
1354 if (A->getOption().matches(options::OPT_offload_host_only))
1355 Offload = OffloadHost;
1356 else if (A->getOption().matches(options::OPT_offload_device_only))
1357 Offload = OffloadDevice;
1359 Offload = OffloadHostDevice;
1365 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1366 StringRef
Name = A->getValue();
1367 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1368 .Case(
"off", EmbedNone)
1369 .Case(
"all", EmbedBitcode)
1370 .Case(
"bitcode", EmbedBitcode)
1371 .Case(
"marker", EmbedMarker)
1374 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1377 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1381 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1382 llvm::sys::fs::remove(A->getValue());
1388 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1390 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1391 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1392 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1393 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1394 Std->containsValue(
"c++latest"));
1397 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1398 options::OPT_fmodule_header)) {
1400 ModulesModeCXX20 =
true;
1401 if (A->getOption().matches(options::OPT_fmodule_header))
1404 StringRef ArgName = A->getValue();
1405 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1410 Diags.
Report(diag::err_drv_invalid_value)
1411 << A->getAsString(Args) << ArgName;
1417 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1418 std::make_unique<InputArgList>(std::move(Args));
1421 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1428 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1429 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1430 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1438 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1439 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1441 case llvm::Triple::arm:
1442 case llvm::Triple::armeb:
1443 case llvm::Triple::thumb:
1444 case llvm::Triple::thumbeb:
1445 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1446 Diag(diag::warn_target_unrecognized_env)
1448 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1451 case llvm::Triple::aarch64:
1452 case llvm::Triple::aarch64_be:
1453 case llvm::Triple::aarch64_32:
1454 if (TC.
getTriple().getEnvironmentName().startswith(
"eabi")) {
1455 Diag(diag::warn_target_unrecognized_env)
1457 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1474 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1481 if (TC.
getTriple().isOSBinFormatMachO())
1486 if (CCCPrintPhases) {
1497 llvm::opt::ArgStringList ASL;
1498 for (
const auto *A : Args) {
1502 while (A->getAlias())
1504 A->render(Args, ASL);
1507 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1508 if (I != ASL.begin())
1510 llvm::sys::printArg(OS, *I,
true);
1515bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1517 using namespace llvm::sys;
1518 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1519 "Only knows about .crash files on Darwin");
1524 path::home_directory(CrashDiagDir);
1525 if (CrashDiagDir.startswith(
"/var/root"))
1527 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1535 fs::file_status FileStatus;
1536 TimePoint<> LastAccessTime;
1540 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1541 File != FileEnd && !EC;
File.increment(EC)) {
1545 if (fs::status(
File->path(), FileStatus))
1547 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1548 llvm::MemoryBuffer::getFile(
File->path());
1553 StringRef
Data = CrashFile.get()->getBuffer();
1554 if (!
Data.startswith(
"Process:"))
1557 size_t ParentProcPos =
Data.find(
"Parent Process:");
1558 if (ParentProcPos == StringRef::npos)
1560 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1561 if (LineEnd == StringRef::npos)
1563 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1564 int OpenBracket = -1, CloseBracket = -1;
1565 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1566 if (ParentProcess[i] ==
'[')
1568 if (ParentProcess[i] ==
']')
1574 if (OpenBracket < 0 || CloseBracket < 0 ||
1575 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1576 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1586 const auto FileAccessTime = FileStatus.getLastModificationTime();
1587 if (FileAccessTime > LastAccessTime) {
1588 CrashFilePath.assign(
File->path());
1589 LastAccessTime = FileAccessTime;
1594 if (!CrashFilePath.empty()) {
1595 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1605 "\n********************\n\n"
1606 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1607 "Preprocessed source(s) and associated run script(s) are located at:";
1615 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1619 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1620 Level = llvm::StringSwitch<unsigned>(A->getValue())
1622 .Case(
"compiler", 1)
1634 ArgStringList SavedTemps;
1636 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1637 if (!IsLLD || Level < 2)
1644 SavedTemps = std::move(
C.getTempFiles());
1645 assert(!
C.getTempFiles().size());
1662 C.initCompilationForDiagnostics();
1668 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1669 StringRef ReproduceOption =
1670 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1673 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1677 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1679 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1680 Diag(clang::diag::note_drv_command_failed_diag_msg)
1681 <<
"\n\n********************";
1691 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1692 bool IgnoreInput =
false;
1698 }
else if (!strcmp(it->second->getValue(),
"-")) {
1699 Diag(clang::diag::note_drv_command_failed_diag_msg)
1700 <<
"Error generating preprocessed source(s) - "
1701 "ignoring input from stdin.";
1706 it = Inputs.erase(it);
1713 if (Inputs.empty()) {
1714 Diag(clang::diag::note_drv_command_failed_diag_msg)
1715 <<
"Error generating preprocessed source(s) - "
1716 "no preprocessable inputs.";
1722 llvm::StringSet<> ArchNames;
1723 for (
const Arg *A :
C.getArgs()) {
1724 if (A->getOption().matches(options::OPT_arch)) {
1725 StringRef ArchName = A->getValue();
1726 ArchNames.insert(ArchName);
1729 if (ArchNames.size() > 1) {
1730 Diag(clang::diag::note_drv_command_failed_diag_msg)
1731 <<
"Error generating preprocessed source(s) - cannot generate "
1732 "preprocessed source with multiple -arch options.";
1738 const ToolChain &TC =
C.getDefaultToolChain();
1739 if (TC.
getTriple().isOSBinFormatMachO())
1748 Diag(clang::diag::note_drv_command_failed_diag_msg)
1749 <<
"Error generating preprocessed source(s).";
1755 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1758 if (!FailingCommands.empty()) {
1759 Diag(clang::diag::note_drv_command_failed_diag_msg)
1760 <<
"Error generating preprocessed source(s).";
1764 const ArgStringList &TempFiles =
C.getTempFiles();
1765 if (TempFiles.empty()) {
1766 Diag(clang::diag::note_drv_command_failed_diag_msg)
1767 <<
"Error generating preprocessed source(s).";
1775 for (
const char *TempFile : TempFiles) {
1776 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
1779 if (ReproCrashFilename.empty()) {
1780 ReproCrashFilename = TempFile;
1781 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
1783 if (StringRef(TempFile).endswith(
".cache")) {
1786 VFS = llvm::sys::path::filename(TempFile);
1787 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
1791 for (
const char *TempFile : SavedTemps)
1792 C.addTempFile(TempFile);
1798 llvm::sys::path::replace_extension(Script,
"sh");
1800 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
1801 llvm::sys::fs::FA_Write,
1802 llvm::sys::fs::OF_Text);
1804 Diag(clang::diag::note_drv_command_failed_diag_msg)
1805 <<
"Error generating run script: " << Script <<
" " << EC.message();
1808 <<
"# Driver args: ";
1810 ScriptOS <<
"# Original command: ";
1811 Cmd.Print(ScriptOS,
"\n",
true);
1812 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
1813 if (!AdditionalInformation.empty())
1814 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
1818 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
1822 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
1824 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
1825 Diag(clang::diag::note_drv_command_failed_diag_msg)
1826 << ReproCrashFilename.str();
1828 llvm::sys::path::append(CrashDiagDir,
Name);
1829 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
1830 Diag(clang::diag::note_drv_command_failed_diag_msg)
1831 <<
"Crash backtrace is located in";
1832 Diag(clang::diag::note_drv_command_failed_diag_msg)
1833 << CrashDiagDir.str();
1834 Diag(clang::diag::note_drv_command_failed_diag_msg)
1835 <<
"(choose the .crash file that corresponds to your crash)";
1839 Diag(clang::diag::note_drv_command_failed_diag_msg)
1840 <<
"\n\n********************";
1848 if (
Cmd.getResponseFileSupport().ResponseKind ==
1850 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
1851 Cmd.getArguments()))
1855 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
1861 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
1862 if (
C.getArgs().hasArg(options::OPT_v))
1863 C.getJobs().Print(llvm::errs(),
"\n",
true);
1865 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
1875 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
1876 C.getJobs().Print(llvm::errs(),
"\n",
true);
1885 for (
auto &Job :
C.getJobs())
1886 setUpResponseFiles(
C, Job);
1888 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1891 if (FailingCommands.empty())
1897 for (
const auto &CmdPair : FailingCommands) {
1898 int CommandRes = CmdPair.first;
1899 const Command *FailingCommand = CmdPair.second;
1904 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
1908 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
1913 if (CommandRes == EX_IOERR) {
1930 Diag(clang::diag::err_drv_command_signalled)
1933 Diag(clang::diag::err_drv_command_failed)
1941 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
1943 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
1957 const ToolChain &TC =
C.getDefaultToolChain();
1961 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
1964 OS <<
"Thread model: " << A->getValue();
1973 for (
auto ConfigFile : ConfigFiles)
1974 OS <<
"Configuration file: " << ConfigFile <<
'\n';
1987 if (PassedFlags ==
"")
1991 std::vector<std::string> SuggestedCompletions;
1992 std::vector<std::string> Flags;
2004 const bool HasSpace = PassedFlags.endswith(
",");
2008 StringRef TargetFlags = PassedFlags;
2009 while (TargetFlags !=
"") {
2011 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2012 Flags.push_back(std::string(CurFlag));
2017 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2020 const llvm::opt::OptTable &Opts =
getOpts();
2022 Cur = Flags.at(Flags.size() - 1);
2024 if (Flags.size() >= 2) {
2025 Prev = Flags.at(Flags.size() - 2);
2026 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2029 if (SuggestedCompletions.empty())
2030 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2037 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2038 llvm::outs() <<
'\n';
2044 if (SuggestedCompletions.empty() && !Cur.endswith(
"=")) {
2048 SuggestedCompletions = Opts.findByPrefix(
2049 Cur, VisibilityMask,
2056 if (S.startswith(Cur))
2057 SuggestedCompletions.push_back(std::string(S));
2064 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2065 if (
int X = A.compare_insensitive(B))
2067 return A.compare(B) > 0;
2070 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2077 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2078 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2082 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2085 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2089 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2094 if (
C.getArgs().hasArg(options::OPT_help) ||
2095 C.getArgs().hasArg(options::OPT__help_hidden)) {
2096 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2100 if (
C.getArgs().hasArg(options::OPT__version)) {
2106 if (
C.getArgs().hasArg(options::OPT_v) ||
2107 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2108 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2109 C.getArgs().hasArg(options::OPT_print_supported_extensions)) {
2111 SuppressMissingInputWarning =
true;
2114 if (
C.getArgs().hasArg(options::OPT_v)) {
2116 llvm::errs() <<
"System configuration file directory: "
2119 llvm::errs() <<
"User configuration file directory: "
2123 const ToolChain &TC =
C.getDefaultToolChain();
2125 if (
C.getArgs().hasArg(options::OPT_v))
2128 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2133 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2134 llvm::outs() <<
"programs: =";
2135 bool separator =
false;
2139 llvm::outs() << llvm::sys::EnvPathSeparator;
2140 llvm::outs() << Path;
2145 llvm::outs() << llvm::sys::EnvPathSeparator;
2146 llvm::outs() << Path;
2149 llvm::outs() <<
"\n";
2152 StringRef sysroot =
C.getSysRoot();
2156 llvm::outs() << llvm::sys::EnvPathSeparator;
2159 llvm::outs() << sysroot << Path.substr(1);
2161 llvm::outs() << Path;
2163 llvm::outs() <<
"\n";
2167 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2168 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2169 llvm::outs() << *RuntimePath <<
'\n';
2175 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2177 for (std::size_t I = 0; I != Flags.size(); I += 2)
2178 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2184 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2185 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2189 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2190 StringRef ProgName = A->getValue();
2193 if (! ProgName.empty())
2196 llvm::outs() <<
"\n";
2200 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2201 StringRef PassedFlags = A->getValue();
2206 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2212 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2215 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2221 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2227 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2230 std::set<llvm::StringRef> SortedFlags;
2231 for (
const auto &FlagEntry : ExpandedFlags)
2232 SortedFlags.insert(FlagEntry.getKey());
2233 for (
auto Flag : SortedFlags)
2234 llvm::outs() << Flag <<
'\n';
2238 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2241 llvm::outs() <<
".\n";
2244 assert(Suffix.front() ==
'/');
2245 llvm::outs() << Suffix.substr(1) <<
"\n";
2251 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2256 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2258 llvm::outs() << Triple.getTriple() <<
"\n";
2262 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2263 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2280 std::map<Action *, unsigned> &Ids,
2286 llvm::raw_string_ostream os(str);
2288 auto getSibIndent = [](
int K) -> Twine {
2292 Twine SibIndent = Indent + getSibIndent(Kind);
2296 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2298 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2299 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2300 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2301 bool IsFirst =
true;
2302 OA->doOnEachDependence(
2304 assert(TC &&
"Unknown host toolchain");
2316 os <<
":" << BoundArch;
2319 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2327 const char *Prefix =
"{";
2328 for (
Action *PreRequisite : *AL) {
2329 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2340 std::string offload_str;
2341 llvm::raw_string_ostream offload_os(offload_str);
2342 if (!isa<OffloadAction>(A)) {
2345 offload_os <<
", (" << S;
2352 auto getSelfIndent = [](
int K) -> Twine {
2356 unsigned Id = Ids.size();
2358 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2367 std::map<Action *, unsigned> Ids;
2368 for (
Action *A :
C.getActions())
2375 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2376 isa<AssembleJobAction>(A))
2384 DerivedArgList &Args =
C.getArgs();
2386 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2389 llvm::StringSet<> ArchNames;
2391 for (Arg *A : Args) {
2392 if (A->getOption().matches(options::OPT_arch)) {
2395 llvm::Triple::ArchType Arch =
2397 if (Arch == llvm::Triple::UnknownArch) {
2398 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2403 if (ArchNames.insert(A->getValue()).second)
2404 Archs.push_back(A->getValue());
2418 for (
Action* Act : SingleActions) {
2426 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2430 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2435 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2436 Actions.append(Inputs.begin(), Inputs.end());
2438 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2441 Arg *A = Args.getLastArg(options::OPT_g_Group);
2442 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2443 !A->getOption().matches(options::OPT_gstabs);
2451 if (Act->getType() == types::TY_Image) {
2453 Inputs.push_back(Actions.back());
2460 if (Args.hasArg(options::OPT_verify_debug_info)) {
2461 Action* LastAction = Actions.back();
2464 LastAction, types::TY_Nothing));
2483 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2484 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2496 std::string Nearest;
2497 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2498 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2499 <<
Value << Nearest;
2538 if (
IsCLMode() && Ty == types::TY_Object && !
Value.startswith(
"/"))
2541 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2549 return types::TY_CXXUHeader;
2551 return types::TY_CXXSHeader;
2555 llvm_unreachable(
"should not be called in this case");
2557 return types::TY_CXXHUHeader;
2563 const llvm::opt::OptTable &Opts =
getOpts();
2567 types::ID InputType = types::TY_Nothing;
2568 Arg *InputTypeArg =
nullptr;
2571 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2572 options::OPT__SLASH_TP)) {
2573 InputTypeArg = TCTP;
2574 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2579 bool ShowNote =
false;
2581 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2583 Diag(clang::diag::warn_drv_overriding_option)
2584 <<
Previous->getSpelling() << A->getSpelling();
2590 Diag(clang::diag::note_drv_t_option_is_global);
2595 auto LastXArg = Args.getLastArgValue(options::OPT_x);
2596 const llvm::StringSet<> ValidXArgs = {
"cuda",
"hip",
"cui",
"hipi"};
2597 if (!
IsCLMode() || ValidXArgs.contains(LastXArg)) {
2598 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2599 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2600 if (LastXArg && LastInputArg &&
2601 LastInputArg->getIndex() < LastXArg->getIndex())
2602 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2606 if (
auto *A = Args.getLastArg(options::OPT_x))
2607 Diag(diag::err_drv_unsupported_opt_with_suggestion)
2608 << A->getAsString(Args) <<
"/TC' or '/TP";
2611 for (Arg *A : Args) {
2612 if (A->getOption().
getKind() == Option::InputClass) {
2613 const char *
Value = A->getValue();
2617 if (InputType == types::TY_Nothing) {
2620 InputTypeArg->claim();
2623 if (memcmp(
Value,
"-", 2) == 0) {
2625 Ty = types::TY_Fortran;
2627 Ty = types::TY_HLSL;
2636 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2637 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2638 : clang::diag::err_drv_unknown_stdin_type);
2647 if (
const char *Ext = strrchr(
Value,
'.'))
2656 Ty = types::TY_Object;
2667 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2668 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2669 << getTypeName(OldTy) << getTypeName(Ty);
2674 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2675 Ty == types::TY_Object)
2676 Ty = types::TY_LLVM_BC;
2684 if (Ty != types::TY_Object) {
2685 if (Args.hasArg(options::OPT_ObjC))
2686 Ty = types::TY_ObjC;
2687 else if (Args.hasArg(options::OPT_ObjCXX))
2688 Ty = types::TY_ObjCXX;
2695 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
2699 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2700 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2703 const char *Ext = strrchr(
Value,
'.');
2705 Ty = types::TY_Object;
2709 InputTypeArg->claim();
2713 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
2714 Args.hasArgNoClaim(options::OPT_hipstdpar))
2718 Inputs.push_back(std::make_pair(Ty, A));
2720 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2721 StringRef
Value = A->getValue();
2724 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2725 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2728 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2729 StringRef
Value = A->getValue();
2732 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2733 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2739 Inputs.push_back(std::make_pair(types::TY_Object, A));
2741 }
else if (A->getOption().matches(options::OPT_x)) {
2750 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2751 InputType = types::TY_Object;
2758 }
else if (A->getOption().getID() == options::OPT_U) {
2759 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
2760 StringRef Val = A->getValue(0);
2761 if (Val.find_first_of(
"/\\") != StringRef::npos) {
2763 Diag(diag::warn_slash_u_filename) << Val;
2764 Diag(diag::note_use_dashdash);
2768 if (
CCCIsCPP() && Inputs.empty()) {
2772 Inputs.push_back(std::make_pair(types::TY_C, A));
2779class OffloadingActionBuilder final {
2781 bool IsValid =
false;
2787 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
2790 std::map<Action *, const Arg *> HostActionToInputArgMap;
2793 class DeviceActionBuilder {
2797 enum ActionBuilderReturnCode {
2816 DerivedArgList &Args;
2825 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
2828 :
C(
C), Args(Args), Inputs(Inputs),
2829 AssociatedOffloadKind(AssociatedOffloadKind) {}
2830 virtual ~DeviceActionBuilder() {}
2835 virtual ActionBuilderReturnCode
2839 return ABRT_Inactive;
2844 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
2845 return ABRT_Inactive;
2849 virtual void appendTopLevelActions(
ActionList &AL) {}
2852 virtual void appendLinkDeviceActions(
ActionList &AL) {}
2865 virtual bool canUseBundlerUnbundler()
const {
return false; }
2869 bool isValid() {
return !ToolChains.empty(); }
2873 return AssociatedOffloadKind;
2879 class CudaActionBuilderBase :
public DeviceActionBuilder {
2883 bool CompileHostOnly =
false;
2884 bool CompileDeviceOnly =
false;
2886 bool EmitAsm =
false;
2896 TargetID(
const char *
ID) :
ID(
ID) {}
2897 operator const char *() {
return ID; }
2898 operator StringRef() {
return StringRef(
ID); }
2907 Action *CudaFatBinary =
nullptr;
2910 bool IsActive =
false;
2913 bool Relocatable =
false;
2916 CudaArch DefaultCudaArch = CudaArch::UNKNOWN;
2920 enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
2921 UseCUIDKind UseCUID = CUID_Hash;
2924 StringRef FixedCUID;
2927 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
2930 : DeviceActionBuilder(
C, Args, Inputs, OFKind) {
2932 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
2933 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
2934 options::OPT_fno_gpu_rdc,
false);
2937 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
2944 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
2945 assert(!GpuArchList.empty() &&
2946 "We should have at least one GPU architecture.");
2950 if (!(IA->getType() == types::TY_CUDA ||
2951 IA->getType() == types::TY_HIP ||
2952 IA->getType() == types::TY_PP_HIP)) {
2955 return ABRT_Inactive;
2961 if (CompileHostOnly)
2962 return ABRT_Success;
2965 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
2966 : types::TY_CUDA_DEVICE;
2967 std::string CUID = FixedCUID.str();
2969 if (UseCUID == CUID_Random)
2970 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
2972 else if (UseCUID == CUID_Hash) {
2974 llvm::MD5::MD5Result Hash;
2976 llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
2978 Hasher.update(RealPath);
2979 for (
auto *A : Args) {
2980 if (A->getOption().matches(options::OPT_INPUT))
2982 Hasher.update(A->getAsString(Args));
2985 CUID = llvm::utohexstr(Hash.low(),
true);
2990 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
2991 CudaDeviceActions.push_back(
2992 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
2995 return ABRT_Success;
2999 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3003 if (UA->getType() == types::TY_Object && !Relocatable)
3004 return ABRT_Inactive;
3006 CudaDeviceActions.clear();
3007 auto *IA = cast<InputAction>(UA->getInputs().back());
3008 std::string
FileName = IA->getInputArg().getAsString(Args);
3014 const StringRef LibFileExt =
".lib";
3015 if (IA->getType() == types::TY_Object &&
3016 (!llvm::sys::path::has_extension(
FileName) ||
3018 llvm::sys::path::extension(
FileName).drop_front()) !=
3020 llvm::sys::path::extension(
FileName) == LibFileExt))
3021 return ABRT_Inactive;
3023 for (
auto Arch : GpuArchList) {
3024 CudaDeviceActions.push_back(UA);
3025 UA->registerDependentActionInfo(ToolChains[0], Arch,
3026 AssociatedOffloadKind);
3029 return ABRT_Success;
3032 return IsActive ? ABRT_Success : ABRT_Inactive;
3035 void appendTopLevelActions(
ActionList &AL)
override {
3037 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3039 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3044 if (CudaFatBinary) {
3045 AddTopLevel(CudaFatBinary, CudaArch::UNUSED);
3046 CudaDeviceActions.clear();
3047 CudaFatBinary =
nullptr;
3051 if (CudaDeviceActions.empty())
3057 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3058 "Expecting one action per GPU architecture.");
3059 assert(ToolChains.size() == 1 &&
3060 "Expecting to have a single CUDA toolchain.");
3061 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3062 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3064 CudaDeviceActions.clear();
3069 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3071 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3089 assert(HostTC &&
"No toolchain for host compilation.");
3091 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3095 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3100 ToolChains.push_back(
3105 CompileHostOnly =
C.getDriver().offloadHostOnly();
3106 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3107 EmitAsm = Args.getLastArg(options::OPT_S);
3108 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3109 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3110 StringRef UseCUIDStr = A->getValue();
3111 UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3112 .Case(
"hash", CUID_Hash)
3113 .Case(
"random", CUID_Random)
3114 .Case(
"none", CUID_None)
3115 .Default(CUID_Invalid);
3116 if (UseCUID == CUID_Invalid) {
3117 C.getDriver().Diag(diag::err_drv_invalid_value)
3118 << A->getAsString(Args) << UseCUIDStr;
3119 C.setContainsError();
3125 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3126 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3127 options::OPT_no_offload_arch_EQ)) {
3128 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3133 std::set<StringRef> GpuArchs;
3135 for (Arg *A : Args) {
3136 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3137 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3141 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3142 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3145 }
else if (ArchStr ==
"native") {
3146 const ToolChain &TC = *ToolChains.front();
3147 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3150 << llvm::Triple::getArchTypeName(TC.
getArch())
3151 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3155 for (
auto GPU : *GPUsOrErr) {
3156 GpuArchs.insert(Args.MakeArgString(GPU));
3159 ArchStr = getCanonicalOffloadArch(ArchStr);
3160 if (ArchStr.empty()) {
3162 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3163 GpuArchs.insert(ArchStr);
3164 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3165 GpuArchs.erase(ArchStr);
3167 llvm_unreachable(
"Unexpected option.");
3173 if (ConflictingArchs) {
3174 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3175 << ConflictingArchs->first << ConflictingArchs->second;
3176 C.setContainsError();
3181 for (
auto Arch : GpuArchs)
3182 GpuArchList.push_back(Arch.data());
3187 if (GpuArchList.empty()) {
3188 if (ToolChains.front()->getTriple().isSPIRV())
3189 GpuArchList.push_back(CudaArch::Generic);
3191 GpuArchList.push_back(DefaultCudaArch);
3200 class CudaActionBuilder final :
public CudaActionBuilderBase {
3202 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3204 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3205 DefaultCudaArch = CudaArch::SM_35;
3208 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3211 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3217 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3219 const std::set<StringRef> &GpuArchs)
override {
3220 return std::nullopt;
3223 ActionBuilderReturnCode
3226 PhasesTy &Phases)
override {
3228 return ABRT_Inactive;
3232 if (CudaDeviceActions.empty())
3233 return ABRT_Success;
3235 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3236 "Expecting one action per GPU architecture.");
3237 assert(!CompileHostOnly &&
3238 "Not expecting CUDA actions in host-only compilation.");
3248 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3251 for (
auto Ph : Phases) {
3256 if (Ph > FinalPhase)
3259 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3269 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3273 Action *AssembleAction = CudaDeviceActions[I];
3274 assert(AssembleAction->
getType() == types::TY_Object);
3275 assert(AssembleAction->
getInputs().size() == 1);
3283 DeviceActions.push_back(
3289 if (!DeviceActions.empty()) {
3291 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3293 if (!CompileDeviceOnly) {
3294 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3298 CudaFatBinary =
nullptr;
3303 CudaDeviceActions.clear();
3307 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3312 return ABRT_Success;
3316 "instructions should only occur "
3317 "before the backend phase!");
3320 for (
Action *&A : CudaDeviceActions)
3321 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3323 return ABRT_Success;
3328 class HIPActionBuilder final :
public CudaActionBuilderBase {
3336 std::optional<bool> BundleOutput;
3337 std::optional<bool> EmitReloc;
3342 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3344 DefaultCudaArch = CudaArch::GFX906;
3346 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3347 options::OPT_fno_hip_emit_relocatable)) {
3348 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3349 options::OPT_fno_hip_emit_relocatable,
false);
3353 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3354 <<
"-fhip-emit-relocatable"
3358 if (!CompileDeviceOnly) {
3359 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3360 <<
"-fhip-emit-relocatable"
3361 <<
"--cuda-device-only";
3366 if (Args.hasArg(options::OPT_gpu_bundle_output,
3367 options::OPT_no_gpu_bundle_output))
3368 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3369 options::OPT_no_gpu_bundle_output,
true) &&
3370 (!EmitReloc || !*EmitReloc);
3373 bool canUseBundlerUnbundler()
const override {
return true; }
3375 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3376 llvm::StringMap<bool> Features;
3383 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3384 C.setContainsError();
3388 return Args.MakeArgStringRef(CanId);
3391 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3393 const std::set<StringRef> &GpuArchs)
override {
3397 ActionBuilderReturnCode
3400 PhasesTy &Phases)
override {
3402 return ABRT_Inactive;
3408 if (CudaDeviceActions.empty())
3409 return ABRT_Success;
3412 CudaDeviceActions.size() == GpuArchList.size()) &&
3413 "Expecting one action per GPU architecture.");
3414 assert(!CompileHostOnly &&
3415 "Not expecting HIP actions in host-only compilation.");
3417 bool ShouldLink = !EmitReloc || !*EmitReloc;
3420 !EmitAsm && ShouldLink) {
3426 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3427 if (
C.getDriver().isUsingLTO(
true)) {
3431 AL.push_back(CudaDeviceActions[I]);
3434 CudaDeviceActions[I] =
3441 if (ToolChains.front()->getTriple().isSPIRV()) {
3444 types::ID Output = Args.hasArg(options::OPT_S)
3446 : types::TY_LLVM_BC;
3452 AssociatedOffloadKind);
3453 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3455 AssociatedOffloadKind);
3456 AL.push_back(AssembleAction);
3459 CudaDeviceActions[I] =
3470 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3471 AssociatedOffloadKind);
3473 DDep, CudaDeviceActions[I]->getType());
3476 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3479 types::TY_HIP_FATBIN);
3481 if (!CompileDeviceOnly) {
3482 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3483 AssociatedOffloadKind);
3486 CudaFatBinary =
nullptr;
3491 CudaDeviceActions.clear();
3494 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3497 return ABRT_Success;
3503 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3504 auto LI = DeviceLinkerInputs.begin();
3505 for (
auto *A : CudaDeviceActions) {
3512 CudaDeviceActions.clear();
3513 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3517 for (
Action *&A : CudaDeviceActions)
3518 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3519 AssociatedOffloadKind);
3521 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3523 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3525 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3526 AssociatedOffloadKind);
3528 DDep, CudaDeviceActions[I]->getType());
3532 CudaDeviceActions.clear();
3535 return (CompileDeviceOnly &&
3536 (CurPhase == FinalPhase ||
3542 void appendLinkDeviceActions(
ActionList &AL)
override {
3543 if (DeviceLinkerInputs.size() == 0)
3546 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3547 "Linker inputs and GPU arch list sizes do not match.");
3553 for (
auto &LI : DeviceLinkerInputs) {
3555 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3559 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3563 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3564 GpuArchList[I], AssociatedOffloadKind);
3566 DeviceLinkDeps, DeviceLinkAction->getType()));
3569 DeviceLinkerInputs.clear();
3572 if (Args.hasArg(options::OPT_emit_llvm)) {
3581 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3584 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3585 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3586 AssociatedOffloadKind);
3589 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3595 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3611 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3619 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3622 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3630 unsigned ValidBuilders = 0u;
3631 unsigned ValidBuildersSupportingBundling = 0u;
3632 for (
auto *SB : SpecializedBuilders) {
3633 IsValid = IsValid && !SB->initialize();
3636 if (SB->isValid()) {
3638 if (SB->canUseBundlerUnbundler())
3639 ++ValidBuildersSupportingBundling;
3643 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3646 ~OffloadingActionBuilder() {
3647 for (
auto *SB : SpecializedBuilders)
3652 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3653 assert(HostAction &&
"Invalid host action");
3654 assert(InputArg &&
"Invalid input argument");
3655 auto Loc = HostActionToInputArgMap.find(HostAction);
3656 if (Loc == HostActionToInputArgMap.end())
3657 HostActionToInputArgMap[HostAction] = InputArg;
3658 assert(HostActionToInputArgMap[HostAction] == InputArg &&
3659 "host action mapped to multiple input arguments");
3667 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3669 DeviceActionBuilder::PhasesTy &Phases) {
3673 if (SpecializedBuilders.empty())
3676 assert(HostAction &&
"Invalid host action!");
3677 recordHostAction(HostAction, InputArg);
3682 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3683 unsigned InactiveBuilders = 0u;
3684 unsigned IgnoringBuilders = 0u;
3685 for (
auto *SB : SpecializedBuilders) {
3686 if (!SB->isValid()) {
3691 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3696 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3701 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3702 OffloadKind |= SB->getAssociatedOffloadKind();
3707 if (IgnoringBuilders &&
3708 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3725 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3726 const Arg *InputArg) {
3730 recordHostAction(HostAction, InputArg);
3738 if (CanUseBundler && isa<InputAction>(HostAction) &&
3739 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3741 HostAction->
getType() == types::TY_PP_HIP)) {
3742 auto UnbundlingHostAction =
3747 HostAction = UnbundlingHostAction;
3748 recordHostAction(HostAction, InputArg);
3751 assert(HostAction &&
"Invalid host action!");
3754 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3755 for (
auto *SB : SpecializedBuilders) {
3759 auto RetCode = SB->addDeviceDependences(HostAction);
3763 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3764 "Host dependence not expected to be ignored.!");
3768 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3769 OffloadKind |= SB->getAssociatedOffloadKind();
3774 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
3784 const Arg *InputArg) {
3786 recordHostAction(HostAction, InputArg);
3790 for (
auto *SB : SpecializedBuilders) {
3793 SB->appendTopLevelActions(OffloadAL);
3800 if (CanUseBundler && HostAction &&
3801 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
3803 OffloadAL.push_back(HostAction);
3807 assert(HostAction == AL.back() &&
"Host action not in the list??");
3809 recordHostAction(HostAction, InputArg);
3810 AL.back() = HostAction;
3812 AL.append(OffloadAL.begin(), OffloadAL.end());
3822 void appendDeviceLinkActions(
ActionList &AL) {
3823 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3826 SB->appendLinkDeviceActions(AL);
3830 Action *makeHostLinkAction() {
3833 appendDeviceLinkActions(DeviceAL);
3834 if (DeviceAL.empty())
3839 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3842 HA = SB->appendLinkHostActions(DeviceAL);
3859 for (
auto *SB : SpecializedBuilders) {
3863 SB->appendLinkDependences(DDeps);
3867 unsigned ActiveOffloadKinds = 0u;
3868 for (
auto &I : InputArgToOffloadKindMap)
3869 ActiveOffloadKinds |= I.second;
3881 for (
auto *A : HostAction->
inputs()) {
3882 auto ArgLoc = HostActionToInputArgMap.find(A);
3883 if (ArgLoc == HostActionToInputArgMap.end())
3885 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
3886 if (OFKLoc == InputArgToOffloadKindMap.end())
3898 nullptr, ActiveOffloadKinds);
3904void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
3905 const InputList &Inputs,
3909 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3910 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3911 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3912 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3913 Args.eraseArg(options::OPT__SLASH_Yc);
3914 Args.eraseArg(options::OPT__SLASH_Yu);
3915 YcArg = YuArg =
nullptr;
3917 if (YcArg && Inputs.size() > 1) {
3918 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3919 Args.eraseArg(options::OPT__SLASH_Yc);
3927 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
3928 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
3929 Args.AddFlagArg(
nullptr,
3930 getOpts().getOption(options::OPT_frtlib_add_rpath));
3933 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
3934 Diag(clang::diag::err_drv_emit_llvm_link);
3936 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
3937 .equals_insensitive(
"lld"))
3938 Diag(clang::diag::err_drv_lto_without_lld);
3944 if (!Args.hasArg(options::OPT_dumpdir)) {
3945 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
3946 Arg *Arg = Args.MakeSeparateArg(
3947 nullptr,
getOpts().getOption(options::OPT_dumpdir),
3949 (FinalOutput ? FinalOutput->getValue()
3961 Args.eraseArg(options::OPT__SLASH_Fp);
3962 Args.eraseArg(options::OPT__SLASH_Yc);
3963 Args.eraseArg(options::OPT__SLASH_Yu);
3964 YcArg = YuArg =
nullptr;
3967 unsigned LastPLSize = 0;
3968 for (
auto &I : Inputs) {
3970 const Arg *InputArg = I.second;
3973 LastPLSize = PL.size();
3978 if (InitialPhase > FinalPhase) {
3979 if (InputArg->isClaimed())
3986 if (Args.hasArg(options::OPT_Qunused_arguments))
3992 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
3993 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
3997 (Args.getLastArg(options::OPT__SLASH_EP,
3998 options::OPT__SLASH_P) ||
3999 Args.getLastArg(options::OPT_E) ||
4000 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4002 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4003 << InputArg->getAsString(Args) << !!FinalPhaseArg
4004 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4006 Diag(clang::diag::warn_drv_input_file_unused)
4007 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4009 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4022 Actions.push_back(ClangClPch);
4036 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4037 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4043 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4045 if (!SuppressMissingInputWarning && Inputs.empty()) {
4046 Diag(clang::diag::err_drv_no_input_files);
4051 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4052 StringRef
V = A->getValue();
4053 if (Inputs.size() > 1 && !
V.empty() &&
4054 !llvm::sys::path::is_separator(
V.back())) {
4056 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4057 << A->getSpelling() <<
V;
4058 Args.eraseArg(options::OPT__SLASH_Fo);
4063 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4064 StringRef
V = A->getValue();
4065 if (Inputs.size() > 1 && !
V.empty() &&
4066 !llvm::sys::path::is_separator(
V.back())) {
4068 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4069 << A->getSpelling() <<
V;
4070 Args.eraseArg(options::OPT__SLASH_Fa);
4075 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4076 if (A->getValue()[0] ==
'\0') {
4078 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4079 Args.eraseArg(options::OPT__SLASH_o);
4083 handleArguments(
C, Args, Inputs, Actions);
4085 bool UseNewOffloadingDriver =
4087 Args.hasFlag(options::OPT_offload_new_driver,
4088 options::OPT_no_offload_new_driver,
false);
4091 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4092 !UseNewOffloadingDriver
4093 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4101 for (
auto &I : Inputs) {
4103 const Arg *InputArg = I.second;
4116 if (!UseNewOffloadingDriver)
4117 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4123 if (!UseNewOffloadingDriver)
4124 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4125 Current, InputArg, Phase, PL.back(), FullPL);
4131 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4134 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4135 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4137 LinkerInputs.push_back(Current);
4147 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4148 MergerInputs.push_back(Current);
4166 if (NewCurrent == Current)
4169 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4172 Current = NewCurrent;
4176 if (UseNewOffloadingDriver)
4180 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4184 if (Current->getType() == types::TY_Nothing)
4190 Actions.push_back(Current);
4193 if (!UseNewOffloadingDriver)
4194 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4196 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4202 if (LinkerInputs.empty()) {
4205 if (!UseNewOffloadingDriver)
4206 OffloadBuilder->appendDeviceLinkActions(Actions);
4209 if (!LinkerInputs.empty()) {
4210 if (!UseNewOffloadingDriver)
4211 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4212 LinkerInputs.push_back(Wrapper);
4217 }
else if (UseNewOffloadingDriver ||
4218 Args.hasArg(options::OPT_offload_link)) {
4225 if (!UseNewOffloadingDriver)
4226 LA = OffloadBuilder->processHostLinkAction(LA);
4227 Actions.push_back(LA);
4231 if (!MergerInputs.empty())
4235 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4242 for (
auto &I : Inputs) {
4244 const Arg *InputArg = I.second;
4249 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4250 InputType == types::TY_Asm)
4255 for (
auto Phase : PhaseList) {
4259 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4264 if (InputType == types::TY_Object)
4271 assert(Phase == PhaseList.back() &&
4272 "merging must be final compilation step.");
4273 MergerInputs.push_back(Current);
4282 Actions.push_back(Current);
4286 if (!MergerInputs.empty())
4291 for (
auto Opt : {options::OPT_print_supported_cpus,
4292 options::OPT_print_supported_extensions}) {
4299 if (Arg *A = Args.getLastArg(Opt)) {
4300 if (Opt == options::OPT_print_supported_extensions &&
4301 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4302 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4303 !
C.getDefaultToolChain().getTriple().isARM()) {
4304 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4305 <<
"--print-supported-extensions";
4314 for (
auto &I : Inputs)
4320 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4324 if (TC.requiresValidation(Args)) {
4325 Action *LastAction = Actions.back();
4327 LastAction, types::TY_DX_CONTAINER));
4332 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4338 const llvm::opt::DerivedArgList &Args,
4340 const llvm::Triple &Triple,
4341 bool SuppressError =
false) {
4345 if (!SuppressError && Triple.isNVPTX() &&
4347 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4348 <<
"CUDA" << ArchStr;
4350 }
else if (!SuppressError && Triple.isAMDGPU() &&
4352 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4353 <<
"HIP" << ArchStr;
4361 llvm::StringMap<bool> Features;
4367 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4368 C.setContainsError();
4380static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4382 llvm::Triple Triple) {
4383 if (!Triple.isAMDGPU())
4384 return std::nullopt;
4386 std::set<StringRef> ArchSet;
4387 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4394 bool SuppressError)
const {
4396 TC = &
C.getDefaultToolChain();
4399 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4400 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4401 options::OPT_no_offload_arch_EQ)) {
4402 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4404 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4406 :
"--no-offload-arch");
4409 if (KnownArchs.contains(TC))
4410 return KnownArchs.lookup(TC);
4413 for (
auto *Arg : Args) {
4415 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4416 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4419 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4420 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4421 Arg = ExtractedArg.get();
4426 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4427 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4428 if (Arch ==
"native" || Arch.empty()) {
4432 llvm::consumeError(GPUsOrErr.takeError());
4435 << llvm::Triple::getArchTypeName(TC->
getArch())
4436 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4440 for (
auto ArchStr : *GPUsOrErr) {
4447 C, Args, Arch, TC->
getTriple(), SuppressError);
4448 if (ArchStr.empty())
4450 Archs.insert(ArchStr);
4453 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4454 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4455 if (Arch ==
"all") {
4459 C, Args, Arch, TC->
getTriple(), SuppressError);
4460 if (ArchStr.empty())
4462 Archs.erase(ArchStr);
4468 if (
auto ConflictingArchs =
4470 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4471 << ConflictingArchs->first << ConflictingArchs->second;
4472 C.setContainsError();
4479 if (Archs.empty()) {
4485 Archs.insert(StringRef());
4487 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4488 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4495 llvm::opt::DerivedArgList &Args,
4497 Action *HostAction)
const {
4502 !(isa<CompileJobAction>(HostAction) ||
4516 auto TCRange =
C.getOffloadToolChains(Kind);
4517 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4518 ToolChains.push_back(TI->second);
4520 if (ToolChains.empty())
4524 const Arg *InputArg = Input.second;
4535 TCAndArchs.push_back(std::make_pair(TC, Arch));
4537 for (
unsigned I = 0, E = TCAndArchs.size(); I != E; ++I)
4538 DeviceActions.push_back(
C.MakeAction<
InputAction>(*InputArg, InputType));
4540 if (DeviceActions.empty())
4547 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4551 auto TCAndArch = TCAndArchs.begin();
4552 for (
Action *&A : DeviceActions) {
4553 if (A->
getType() == types::TY_Nothing)
4561 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4563 HostAction->
getType() != types::TY_Nothing) {
4570 TCAndArch->second.data(), Kind);
4572 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4581 for (
Action *&A : DeviceActions) {
4582 if ((A->
getType() != types::TY_Object &&
4583 A->
getType() != types::TY_LTO_BC) ||
4585 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4591 auto TCAndArch = TCAndArchs.begin();
4592 for (
Action *A : DeviceActions) {
4593 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4595 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4604 if (OffloadActions.empty())
4609 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4613 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4617 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4622 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4631 nullptr,
C.getActiveOffloadKinds());
4636 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4637 return A->
getType() == types::TY_Nothing;
4638 }) && isa<CompileJobAction>(HostAction);
4641 nullptr, SingleDeviceOutput ? DDep : DDeps);
4642 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4648 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4659 llvm_unreachable(
"link action invalid here.");
4661 llvm_unreachable(
"ifsmerge action invalid here.");
4666 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4667 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4668 OutputTy = types::TY_Dependencies;
4673 if (!Args.hasFlag(options::OPT_frewrite_includes,
4674 options::OPT_fno_rewrite_includes,
false) &&
4675 !Args.hasFlag(options::OPT_frewrite_imports,
4676 options::OPT_fno_rewrite_imports,
false) &&
4677 !Args.hasFlag(options::OPT_fdirectives_only,
4678 options::OPT_fno_directives_only,
false) &&
4682 "Cannot preprocess this input type!");
4688 if (Args.hasArg(options::OPT_extract_api))
4693 "Cannot precompile this input type!");
4697 const char *ModName =
nullptr;
4698 if (OutputTy == types::TY_PCH) {
4699 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4700 ModName = A->getValue();
4702 OutputTy = types::TY_ModuleFile;
4705 if (Args.hasArg(options::OPT_fsyntax_only)) {
4707 OutputTy = types::TY_Nothing;
4713 if (Args.hasArg(options::OPT_fsyntax_only))
4715 if (Args.hasArg(options::OPT_rewrite_objc))
4717 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
4719 types::TY_RewrittenLegacyObjC);
4720 if (Args.hasArg(options::OPT__analyze))
4722 if (Args.hasArg(options::OPT__migrate))
4724 if (Args.hasArg(options::OPT_emit_ast))
4726 if (Args.hasArg(options::OPT_module_file_info))
4728 if (Args.hasArg(options::OPT_verify_pch))
4730 if (Args.hasArg(options::OPT_extract_api))
4737 if (Args.hasArg(options::OPT_S))
4738 Output = types::TY_LTO_IR;
4739 else if (Args.hasArg(options::OPT_ffat_lto_objects))
4740 Output = types::TY_PP_Asm;
4742 Output = types::TY_LTO_BC;
4748 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
4751 if (Args.hasArg(options::OPT_emit_llvm) ||
4755 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4759 Args.hasArg(options::OPT_S) &&
4763 !Args.hasFlag(options::OPT_offload_new_driver,
4764 options::OPT_no_offload_new_driver,
false)))
4766 : types::TY_LLVM_BC;
4775 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4779 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4781 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
4801 unsigned NumOutputs = 0;
4802 unsigned NumIfsOutputs = 0;
4803 for (
const Action *A :
C.getActions()) {
4804 if (A->
getType() != types::TY_Nothing &&
4805 A->
getType() != types::TY_DX_CONTAINER &&
4807 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
4809 0 == NumIfsOutputs++) ||
4814 A->
getType() == types::TY_Nothing &&
4815 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
4816 NumOutputs += A->
size();
4819 if (NumOutputs > 1) {
4820 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
4821 FinalOutput =
nullptr;
4825 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
4828 llvm::StringSet<> ArchNames;
4829 if (RawTriple.isOSBinFormatMachO())
4830 for (
const Arg *A :
C.getArgs())
4831 if (A->getOption().matches(options::OPT_arch))
4832 ArchNames.insert(A->getValue());
4835 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
4836 for (
Action *A :
C.getActions()) {
4843 const char *LinkingOutput =
nullptr;
4844 if (isa<LipoJobAction>(A)) {
4846 LinkingOutput = FinalOutput->getValue();
4854 ArchNames.size() > 1,
4855 LinkingOutput, CachedResults,
4862 for (
auto &J :
C.getJobs())
4863 J.InProcess =
false;
4866 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
4867 std::optional<llvm::sys::ProcessStatistics> ProcStat =
4868 Cmd.getProcessStatistics();
4872 const char *LinkingOutput =
nullptr;
4874 LinkingOutput = FinalOutput->getValue();
4875 else if (!
Cmd.getOutputFilenames().empty())
4876 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
4881 using namespace llvm;
4883 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
4884 <<
"output=" << LinkingOutput;
4885 outs() <<
", total="
4886 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
4888 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
4889 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
4893 llvm::raw_string_ostream Out(Buffer);
4894 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
4897 llvm::sys::printArg(Out, LinkingOutput, true);
4898 Out <<
',' << ProcStat->TotalTime.count() <<
','
4899 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
4903 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
4904 llvm::sys::fs::OF_Append |
4905 llvm::sys::fs::OF_Text);
4910 llvm::errs() <<
"ERROR: Cannot lock file "
4911 << CCPrintStatReportFilename <<
": "
4912 << toString(L.takeError()) <<
"\n";
4923 if (Diags.hasErrorOccurred() ||
4924 C.getArgs().hasArg(options::OPT_Qunused_arguments))
4928 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
4930 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
4933 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
4934 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
4936 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
4940 return strstr(J.getCreator().getShortName(),
"assembler");
4942 for (Arg *A :
C.getArgs()) {
4946 if (!A->isClaimed()) {
4952 const Option &Opt = A->getOption();
4953 if (Opt.getKind() == Option::FlagClass) {
4954 bool DuplicateClaimed =
false;
4956 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
4957 if (AA->isClaimed()) {
4958 DuplicateClaimed =
true;
4963 if (DuplicateClaimed)
4969 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
4971 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
4976 !
C.getActions().empty()) {
4977 Diag(diag::err_drv_unsupported_opt_for_target)
4978 << A->getSpelling() << getTargetTriple();
4980 Diag(clang::diag::warn_drv_unused_argument)
4981 << A->getAsString(
C.getArgs());
4991class ToolSelector final {
5002 bool IsHostSelector;
5013 bool CanBeCollapsed =
true) {
5015 if (Inputs.size() != 1)
5018 Action *CurAction = *Inputs.begin();
5019 if (CanBeCollapsed &&
5025 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5029 if (!IsHostSelector) {
5030 if (OA->hasSingleDeviceDependence(
true)) {
5032 OA->getSingleDeviceDependence(
true);
5033 if (CanBeCollapsed &&
5036 SavedOffloadAction.push_back(OA);
5037 return dyn_cast<JobAction>(CurAction);
5039 }
else if (OA->hasHostDependence()) {
5040 CurAction = OA->getHostDependence();
5041 if (CanBeCollapsed &&
5044 SavedOffloadAction.push_back(OA);
5045 return dyn_cast<JobAction>(CurAction);
5050 return dyn_cast<JobAction>(CurAction);
5054 bool canCollapseAssembleAction()
const {
5055 return TC.useIntegratedAs() && !SaveTemps &&
5056 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5057 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5058 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5059 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5063 bool canCollapsePreprocessorAction()
const {
5064 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5065 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5066 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5071 struct JobActionInfo final {
5081 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5083 unsigned ElementNum) {
5084 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5085 for (
unsigned I = 0; I < ElementNum; ++I)
5086 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5087 ActionInfo[I].SavedOffloadAction.end());
5103 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5105 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5106 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5107 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5108 if (!AJ || !BJ || !CJ)
5112 const Tool *T = TC.SelectTool(*CJ);
5125 const Tool *BT = TC.SelectTool(*BJ);
5133 Inputs = CJ->getInputs();
5134 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5141 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5143 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5144 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5149 const Tool *T = TC.SelectTool(*BJ);
5156 Inputs = BJ->getInputs();
5157 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5164 if (ActionInfo.size() < 2)
5166 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5167 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5176 bool InputIsBitcode =
true;
5177 for (
size_t i = 1; i < ActionInfo.size(); i++)
5178 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5179 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5180 InputIsBitcode =
false;
5183 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5187 const Tool *T = TC.SelectTool(*CJ);
5200 Inputs = CJ->getInputs();
5201 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5218 for (
Action *A : Inputs) {
5219 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5220 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5221 NewInputs.push_back(A);
5227 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5228 PreprocessJobOffloadActions.end());
5229 NewInputs.append(PJ->input_begin(), PJ->input_end());
5237 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5239 assert(BaseAction &&
"Invalid base action.");
5256 ActionChain.back().JA = BaseAction;
5257 while (ActionChain.back().JA) {
5258 const Action *CurAction = ActionChain.back().JA;
5261 ActionChain.resize(ActionChain.size() + 1);
5262 JobActionInfo &AI = ActionChain.back();
5266 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5270 ActionChain.pop_back();
5278 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5279 CollapsedOffloadAction);
5281 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5283 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5289 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
5301 StringRef BoundArch,
5303 std::string TriplePlusArch = TC->
getTriple().normalize();
5304 if (!BoundArch.empty()) {
5305 TriplePlusArch +=
"-";
5306 TriplePlusArch += BoundArch;
5308 TriplePlusArch +=
"-";
5310 return TriplePlusArch;
5315 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5316 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5319 std::pair<const Action *, std::string> ActionTC = {
5321 auto CachedResult = CachedResults.find(ActionTC);
5322 if (CachedResult != CachedResults.end()) {
5323 return CachedResult->second;
5326 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5327 CachedResults, TargetDeviceOffloadKind);
5328 CachedResults[ActionTC] =
Result;
5333 const JobAction *JA,
const char *BaseInput,
5336 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5340 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5341 Path = A->getValue();
5342 if (llvm::sys::fs::is_directory(Path)) {
5344 llvm::sys::path::replace_extension(Tmp,
"json");
5345 llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
5348 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5351 Path = DumpDir->getValue();
5352 Path += llvm::sys::path::filename(BaseInput);
5354 Path =
Result.getFilename();
5356 llvm::sys::path::replace_extension(Path,
"json");
5358 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5359 C.addTimeTraceFile(ResultFile, JA);
5360 C.addResultFile(ResultFile, JA);
5365 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5366 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5369 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5372 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5405 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5407 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5408 const char *DepBoundArch) {
5411 LinkingOutput, CachedResults,
5421 OA->doOnEachDependence(
5422 BuildingForOffloadDevice,
5425 C, DepA, DepTC, DepBoundArch,
false,
5426 !!DepBoundArch, LinkingOutput, CachedResults,
5430 A = BuildingForOffloadDevice
5431 ? OA->getSingleDeviceDependence(
true)
5432 : OA->getHostDependence();
5436 std::pair<const Action *, std::string> ActionTC = {
5437 OA->getHostDependence(),
5439 if (CachedResults.find(ActionTC) != CachedResults.end()) {
5441 Inputs.append(OffloadDependencesInputInfo);
5446 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5449 const Arg &Input = IA->getInputArg();
5451 if (Input.getOption().matches(options::OPT_INPUT)) {
5452 const char *
Name = Input.getValue();
5462 if (!ArchName.empty())
5463 TC = &getToolChain(
C.getArgs(),
5465 C.getArgs(), ArchName));
5467 TC = &
C.getDefaultToolChain();
5470 MultipleArchs, LinkingOutput, CachedResults,
5471 TargetDeviceOffloadKind);
5477 const JobAction *JA = cast<JobAction>(A);
5482 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
5489 for (
const auto *OA : CollapsedOffloadActions)
5490 cast<OffloadAction>(OA)->doOnEachDependence(
5491 BuildingForOffloadDevice,
5494 C, DepA, DepTC, DepBoundArch,
false,
5495 !!DepBoundArch, LinkingOutput, CachedResults,
5501 for (
const Action *Input : Inputs) {
5505 bool SubJobAtTopLevel =
5506 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5508 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5513 const char *BaseInput = InputInfos[0].getBaseInput();
5514 for (
auto &Info : InputInfos) {
5515 if (Info.isFilename()) {
5516 BaseInput = Info.getBaseInput();
5523 if (JA->
getType() == types::TY_dSYM)
5524 BaseInput = InputInfos[0].getFilename();
5527 if (!OffloadDependencesInputInfo.empty())
5528 InputInfos.append(OffloadDependencesInputInfo.begin(),
5529 OffloadDependencesInputInfo.end());
5532 llvm::Triple EffectiveTriple;
5534 const ArgList &Args =
5536 if (InputInfos.size() != 1) {
5540 EffectiveTriple = llvm::Triple(
5548 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {