55#include "clang/Config/config.h"
67#include "llvm/ADT/ArrayRef.h"
68#include "llvm/ADT/STLExtras.h"
69#include "llvm/ADT/StringExtras.h"
70#include "llvm/ADT/StringRef.h"
71#include "llvm/ADT/StringSet.h"
72#include "llvm/ADT/StringSwitch.h"
73#include "llvm/Config/llvm-config.h"
74#include "llvm/MC/TargetRegistry.h"
75#include "llvm/Option/Arg.h"
76#include "llvm/Option/ArgList.h"
77#include "llvm/Option/OptSpecifier.h"
78#include "llvm/Option/OptTable.h"
79#include "llvm/Option/Option.h"
80#include "llvm/Support/CommandLine.h"
81#include "llvm/Support/ErrorHandling.h"
82#include "llvm/Support/ExitCodes.h"
83#include "llvm/Support/FileSystem.h"
84#include "llvm/Support/FormatVariadic.h"
85#include "llvm/Support/MD5.h"
86#include "llvm/Support/Path.h"
87#include "llvm/Support/PrettyStackTrace.h"
88#include "llvm/Support/Process.h"
89#include "llvm/Support/Program.h"
90#include "llvm/Support/Regex.h"
91#include "llvm/Support/StringSaver.h"
92#include "llvm/Support/VirtualFileSystem.h"
93#include "llvm/Support/raw_ostream.h"
94#include "llvm/TargetParser/Host.h"
95#include "llvm/TargetParser/RISCVISAInfo.h"
107using namespace clang;
111 const ArgList &Args) {
112 auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
116 switch (OffloadTargets.size()) {
118 D.
Diag(diag::err_drv_only_one_offload_target_supported);
121 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) <<
"";
126 return llvm::Triple(OffloadTargets[0]);
129static std::optional<llvm::Triple>
131 const llvm::Triple &HostTriple) {
132 if (!Args.hasArg(options::OPT_offload_EQ)) {
133 return llvm::Triple(HostTriple.isArch64Bit() ?
"nvptx64-nvidia-cuda"
134 :
"nvptx-nvidia-cuda");
137 if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
138 TT->getArch() == llvm::Triple::spirv64)) {
139 if (Args.hasArg(options::OPT_emit_llvm))
141 D.
Diag(diag::err_drv_cuda_offload_only_emit_bc);
144 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
147static std::optional<llvm::Triple>
149 if (!Args.hasArg(options::OPT_offload_EQ)) {
150 return llvm::Triple(
"amdgcn-amd-amdhsa");
155 if (TT->getArch() == llvm::Triple::amdgcn &&
156 TT->getVendor() == llvm::Triple::AMD &&
157 TT->getOS() == llvm::Triple::AMDHSA)
159 if (TT->getArch() == llvm::Triple::spirv64)
161 D.
Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
167 StringRef CustomResourceDir) {
173 std::string
Dir = std::string(llvm::sys::path::parent_path(BinaryPath));
176 if (CustomResourceDir !=
"") {
177 llvm::sys::path::append(
P, CustomResourceDir);
184 P = llvm::sys::path::parent_path(
Dir);
187 llvm::sys::path::append(
P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
188 CLANG_VERSION_MAJOR_STRING);
191 return std::string(
P);
197 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
198 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
201 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
202 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
203 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
204 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
205 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
206 CheckInputsExist(
true), ProbePrecompiled(
true),
207 SuppressMissingInputWarning(
false) {
210 this->VFS = llvm::vfs::getRealFileSystem();
215 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
218 llvm::sys::path::append(
P,
SysRoot);
222#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
225#if defined(CLANG_CONFIG_FILE_USER_DIR)
228 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
234void Driver::setDriverMode(StringRef
Value) {
235 static StringRef OptName =
236 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
237 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
238 .Case(
"gcc", GCCMode)
239 .Case(
"g++", GXXMode)
240 .Case(
"cpp", CPPMode)
242 .Case(
"flang", FlangMode)
243 .Case(
"dxc", DXCMode)
247 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
250void Driver::setResourceDirectory() {
269 bool UseDriverMode,
bool &ContainsError) {
270 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
271 ContainsError =
false;
273 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
274 unsigned MissingArgIndex, MissingArgCount;
275 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
276 MissingArgCount, VisibilityMask);
279 if (MissingArgCount) {
280 Diag(diag::err_drv_missing_argument)
281 << Args.getArgString(MissingArgIndex) << MissingArgCount;
288 for (
const Arg *A : Args) {
290 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
298 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
299 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
301 diag::warn_drv_empty_joined_argument,
306 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
308 auto ArgString = A->getAsString(Args);
310 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
312 getOpts().findExact(ArgString, Nearest,
314 DiagID = diag::err_drv_unknown_argument_with_suggestion;
315 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
317 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
318 : diag::err_drv_unknown_argument;
319 Diags.
Report(DiagID) << ArgString;
323 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
324 : diag::err_drv_unknown_argument_with_suggestion;
325 Diags.
Report(DiagID) << ArgString << Nearest;
331 for (
const Arg *A : Args.filtered(options::OPT_o)) {
332 if (ArgStrings[A->getIndex()] == A->getSpelling())
336 std::string ArgString = ArgStrings[A->getIndex()];
338 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
339 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
340 << A->getAsString(Args) << Nearest;
350 Arg **FinalPhaseArg)
const {
351 Arg *PhaseArg =
nullptr;
355 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
356 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
357 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
365 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
368 options::OPT_fmodule_header_EQ))) {
371 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
372 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
373 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
374 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
375 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
376 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
377 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
378 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
379 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
380 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
384 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
388 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
391 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
399 *FinalPhaseArg = PhaseArg;
405 StringRef
Value,
bool Claim =
true) {
406 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
407 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
408 Args.AddSynthesizedArg(A);
414DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
415 const llvm::opt::OptTable &Opts =
getOpts();
416 DerivedArgList *DAL =
new DerivedArgList(Args);
418 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
419 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
420 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
421 bool IgnoreUnused =
false;
422 for (Arg *A : Args) {
426 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
430 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
431 IgnoreUnused =
false;
441 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
442 A->getOption().matches(options::OPT_Xlinker)) &&
443 A->containsValue(
"--no-demangle")) {
445 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
448 for (StringRef Val : A->getValues())
449 if (Val !=
"--no-demangle")
450 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
458 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
459 (A->getValue(0) == StringRef(
"-MD") ||
460 A->getValue(0) == StringRef(
"-MMD"))) {
462 if (A->getValue(0) == StringRef(
"-MD"))
463 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
465 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
466 if (A->getNumValues() == 2)
467 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
472 if (A->getOption().matches(options::OPT_l)) {
473 StringRef
Value = A->getValue();
476 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
478 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
483 if (
Value ==
"cc_kext") {
484 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
490 if (A->getOption().matches(options::OPT__DASH_DASH)) {
492 for (StringRef Val : A->getValues())
501 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
502 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
505 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
506 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
510#if defined(HOST_LINK_VERSION)
511 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
512 strlen(HOST_LINK_VERSION) > 0) {
513 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
515 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
527 StringRef TargetTriple,
529 StringRef DarwinArchName =
"") {
531 if (
const Arg *A = Args.getLastArg(options::OPT_target))
532 TargetTriple = A->getValue();
534 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
539 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
543 if (
Target.isOSBinFormatMachO()) {
545 if (!DarwinArchName.empty()) {
552 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
553 StringRef ArchName = A->getValue();
560 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
561 options::OPT_mbig_endian)) {
562 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
563 ?
Target.getLittleEndianArchVariant()
564 :
Target.getBigEndianArchVariant();
565 if (
T.getArch() != llvm::Triple::UnknownArch) {
567 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
572 if (
Target.getArch() == llvm::Triple::tce)
577 if (std::optional<std::string> ObjectModeValue =
578 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
579 StringRef ObjectMode = *ObjectModeValue;
580 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
582 if (ObjectMode ==
"64") {
583 AT =
Target.get64BitArchVariant().getArch();
584 }
else if (ObjectMode ==
"32") {
585 AT =
Target.get32BitArchVariant().getArch();
587 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
590 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
596 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
598 D.
Diag(diag::err_drv_unsupported_opt_for_target)
599 << A->getAsString(Args) <<
Target.str();
602 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
603 options::OPT_m32, options::OPT_m16,
604 options::OPT_maix32, options::OPT_maix64);
606 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
608 if (A->getOption().matches(options::OPT_m64) ||
609 A->getOption().matches(options::OPT_maix64)) {
610 AT =
Target.get64BitArchVariant().getArch();
611 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
612 Target.setEnvironment(llvm::Triple::GNU);
613 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
614 Target.setEnvironment(llvm::Triple::Musl);
615 }
else if (A->getOption().matches(options::OPT_mx32) &&
616 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
617 AT = llvm::Triple::x86_64;
618 if (
Target.getEnvironment() == llvm::Triple::Musl)
619 Target.setEnvironment(llvm::Triple::MuslX32);
621 Target.setEnvironment(llvm::Triple::GNUX32);
622 }
else if (A->getOption().matches(options::OPT_m32) ||
623 A->getOption().matches(options::OPT_maix32)) {
624 AT =
Target.get32BitArchVariant().getArch();
625 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
626 Target.setEnvironment(llvm::Triple::GNU);
627 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
628 Target.setEnvironment(llvm::Triple::Musl);
629 }
else if (A->getOption().matches(options::OPT_m16) &&
630 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
631 AT = llvm::Triple::x86;
632 Target.setEnvironment(llvm::Triple::CODE16);
635 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
637 if (
Target.isWindowsGNUEnvironment())
643 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
644 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
645 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
648 if (A && !A->getOption().matches(options::OPT_m32))
649 D.
Diag(diag::err_drv_argument_not_allowed_with)
650 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
652 Target.setArch(llvm::Triple::x86);
653 Target.setArchName(
"i586");
654 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
655 Target.setEnvironmentName(
"");
656 Target.setOS(llvm::Triple::ELFIAMCU);
657 Target.setVendor(llvm::Triple::UnknownVendor);
658 Target.setVendorName(
"intel");
664 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
665 StringRef ABIName = A->getValue();
666 if (ABIName ==
"32") {
668 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
669 Target.getEnvironment() == llvm::Triple::GNUABIN32)
670 Target.setEnvironment(llvm::Triple::GNU);
671 }
else if (ABIName ==
"n32") {
673 if (
Target.getEnvironment() == llvm::Triple::GNU ||
674 Target.getEnvironment() == llvm::Triple::GNUABI64)
675 Target.setEnvironment(llvm::Triple::GNUABIN32);
676 }
else if (ABIName ==
"64") {
678 if (
Target.getEnvironment() == llvm::Triple::GNU ||
679 Target.getEnvironment() == llvm::Triple::GNUABIN32)
680 Target.setEnvironment(llvm::Triple::GNUABI64);
688 if (Args.hasArg(options::OPT_march_EQ) ||
689 Args.hasArg(options::OPT_mcpu_EQ)) {
691 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
693 if (!llvm::errorToBool(ISAInfo.takeError())) {
694 unsigned XLen = (*ISAInfo)->getXLen();
696 Target.setArch(llvm::Triple::riscv32);
698 Target.setArch(llvm::Triple::riscv64);
710 OptSpecifier OptEq, OptSpecifier OptNeg) {
711 if (!Args.hasFlag(OptEq, OptNeg,
false))
714 const Arg *A = Args.getLastArg(OptEq);
715 StringRef LTOName = A->getValue();
723 D.
Diag(diag::err_drv_unsupported_option_argument)
724 << A->getSpelling() << A->getValue();
731void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
733 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
735 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
736 options::OPT_fno_offload_lto);
739 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
740 options::OPT_fno_openmp_target_jit,
false)) {
741 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
742 options::OPT_fno_offload_lto))
744 Diag(diag::err_drv_incompatible_options)
745 << A->getSpelling() <<
"-fopenmp-target-jit";
752 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
754 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
756 RuntimeName = A->getValue();
758 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
766 Diag(diag::err_drv_unsupported_option_argument)
767 << A->getSpelling() << A->getValue();
770 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
785 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
790 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
793 C.getInputArgs().hasArg(options::OPT_hip_link) ||
794 C.getInputArgs().hasArg(options::OPT_hipstdpar);
795 if (IsCuda && IsHIP) {
796 Diag(clang::diag::err_drv_mix_cuda_hip);
801 const llvm::Triple &HostTriple = HostTC->
getTriple();
809 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
811 CudaTC = std::make_unique<toolchains::CudaToolChain>(
812 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
817 if (CudaInstallation.
isValid())
820 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
822 if (
auto *OMPTargetArg =
823 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
824 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
825 << OMPTargetArg->getSpelling() <<
"HIP";
833 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
835 assert(HIPTC &&
"Could not create offloading device tool chain.");
836 C.addOffloadDeviceToolChain(HIPTC, OFK);
844 bool IsOpenMPOffloading =
845 C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
846 options::OPT_fno_openmp,
false) &&
847 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
848 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ));
849 if (IsOpenMPOffloading) {
855 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
859 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
860 llvm::StringMap<StringRef> FoundNormalizedTriples;
861 std::multiset<StringRef> OpenMPTriples;
866 if (Arg *OpenMPTargets =
867 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
868 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
869 Diag(clang::diag::warn_drv_empty_joined_argument)
870 << OpenMPTargets->getAsString(
C.getInputArgs());
873 for (StringRef
T : OpenMPTargets->getValues())
874 OpenMPTriples.insert(
T);
875 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
888 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
889 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
895 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
896 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
901 if (!AMDTriple && !NVPTXTriple) {
902 for (StringRef Arch :
907 for (StringRef Arch : Archs) {
910 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
911 }
else if (AMDTriple &&
914 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
916 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
923 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
928 for (
const auto &TripleAndArchs : DerivedArchs)
929 OpenMPTriples.insert(TripleAndArchs.first());
932 for (StringRef Val : OpenMPTriples) {
934 std::string NormalizedName = TT.normalize();
937 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
938 if (Duplicate != FoundNormalizedTriples.end()) {
939 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
940 << Val << Duplicate->second;
946 FoundNormalizedTriples[NormalizedName] = Val;
949 if (TT.getArch() == llvm::Triple::UnknownArch)
950 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
955 if (TT.isNVPTX() || TT.isAMDGCN()) {
958 assert(HostTC &&
"Host toolchain should be always defined.");
960 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
963 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
964 *
this, TT, *HostTC,
C.getInputArgs());
965 else if (TT.isAMDGCN())
966 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
967 *
this, TT, *HostTC,
C.getInputArgs());
969 assert(DeviceTC &&
"Device toolchain not defined.");
974 TC = &getToolChain(
C.getInputArgs(), TT);
976 if (DerivedArchs.contains(TT.getTriple()))
977 KnownArchs[TC] = DerivedArchs[TT.getTriple()];
980 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
981 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
991 const Arg *BaseArg) {
995 unsigned Index = Args.MakeIndex(Opt->getSpelling());
996 Arg *
Copy =
new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index),
998 Copy->getValues() = Opt->getValues();
999 if (Opt->isClaimed())
1001 Copy->setOwnsValues(Opt->getOwnsValues());
1002 Opt->setOwnsValues(
false);
1006bool Driver::readConfigFile(StringRef
FileName,
1007 llvm::cl::ExpansionContext &ExpCtx) {
1011 Diag(diag::err_drv_cannot_open_config_file)
1012 <<
FileName << Status.getError().message();
1015 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1016 Diag(diag::err_drv_cannot_open_config_file)
1017 <<
FileName <<
"not a regular file";
1023 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgArgs)) {
1024 Diag(diag::err_drv_cannot_read_config_file)
1031 llvm::sys::path::native(CfgFileName);
1033 std::unique_ptr<InputArgList> NewOptions = std::make_unique<InputArgList>(
1040 for (Arg *A : *NewOptions)
1044 CfgOptions = std::move(NewOptions);
1047 for (
auto *Opt : *NewOptions) {
1048 const Arg *BaseArg = &Opt->getBaseArg();
1054 ConfigFiles.push_back(std::string(CfgFileName));
1058bool Driver::loadConfigFiles() {
1059 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1060 llvm::cl::tokenizeConfigFile);
1061 ExpCtx.setVFS(&
getVFS());
1065 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1068 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1069 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1074 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1076 llvm::sys::fs::expand_tilde(
1077 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1078 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1087 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1090 if (loadDefaultConfigFiles(ExpCtx))
1096 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1099 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1100 CfgFilePath.assign(CfgFileName);
1101 if (llvm::sys::path::is_relative(CfgFilePath)) {
1102 if (
getVFS().makeAbsolute(CfgFilePath)) {
1103 Diag(diag::err_drv_cannot_open_config_file)
1104 << CfgFilePath <<
"cannot get absolute path";
1108 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1110 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1111 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1112 if (!SearchDir.empty())
1113 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1118 if (readConfigFile(CfgFilePath, ExpCtx))
1127bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1130 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1134 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1137 std::string RealMode = getExecutableForDriverMode(Mode);
1147 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1148 PrefixTriple.isOSUnknown())
1149 Triple = PrefixTriple.str();
1153 if (Triple.empty()) {
1154 llvm::Triple RealTriple =
1156 Triple = RealTriple.str();
1157 assert(!Triple.empty());
1172 std::string CfgFileName = Triple +
'-' + RealMode +
".cfg";
1173 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1174 return readConfigFile(CfgFilePath, ExpCtx);
1178 if (TryModeSuffix) {
1180 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1181 return readConfigFile(CfgFilePath, ExpCtx);
1186 CfgFileName = RealMode +
".cfg";
1187 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1188 if (readConfigFile(CfgFilePath, ExpCtx))
1190 }
else if (TryModeSuffix) {
1192 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1193 readConfigFile(CfgFilePath, ExpCtx))
1198 CfgFileName = Triple +
".cfg";
1199 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1200 return readConfigFile(CfgFilePath, ExpCtx);
1208 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1217 if (!DriverMode.empty())
1218 setDriverMode(DriverMode);
1220 setResourceDirectory();
1225 CLOptions = std::make_unique<InputArgList>(
1230 ContainsError = loadConfigFiles();
1231 bool HasConfigFile = !ContainsError && (CfgOptions.get() !=
nullptr);
1234 InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
1235 : std::move(*CLOptions));
1238 for (
auto *Opt : *CLOptions) {
1239 if (Opt->getOption().matches(options::OPT_config))
1241 const Arg *BaseArg = &Opt->getBaseArg();
1248 if (
IsCLMode() && !ContainsError) {
1250 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1252 CLModePassThroughArgList.push_back(A->getValue());
1255 if (!CLModePassThroughArgList.empty()) {
1258 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1263 for (
auto *Opt : *CLModePassThroughOptions) {
1270 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1271 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1272 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1275 bool CCCPrintPhases;
1278 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1279 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1282 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1283 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1286 Args.ClaimAllArgs(options::OPT_pipe);
1294 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1296 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1297 CCCGenericGCCName = A->getValue();
1300 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1304 if (Args.hasArg(options::OPT_fproc_stat_report))
1311 llvm::Triple
T(TargetTriple);
1312 T.setOS(llvm::Triple::Win32);
1313 T.setVendor(llvm::Triple::PC);
1314 T.setEnvironment(llvm::Triple::MSVC);
1315 T.setObjectFormat(llvm::Triple::COFF);
1316 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1317 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1318 TargetTriple =
T.str();
1321 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1322 StringRef TargetProfile = A->getValue();
1325 TargetTriple = *Triple;
1327 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1331 if (Args.hasArg(options::OPT_spirv)) {
1332 llvm::Triple
T(TargetTriple);
1333 T.setArch(llvm::Triple::spirv);
1334 T.setOS(llvm::Triple::Vulkan);
1337 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1338 const llvm::StringSet<> ValidValues = {
"vulkan1.2",
"vulkan1.3"};
1339 if (ValidValues.contains(A->getValue())) {
1340 T.setOSName(A->getValue());
1342 Diag(diag::err_drv_invalid_value)
1343 << A->getAsString(Args) << A->getValue();
1348 TargetTriple =
T.str();
1351 Diag(diag::err_drv_dxc_missing_target_profile);
1355 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1356 TargetTriple = A->getValue();
1357 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1358 Dir =
Dir = A->getValue();
1359 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1363 if (std::optional<std::string> CompilerPathValue =
1364 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1365 StringRef CompilerPath = *CompilerPathValue;
1366 while (!CompilerPath.empty()) {
1367 std::pair<StringRef, StringRef> Split =
1368 CompilerPath.split(llvm::sys::EnvPathSeparator);
1369 PrefixDirs.push_back(std::string(Split.first));
1370 CompilerPath = Split.second;
1373 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1375 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1378 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1381 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1382 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1383 .Case(
"cwd", SaveTempsCwd)
1384 .Case(
"obj", SaveTempsObj)
1385 .Default(SaveTempsCwd);
1388 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1389 options::OPT_offload_device_only,
1390 options::OPT_offload_host_device)) {
1391 if (A->getOption().matches(options::OPT_offload_host_only))
1392 Offload = OffloadHost;
1393 else if (A->getOption().matches(options::OPT_offload_device_only))
1394 Offload = OffloadDevice;
1396 Offload = OffloadHostDevice;
1402 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1403 StringRef
Name = A->getValue();
1404 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1405 .Case(
"off", EmbedNone)
1406 .Case(
"all", EmbedBitcode)
1407 .Case(
"bitcode", EmbedBitcode)
1408 .Case(
"marker", EmbedMarker)
1411 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1414 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1418 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1419 llvm::sys::fs::remove(A->getValue());
1425 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1427 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1428 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1429 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1430 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1431 Std->containsValue(
"c++latest"));
1434 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1435 options::OPT_fmodule_header)) {
1437 ModulesModeCXX20 =
true;
1438 if (A->getOption().matches(options::OPT_fmodule_header))
1441 StringRef ArgName = A->getValue();
1442 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1447 Diags.
Report(diag::err_drv_invalid_value)
1448 << A->getAsString(Args) << ArgName;
1454 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1455 std::make_unique<InputArgList>(std::move(Args));
1458 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1466 if (!Triple.isWasm()) {
1467 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1468 StringRef TripleObjectFormat =
1469 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1470 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1471 TripleVersionName != TripleObjectFormat) {
1472 Diags.
Report(diag::err_drv_triple_version_invalid)
1474 ContainsError =
true;
1479 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1480 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1481 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1489 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1490 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1492 case llvm::Triple::arm:
1493 case llvm::Triple::armeb:
1494 case llvm::Triple::thumb:
1495 case llvm::Triple::thumbeb:
1496 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1497 Diag(diag::warn_target_unrecognized_env)
1499 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1502 case llvm::Triple::aarch64:
1503 case llvm::Triple::aarch64_be:
1504 case llvm::Triple::aarch64_32:
1505 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1506 Diag(diag::warn_target_unrecognized_env)
1508 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1525 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1532 if (TC.
getTriple().isOSBinFormatMachO())
1537 if (CCCPrintPhases) {
1548 llvm::opt::ArgStringList ASL;
1549 for (
const auto *A : Args) {
1553 while (A->getAlias())
1555 A->render(Args, ASL);
1558 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1559 if (I != ASL.begin())
1561 llvm::sys::printArg(OS, *I,
true);
1566bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1568 using namespace llvm::sys;
1569 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1570 "Only knows about .crash files on Darwin");
1575 path::home_directory(CrashDiagDir);
1576 if (CrashDiagDir.starts_with(
"/var/root"))
1578 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1586 fs::file_status FileStatus;
1587 TimePoint<> LastAccessTime;
1591 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1592 File != FileEnd && !EC;
File.increment(EC)) {
1596 if (fs::status(
File->path(), FileStatus))
1598 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1599 llvm::MemoryBuffer::getFile(
File->path());
1604 StringRef
Data = CrashFile.get()->getBuffer();
1605 if (!
Data.starts_with(
"Process:"))
1608 size_t ParentProcPos =
Data.find(
"Parent Process:");
1609 if (ParentProcPos == StringRef::npos)
1611 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1612 if (LineEnd == StringRef::npos)
1614 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1615 int OpenBracket = -1, CloseBracket = -1;
1616 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1617 if (ParentProcess[i] ==
'[')
1619 if (ParentProcess[i] ==
']')
1625 if (OpenBracket < 0 || CloseBracket < 0 ||
1626 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1627 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1637 const auto FileAccessTime = FileStatus.getLastModificationTime();
1638 if (FileAccessTime > LastAccessTime) {
1639 CrashFilePath.assign(
File->path());
1640 LastAccessTime = FileAccessTime;
1645 if (!CrashFilePath.empty()) {
1646 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1656 "\n********************\n\n"
1657 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1658 "Preprocessed source(s) and associated run script(s) are located at:";
1666 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1670 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1671 Level = llvm::StringSwitch<unsigned>(A->getValue())
1673 .Case(
"compiler", 1)
1685 ArgStringList SavedTemps;
1687 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1688 if (!IsLLD || Level < 2)
1695 SavedTemps = std::move(
C.getTempFiles());
1696 assert(!
C.getTempFiles().size());
1713 C.initCompilationForDiagnostics();
1719 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1720 StringRef ReproduceOption =
1721 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1724 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1728 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1730 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1731 Diag(clang::diag::note_drv_command_failed_diag_msg)
1732 <<
"\n\n********************";
1742 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1743 bool IgnoreInput =
false;
1749 }
else if (!strcmp(it->second->getValue(),
"-")) {
1750 Diag(clang::diag::note_drv_command_failed_diag_msg)
1751 <<
"Error generating preprocessed source(s) - "
1752 "ignoring input from stdin.";
1757 it = Inputs.erase(it);
1764 if (Inputs.empty()) {
1765 Diag(clang::diag::note_drv_command_failed_diag_msg)
1766 <<
"Error generating preprocessed source(s) - "
1767 "no preprocessable inputs.";
1773 llvm::StringSet<> ArchNames;
1774 for (
const Arg *A :
C.getArgs()) {
1775 if (A->getOption().matches(options::OPT_arch)) {
1776 StringRef ArchName = A->getValue();
1777 ArchNames.insert(ArchName);
1780 if (ArchNames.size() > 1) {
1781 Diag(clang::diag::note_drv_command_failed_diag_msg)
1782 <<
"Error generating preprocessed source(s) - cannot generate "
1783 "preprocessed source with multiple -arch options.";
1789 const ToolChain &TC =
C.getDefaultToolChain();
1790 if (TC.
getTriple().isOSBinFormatMachO())
1799 Diag(clang::diag::note_drv_command_failed_diag_msg)
1800 <<
"Error generating preprocessed source(s).";
1806 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1809 if (!FailingCommands.empty()) {
1810 Diag(clang::diag::note_drv_command_failed_diag_msg)
1811 <<
"Error generating preprocessed source(s).";
1815 const ArgStringList &TempFiles =
C.getTempFiles();
1816 if (TempFiles.empty()) {
1817 Diag(clang::diag::note_drv_command_failed_diag_msg)
1818 <<
"Error generating preprocessed source(s).";
1826 for (
const char *TempFile : TempFiles) {
1827 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
1830 if (ReproCrashFilename.empty()) {
1831 ReproCrashFilename = TempFile;
1832 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
1834 if (StringRef(TempFile).ends_with(
".cache")) {
1837 VFS = llvm::sys::path::filename(TempFile);
1838 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
1842 for (
const char *TempFile : SavedTemps)
1843 C.addTempFile(TempFile);
1849 llvm::sys::path::replace_extension(Script,
"sh");
1851 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
1852 llvm::sys::fs::FA_Write,
1853 llvm::sys::fs::OF_Text);
1855 Diag(clang::diag::note_drv_command_failed_diag_msg)
1856 <<
"Error generating run script: " << Script <<
" " << EC.message();
1859 <<
"# Driver args: ";
1861 ScriptOS <<
"# Original command: ";
1862 Cmd.Print(ScriptOS,
"\n",
true);
1863 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
1864 if (!AdditionalInformation.empty())
1865 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
1869 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
1873 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
1875 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
1876 Diag(clang::diag::note_drv_command_failed_diag_msg)
1877 << ReproCrashFilename.str();
1879 llvm::sys::path::append(CrashDiagDir,
Name);
1880 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
1881 Diag(clang::diag::note_drv_command_failed_diag_msg)
1882 <<
"Crash backtrace is located in";
1883 Diag(clang::diag::note_drv_command_failed_diag_msg)
1884 << CrashDiagDir.str();
1885 Diag(clang::diag::note_drv_command_failed_diag_msg)
1886 <<
"(choose the .crash file that corresponds to your crash)";
1890 Diag(clang::diag::note_drv_command_failed_diag_msg)
1891 <<
"\n\n********************";
1899 if (
Cmd.getResponseFileSupport().ResponseKind ==
1901 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
1902 Cmd.getArguments()))
1906 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
1912 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
1913 if (
C.getArgs().hasArg(options::OPT_v))
1914 C.getJobs().Print(llvm::errs(),
"\n",
true);
1916 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
1926 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
1927 C.getJobs().Print(llvm::errs(),
"\n",
true);
1936 for (
auto &Job :
C.getJobs())
1937 setUpResponseFiles(
C, Job);
1939 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1942 if (FailingCommands.empty())
1948 for (
const auto &CmdPair : FailingCommands) {
1949 int CommandRes = CmdPair.first;
1950 const Command *FailingCommand = CmdPair.second;
1955 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
1959 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
1964 if (CommandRes == EX_IOERR) {
1981 Diag(clang::diag::err_drv_command_signalled)
1984 Diag(clang::diag::err_drv_command_failed)
1992 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
1994 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2008 const ToolChain &TC =
C.getDefaultToolChain();
2012 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2015 OS <<
"Thread model: " << A->getValue();
2021 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2026 if (!llvm::cl::getCompilerBuildConfig().empty())
2027 llvm::cl::printBuildConfig(OS);
2030 for (
auto ConfigFile : ConfigFiles)
2031 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2044 if (PassedFlags ==
"")
2048 std::vector<std::string> SuggestedCompletions;
2049 std::vector<std::string> Flags;
2061 const bool HasSpace = PassedFlags.ends_with(
",");
2065 StringRef TargetFlags = PassedFlags;
2066 while (TargetFlags !=
"") {
2068 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2069 Flags.push_back(std::string(CurFlag));
2074 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2077 const llvm::opt::OptTable &Opts =
getOpts();
2079 Cur = Flags.at(Flags.size() - 1);
2081 if (Flags.size() >= 2) {
2082 Prev = Flags.at(Flags.size() - 2);
2083 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2086 if (SuggestedCompletions.empty())
2087 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2094 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2095 llvm::outs() <<
'\n';
2101 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2105 SuggestedCompletions = Opts.findByPrefix(
2106 Cur, VisibilityMask,
2113 if (S.starts_with(Cur))
2114 SuggestedCompletions.push_back(std::string(S));
2121 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2122 if (
int X = A.compare_insensitive(B))
2124 return A.compare(B) > 0;
2127 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2134 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2135 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2139 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2142 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2146 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2151 if (
C.getArgs().hasArg(options::OPT_help) ||
2152 C.getArgs().hasArg(options::OPT__help_hidden)) {
2153 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2157 if (
C.getArgs().hasArg(options::OPT__version)) {
2163 if (
C.getArgs().hasArg(options::OPT_v) ||
2164 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2165 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2166 C.getArgs().hasArg(options::OPT_print_supported_extensions)) {
2168 SuppressMissingInputWarning =
true;
2171 if (
C.getArgs().hasArg(options::OPT_v)) {
2173 llvm::errs() <<
"System configuration file directory: "
2176 llvm::errs() <<
"User configuration file directory: "
2180 const ToolChain &TC =
C.getDefaultToolChain();
2182 if (
C.getArgs().hasArg(options::OPT_v))
2185 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2190 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2191 llvm::outs() <<
"programs: =";
2192 bool separator =
false;
2196 llvm::outs() << llvm::sys::EnvPathSeparator;
2197 llvm::outs() << Path;
2202 llvm::outs() << llvm::sys::EnvPathSeparator;
2203 llvm::outs() << Path;
2206 llvm::outs() <<
"\n";
2209 StringRef sysroot =
C.getSysRoot();
2213 llvm::outs() << llvm::sys::EnvPathSeparator;
2216 llvm::outs() << sysroot << Path.substr(1);
2218 llvm::outs() << Path;
2220 llvm::outs() <<
"\n";
2224 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2230 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2231 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2232 llvm::outs() << *RuntimePath <<
'\n';
2238 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2240 for (std::size_t I = 0; I != Flags.size(); I += 2)
2241 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2247 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2248 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2252 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2253 StringRef ProgName = A->getValue();
2256 if (! ProgName.empty())
2259 llvm::outs() <<
"\n";
2263 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2264 StringRef PassedFlags = A->getValue();
2269 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2275 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2278 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2284 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2290 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2293 std::set<llvm::StringRef> SortedFlags;
2294 for (
const auto &FlagEntry : ExpandedFlags)
2295 SortedFlags.insert(FlagEntry.getKey());
2296 for (
auto Flag : SortedFlags)
2297 llvm::outs() << Flag <<
'\n';
2301 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2304 llvm::outs() <<
".\n";
2307 assert(Suffix.front() ==
'/');
2308 llvm::outs() << Suffix.substr(1) <<
"\n";
2314 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2319 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2321 llvm::outs() << Triple.getTriple() <<
"\n";
2325 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2326 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2343 std::map<Action *, unsigned> &Ids,
2349 llvm::raw_string_ostream os(str);
2351 auto getSibIndent = [](
int K) -> Twine {
2355 Twine SibIndent = Indent + getSibIndent(Kind);
2359 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2361 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2362 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2363 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2364 bool IsFirst =
true;
2365 OA->doOnEachDependence(
2367 assert(TC &&
"Unknown host toolchain");
2379 os <<
":" << BoundArch;
2382 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2390 const char *Prefix =
"{";
2391 for (
Action *PreRequisite : *AL) {
2392 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2403 std::string offload_str;
2404 llvm::raw_string_ostream offload_os(offload_str);
2405 if (!isa<OffloadAction>(A)) {
2408 offload_os <<
", (" << S;
2415 auto getSelfIndent = [](
int K) -> Twine {
2419 unsigned Id = Ids.size();
2421 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2430 std::map<Action *, unsigned> Ids;
2431 for (
Action *A :
C.getActions())
2438 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2439 isa<AssembleJobAction>(A))
2447 DerivedArgList &Args =
C.getArgs();
2449 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2452 llvm::StringSet<> ArchNames;
2454 for (Arg *A : Args) {
2455 if (A->getOption().matches(options::OPT_arch)) {
2458 llvm::Triple::ArchType Arch =
2460 if (Arch == llvm::Triple::UnknownArch) {
2461 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2466 if (ArchNames.insert(A->getValue()).second)
2467 Archs.push_back(A->getValue());
2481 for (
Action* Act : SingleActions) {
2489 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2493 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2498 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2499 Actions.append(Inputs.begin(), Inputs.end());
2501 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2504 Arg *A = Args.getLastArg(options::OPT_g_Group);
2505 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2506 !A->getOption().matches(options::OPT_gstabs);
2514 if (Act->getType() == types::TY_Image) {
2516 Inputs.push_back(Actions.back());
2523 if (Args.hasArg(options::OPT_verify_debug_info)) {
2524 Action* LastAction = Actions.back();
2527 LastAction, types::TY_Nothing));
2546 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2547 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2559 std::string Nearest;
2560 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2561 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2562 <<
Value << Nearest;
2601 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2604 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2612 return types::TY_CXXUHeader;
2614 return types::TY_CXXSHeader;
2618 llvm_unreachable(
"should not be called in this case");
2620 return types::TY_CXXHUHeader;
2626 const llvm::opt::OptTable &Opts =
getOpts();
2630 types::ID InputType = types::TY_Nothing;
2631 Arg *InputTypeArg =
nullptr;
2634 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2635 options::OPT__SLASH_TP)) {
2636 InputTypeArg = TCTP;
2637 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2642 bool ShowNote =
false;
2644 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2646 Diag(clang::diag::warn_drv_overriding_option)
2647 <<
Previous->getSpelling() << A->getSpelling();
2653 Diag(clang::diag::note_drv_t_option_is_global);
2658 auto LastXArg = Args.getLastArgValue(options::OPT_x);
2659 const llvm::StringSet<> ValidXArgs = {
"cuda",
"hip",
"cui",
"hipi"};
2660 if (!
IsCLMode() || ValidXArgs.contains(LastXArg)) {
2661 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2662 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2663 if (LastXArg && LastInputArg &&
2664 LastInputArg->getIndex() < LastXArg->getIndex())
2665 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2669 if (
auto *A = Args.getLastArg(options::OPT_x))
2670 Diag(diag::err_drv_unsupported_opt_with_suggestion)
2671 << A->getAsString(Args) <<
"/TC' or '/TP";
2674 for (Arg *A : Args) {
2675 if (A->getOption().
getKind() == Option::InputClass) {
2676 const char *
Value = A->getValue();
2680 if (InputType == types::TY_Nothing) {
2683 InputTypeArg->claim();
2686 if (memcmp(
Value,
"-", 2) == 0) {
2688 Ty = types::TY_Fortran;
2690 Ty = types::TY_HLSL;
2699 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2700 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2701 : clang::diag::err_drv_unknown_stdin_type);
2710 if (
const char *Ext = strrchr(
Value,
'.'))
2719 Ty = types::TY_Object;
2730 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2731 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2732 << getTypeName(OldTy) << getTypeName(Ty);
2737 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2738 Ty == types::TY_Object)
2739 Ty = types::TY_LLVM_BC;
2747 if (Ty != types::TY_Object) {
2748 if (Args.hasArg(options::OPT_ObjC))
2749 Ty = types::TY_ObjC;
2750 else if (Args.hasArg(options::OPT_ObjCXX))
2751 Ty = types::TY_ObjCXX;
2758 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
2762 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2763 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2766 const char *Ext = strrchr(
Value,
'.');
2768 Ty = types::TY_Object;
2772 InputTypeArg->claim();
2776 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
2777 Args.hasArgNoClaim(options::OPT_hipstdpar))
2781 Inputs.push_back(std::make_pair(Ty, A));
2783 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2784 StringRef
Value = A->getValue();
2787 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2788 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2791 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2792 StringRef
Value = A->getValue();
2795 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2796 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2802 Inputs.push_back(std::make_pair(types::TY_Object, A));
2804 }
else if (A->getOption().matches(options::OPT_x)) {
2813 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2814 InputType = types::TY_Object;
2821 }
else if (A->getOption().getID() == options::OPT_U) {
2822 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
2823 StringRef Val = A->getValue(0);
2824 if (Val.find_first_of(
"/\\") != StringRef::npos) {
2826 Diag(diag::warn_slash_u_filename) << Val;
2827 Diag(diag::note_use_dashdash);
2831 if (
CCCIsCPP() && Inputs.empty()) {
2835 Inputs.push_back(std::make_pair(types::TY_C, A));
2842class OffloadingActionBuilder final {
2844 bool IsValid =
false;
2850 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
2853 std::map<Action *, const Arg *> HostActionToInputArgMap;
2856 class DeviceActionBuilder {
2860 enum ActionBuilderReturnCode {
2879 DerivedArgList &Args;
2888 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
2891 :
C(
C), Args(Args), Inputs(Inputs),
2892 AssociatedOffloadKind(AssociatedOffloadKind) {}
2893 virtual ~DeviceActionBuilder() {}
2898 virtual ActionBuilderReturnCode
2902 return ABRT_Inactive;
2907 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
2908 return ABRT_Inactive;
2912 virtual void appendTopLevelActions(
ActionList &AL) {}
2915 virtual void appendLinkDeviceActions(
ActionList &AL) {}
2928 virtual bool canUseBundlerUnbundler()
const {
return false; }
2932 bool isValid() {
return !ToolChains.empty(); }
2936 return AssociatedOffloadKind;
2942 class CudaActionBuilderBase :
public DeviceActionBuilder {
2946 bool CompileHostOnly =
false;
2947 bool CompileDeviceOnly =
false;
2949 bool EmitAsm =
false;
2959 TargetID(
const char *
ID) :
ID(
ID) {}
2960 operator const char *() {
return ID; }
2961 operator StringRef() {
return StringRef(
ID); }
2970 Action *CudaFatBinary =
nullptr;
2973 bool IsActive =
false;
2976 bool Relocatable =
false;
2979 CudaArch DefaultCudaArch = CudaArch::UNKNOWN;
2983 enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
2984 UseCUIDKind UseCUID = CUID_Hash;
2987 StringRef FixedCUID;
2990 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
2993 : DeviceActionBuilder(
C, Args, Inputs, OFKind) {
2995 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
2996 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
2997 options::OPT_fno_gpu_rdc,
false);
3000 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3007 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3008 assert(!GpuArchList.empty() &&
3009 "We should have at least one GPU architecture.");
3013 if (!(IA->getType() == types::TY_CUDA ||
3014 IA->getType() == types::TY_HIP ||
3015 IA->getType() == types::TY_PP_HIP)) {
3018 return ABRT_Inactive;
3024 if (CompileHostOnly)
3025 return ABRT_Success;
3028 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3029 : types::TY_CUDA_DEVICE;
3030 std::string CUID = FixedCUID.str();
3032 if (UseCUID == CUID_Random)
3033 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
3035 else if (UseCUID == CUID_Hash) {
3037 llvm::MD5::MD5Result Hash;
3039 llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
3041 Hasher.update(RealPath);
3042 for (
auto *A : Args) {
3043 if (A->getOption().matches(options::OPT_INPUT))
3045 Hasher.update(A->getAsString(Args));
3048 CUID = llvm::utohexstr(Hash.low(),
true);
3053 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3054 CudaDeviceActions.push_back(
3055 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3058 return ABRT_Success;
3062 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3066 if (UA->getType() == types::TY_Object && !Relocatable)
3067 return ABRT_Inactive;
3069 CudaDeviceActions.clear();
3070 auto *IA = cast<InputAction>(UA->getInputs().back());
3071 std::string
FileName = IA->getInputArg().getAsString(Args);
3077 const StringRef LibFileExt =
".lib";
3078 if (IA->getType() == types::TY_Object &&
3079 (!llvm::sys::path::has_extension(
FileName) ||
3081 llvm::sys::path::extension(
FileName).drop_front()) !=
3083 llvm::sys::path::extension(
FileName) == LibFileExt))
3084 return ABRT_Inactive;
3086 for (
auto Arch : GpuArchList) {
3087 CudaDeviceActions.push_back(UA);
3088 UA->registerDependentActionInfo(ToolChains[0], Arch,
3089 AssociatedOffloadKind);
3092 return ABRT_Success;
3095 return IsActive ? ABRT_Success : ABRT_Inactive;
3098 void appendTopLevelActions(
ActionList &AL)
override {
3100 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3102 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3107 if (CudaFatBinary) {
3108 AddTopLevel(CudaFatBinary, CudaArch::UNUSED);
3109 CudaDeviceActions.clear();
3110 CudaFatBinary =
nullptr;
3114 if (CudaDeviceActions.empty())
3120 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3121 "Expecting one action per GPU architecture.");
3122 assert(ToolChains.size() == 1 &&
3123 "Expecting to have a single CUDA toolchain.");
3124 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3125 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3127 CudaDeviceActions.clear();
3132 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3134 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3152 assert(HostTC &&
"No toolchain for host compilation.");
3154 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3158 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3163 ToolChains.push_back(
3168 CompileHostOnly =
C.getDriver().offloadHostOnly();
3169 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3170 EmitAsm = Args.getLastArg(options::OPT_S);
3171 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3172 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3173 StringRef UseCUIDStr = A->getValue();
3174 UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3175 .Case(
"hash", CUID_Hash)
3176 .Case(
"random", CUID_Random)
3177 .Case(
"none", CUID_None)
3178 .Default(CUID_Invalid);
3179 if (UseCUID == CUID_Invalid) {
3180 C.getDriver().Diag(diag::err_drv_invalid_value)
3181 << A->getAsString(Args) << UseCUIDStr;
3182 C.setContainsError();
3188 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3189 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3190 options::OPT_no_offload_arch_EQ)) {
3191 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3196 std::set<StringRef> GpuArchs;
3198 for (Arg *A : Args) {
3199 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3200 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3204 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3205 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3208 }
else if (ArchStr ==
"native") {
3209 const ToolChain &TC = *ToolChains.front();
3210 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3213 << llvm::Triple::getArchTypeName(TC.
getArch())
3214 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3218 for (
auto GPU : *GPUsOrErr) {
3219 GpuArchs.insert(Args.MakeArgString(GPU));
3222 ArchStr = getCanonicalOffloadArch(ArchStr);
3223 if (ArchStr.empty()) {
3225 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3226 GpuArchs.insert(ArchStr);
3227 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3228 GpuArchs.erase(ArchStr);
3230 llvm_unreachable(
"Unexpected option.");
3236 if (ConflictingArchs) {
3237 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3238 << ConflictingArchs->first << ConflictingArchs->second;
3239 C.setContainsError();
3244 for (
auto Arch : GpuArchs)
3245 GpuArchList.push_back(Arch.data());
3250 if (GpuArchList.empty()) {
3251 if (ToolChains.front()->getTriple().isSPIRV())
3252 GpuArchList.push_back(CudaArch::Generic);
3254 GpuArchList.push_back(DefaultCudaArch);
3263 class CudaActionBuilder final :
public CudaActionBuilderBase {
3265 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3267 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3268 DefaultCudaArch = CudaArch::CudaDefault;
3271 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3274 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3280 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3282 const std::set<StringRef> &GpuArchs)
override {
3283 return std::nullopt;
3286 ActionBuilderReturnCode
3289 PhasesTy &Phases)
override {
3291 return ABRT_Inactive;
3295 if (CudaDeviceActions.empty())
3296 return ABRT_Success;
3298 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3299 "Expecting one action per GPU architecture.");
3300 assert(!CompileHostOnly &&
3301 "Not expecting CUDA actions in host-only compilation.");
3311 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3314 for (
auto Ph : Phases) {
3319 if (Ph > FinalPhase)
3322 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3332 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3336 Action *AssembleAction = CudaDeviceActions[I];
3337 assert(AssembleAction->
getType() == types::TY_Object);
3338 assert(AssembleAction->
getInputs().size() == 1);
3346 DeviceActions.push_back(
3352 if (!DeviceActions.empty()) {
3354 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3356 if (!CompileDeviceOnly) {
3357 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3361 CudaFatBinary =
nullptr;
3366 CudaDeviceActions.clear();
3370 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3375 return ABRT_Success;
3379 "instructions should only occur "
3380 "before the backend phase!");
3383 for (
Action *&A : CudaDeviceActions)
3384 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3386 return ABRT_Success;
3391 class HIPActionBuilder final :
public CudaActionBuilderBase {
3399 std::optional<bool> BundleOutput;
3400 std::optional<bool> EmitReloc;
3405 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3407 DefaultCudaArch = CudaArch::HIPDefault;
3409 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3410 options::OPT_fno_hip_emit_relocatable)) {
3411 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3412 options::OPT_fno_hip_emit_relocatable,
false);
3416 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3417 <<
"-fhip-emit-relocatable"
3421 if (!CompileDeviceOnly) {
3422 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3423 <<
"-fhip-emit-relocatable"
3424 <<
"--cuda-device-only";
3429 if (Args.hasArg(options::OPT_gpu_bundle_output,
3430 options::OPT_no_gpu_bundle_output))
3431 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3432 options::OPT_no_gpu_bundle_output,
true) &&
3433 (!EmitReloc || !*EmitReloc);
3436 bool canUseBundlerUnbundler()
const override {
return true; }
3438 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3439 llvm::StringMap<bool> Features;
3446 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3447 C.setContainsError();
3451 return Args.MakeArgStringRef(CanId);
3454 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3456 const std::set<StringRef> &GpuArchs)
override {
3460 ActionBuilderReturnCode
3463 PhasesTy &Phases)
override {
3465 return ABRT_Inactive;
3471 if (CudaDeviceActions.empty())
3472 return ABRT_Success;
3475 CudaDeviceActions.size() == GpuArchList.size()) &&
3476 "Expecting one action per GPU architecture.");
3477 assert(!CompileHostOnly &&
3478 "Not expecting HIP actions in host-only compilation.");
3480 bool ShouldLink = !EmitReloc || !*EmitReloc;
3483 !EmitAsm && ShouldLink) {
3489 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3490 if (
C.getDriver().isUsingLTO(
true)) {
3494 AL.push_back(CudaDeviceActions[I]);
3497 CudaDeviceActions[I] =
3504 if (ToolChains.front()->getTriple().isSPIRV()) {
3507 types::ID Output = Args.hasArg(options::OPT_S)
3509 : types::TY_LLVM_BC;
3515 AssociatedOffloadKind);
3516 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3518 AssociatedOffloadKind);
3519 AL.push_back(AssembleAction);
3522 CudaDeviceActions[I] =
3533 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3534 AssociatedOffloadKind);
3536 DDep, CudaDeviceActions[I]->getType());
3539 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3542 types::TY_HIP_FATBIN);
3544 if (!CompileDeviceOnly) {
3545 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3546 AssociatedOffloadKind);
3549 CudaFatBinary =
nullptr;
3554 CudaDeviceActions.clear();
3557 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3560 return ABRT_Success;
3566 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3567 auto LI = DeviceLinkerInputs.begin();
3568 for (
auto *A : CudaDeviceActions) {
3575 CudaDeviceActions.clear();
3576 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3580 for (
Action *&A : CudaDeviceActions)
3581 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3582 AssociatedOffloadKind);
3584 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3586 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3588 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3589 AssociatedOffloadKind);
3591 DDep, CudaDeviceActions[I]->getType());
3595 CudaDeviceActions.clear();
3598 return (CompileDeviceOnly &&
3599 (CurPhase == FinalPhase ||
3605 void appendLinkDeviceActions(
ActionList &AL)
override {
3606 if (DeviceLinkerInputs.size() == 0)
3609 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3610 "Linker inputs and GPU arch list sizes do not match.");
3616 for (
auto &LI : DeviceLinkerInputs) {
3618 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3622 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3626 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3627 GpuArchList[I], AssociatedOffloadKind);
3629 DeviceLinkDeps, DeviceLinkAction->getType()));
3632 DeviceLinkerInputs.clear();
3635 if (Args.hasArg(options::OPT_emit_llvm)) {
3644 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3647 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3648 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3649 AssociatedOffloadKind);
3652 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3658 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3674 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3682 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3685 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3693 unsigned ValidBuilders = 0u;
3694 unsigned ValidBuildersSupportingBundling = 0u;
3695 for (
auto *SB : SpecializedBuilders) {
3696 IsValid = IsValid && !SB->initialize();
3699 if (SB->isValid()) {
3701 if (SB->canUseBundlerUnbundler())
3702 ++ValidBuildersSupportingBundling;
3706 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3709 ~OffloadingActionBuilder() {
3710 for (
auto *SB : SpecializedBuilders)
3715 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3716 assert(HostAction &&
"Invalid host action");
3717 assert(InputArg &&
"Invalid input argument");
3718 auto Loc = HostActionToInputArgMap.find(HostAction);
3719 if (
Loc == HostActionToInputArgMap.end())
3720 HostActionToInputArgMap[HostAction] = InputArg;
3721 assert(HostActionToInputArgMap[HostAction] == InputArg &&
3722 "host action mapped to multiple input arguments");
3730 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3732 DeviceActionBuilder::PhasesTy &Phases) {
3736 if (SpecializedBuilders.empty())
3739 assert(HostAction &&
"Invalid host action!");
3740 recordHostAction(HostAction, InputArg);
3745 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3746 unsigned InactiveBuilders = 0u;
3747 unsigned IgnoringBuilders = 0u;
3748 for (
auto *SB : SpecializedBuilders) {
3749 if (!SB->isValid()) {
3754 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3759 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3764 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3765 OffloadKind |= SB->getAssociatedOffloadKind();
3770 if (IgnoringBuilders &&
3771 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3788 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3789 const Arg *InputArg) {
3793 recordHostAction(HostAction, InputArg);
3801 if (CanUseBundler && isa<InputAction>(HostAction) &&
3802 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3804 HostAction->
getType() == types::TY_PP_HIP)) {
3805 auto UnbundlingHostAction =
3810 HostAction = UnbundlingHostAction;
3811 recordHostAction(HostAction, InputArg);
3814 assert(HostAction &&
"Invalid host action!");
3817 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3818 for (
auto *SB : SpecializedBuilders) {
3822 auto RetCode = SB->addDeviceDependences(HostAction);
3826 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3827 "Host dependence not expected to be ignored.!");
3831 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3832 OffloadKind |= SB->getAssociatedOffloadKind();
3837 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
3847 const Arg *InputArg) {
3849 recordHostAction(HostAction, InputArg);
3853 for (
auto *SB : SpecializedBuilders) {
3856 SB->appendTopLevelActions(OffloadAL);
3863 if (CanUseBundler && HostAction &&
3864 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
3866 OffloadAL.push_back(HostAction);
3870 assert(HostAction == AL.back() &&
"Host action not in the list??");
3872 recordHostAction(HostAction, InputArg);
3873 AL.back() = HostAction;
3875 AL.append(OffloadAL.begin(), OffloadAL.end());
3885 void appendDeviceLinkActions(
ActionList &AL) {
3886 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3889 SB->appendLinkDeviceActions(AL);
3893 Action *makeHostLinkAction() {
3896 appendDeviceLinkActions(DeviceAL);
3897 if (DeviceAL.empty())
3902 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3905 HA = SB->appendLinkHostActions(DeviceAL);
3922 for (
auto *SB : SpecializedBuilders) {
3926 SB->appendLinkDependences(DDeps);
3930 unsigned ActiveOffloadKinds = 0u;
3931 for (
auto &I : InputArgToOffloadKindMap)
3932 ActiveOffloadKinds |= I.second;
3944 for (
auto *A : HostAction->
inputs()) {
3945 auto ArgLoc = HostActionToInputArgMap.find(A);
3946 if (ArgLoc == HostActionToInputArgMap.end())
3948 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
3949 if (OFKLoc == InputArgToOffloadKindMap.end())
3961 nullptr, ActiveOffloadKinds);
3967void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
3968 const InputList &Inputs,
3972 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3973 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3974 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3975 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3976 Args.eraseArg(options::OPT__SLASH_Yc);
3977 Args.eraseArg(options::OPT__SLASH_Yu);
3978 YcArg = YuArg =
nullptr;
3980 if (YcArg && Inputs.size() > 1) {
3981 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3982 Args.eraseArg(options::OPT__SLASH_Yc);
3990 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
3991 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
3992 Args.AddFlagArg(
nullptr,
3993 getOpts().getOption(options::OPT_frtlib_add_rpath));
3996 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
3997 Diag(clang::diag::err_drv_emit_llvm_link);
3999 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4000 .equals_insensitive(
"lld"))
4001 Diag(clang::diag::err_drv_lto_without_lld);
4007 if (!Args.hasArg(options::OPT_dumpdir)) {
4008 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4009 Arg *Arg = Args.MakeSeparateArg(
4010 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4012 (FinalOutput ? FinalOutput->getValue()
4024 Args.eraseArg(options::OPT__SLASH_Fp);
4025 Args.eraseArg(options::OPT__SLASH_Yc);
4026 Args.eraseArg(options::OPT__SLASH_Yu);
4027 YcArg = YuArg =
nullptr;
4030 unsigned LastPLSize = 0;
4031 for (
auto &I : Inputs) {
4033 const Arg *InputArg = I.second;
4036 LastPLSize = PL.size();
4041 if (InitialPhase > FinalPhase) {
4042 if (InputArg->isClaimed())
4049 if (Args.hasArg(options::OPT_Qunused_arguments))
4055 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4056 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4060 (Args.getLastArg(options::OPT__SLASH_EP,
4061 options::OPT__SLASH_P) ||
4062 Args.getLastArg(options::OPT_E) ||
4063 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4065 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4066 << InputArg->getAsString(Args) << !!FinalPhaseArg
4067 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4069 Diag(clang::diag::warn_drv_input_file_unused)
4070 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4072 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4085 Actions.push_back(ClangClPch);
4099 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4100 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4106 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4108 if (!SuppressMissingInputWarning && Inputs.empty()) {
4109 Diag(clang::diag::err_drv_no_input_files);
4114 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4115 StringRef
V = A->getValue();
4116 if (Inputs.size() > 1 && !
V.empty() &&
4117 !llvm::sys::path::is_separator(
V.back())) {
4119 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4120 << A->getSpelling() <<
V;
4121 Args.eraseArg(options::OPT__SLASH_Fo);
4126 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4127 StringRef
V = A->getValue();
4128 if (Inputs.size() > 1 && !
V.empty() &&
4129 !llvm::sys::path::is_separator(
V.back())) {
4131 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4132 << A->getSpelling() <<
V;
4133 Args.eraseArg(options::OPT__SLASH_Fa);
4138 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4139 if (A->getValue()[0] ==
'\0') {
4141 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4142 Args.eraseArg(options::OPT__SLASH_o);
4146 handleArguments(
C, Args, Inputs, Actions);
4148 bool UseNewOffloadingDriver =
4150 Args.hasFlag(options::OPT_offload_new_driver,
4151 options::OPT_no_offload_new_driver,
false);
4154 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4155 !UseNewOffloadingDriver
4156 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4164 for (
auto &I : Inputs) {
4166 const Arg *InputArg = I.second;
4179 if (!UseNewOffloadingDriver)
4180 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4186 if (!UseNewOffloadingDriver)
4187 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4188 Current, InputArg, Phase, PL.back(), FullPL);
4194 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4197 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4198 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4200 LinkerInputs.push_back(Current);
4210 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4211 MergerInputs.push_back(Current);
4229 if (NewCurrent == Current)
4232 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4235 Current = NewCurrent;
4239 if (UseNewOffloadingDriver)
4243 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4247 if (Current->getType() == types::TY_Nothing)
4253 Actions.push_back(Current);
4256 if (!UseNewOffloadingDriver)
4257 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4259 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4265 if (LinkerInputs.empty()) {
4268 if (!UseNewOffloadingDriver)
4269 OffloadBuilder->appendDeviceLinkActions(Actions);
4272 if (!LinkerInputs.empty()) {
4273 if (!UseNewOffloadingDriver)
4274 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4275 LinkerInputs.push_back(Wrapper);
4280 }
else if (UseNewOffloadingDriver ||
4281 Args.hasArg(options::OPT_offload_link)) {
4288 if (!UseNewOffloadingDriver)
4289 LA = OffloadBuilder->processHostLinkAction(LA);
4290 Actions.push_back(LA);
4294 if (!MergerInputs.empty())
4298 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4305 for (
auto &I : Inputs) {
4307 const Arg *InputArg = I.second;
4312 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4313 InputType == types::TY_Asm)
4318 for (
auto Phase : PhaseList) {
4322 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4327 if (InputType == types::TY_Object)
4334 assert(Phase == PhaseList.back() &&
4335 "merging must be final compilation step.");
4336 MergerInputs.push_back(Current);
4345 Actions.push_back(Current);
4349 if (!MergerInputs.empty())
4354 for (
auto Opt : {options::OPT_print_supported_cpus,
4355 options::OPT_print_supported_extensions}) {
4362 if (Arg *A = Args.getLastArg(Opt)) {
4363 if (Opt == options::OPT_print_supported_extensions &&
4364 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4365 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4366 !
C.getDefaultToolChain().getTriple().isARM()) {
4367 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4368 <<
"--print-supported-extensions";
4377 for (
auto &I : Inputs)
4383 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4387 if (TC.requiresValidation(Args)) {
4388 Action *LastAction = Actions.back();
4390 LastAction, types::TY_DX_CONTAINER));
4395 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4401 const llvm::opt::DerivedArgList &Args,
4403 const llvm::Triple &Triple,
4404 bool SuppressError =
false) {
4408 if (!SuppressError && Triple.isNVPTX() &&
4410 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4411 <<
"CUDA" << ArchStr;
4413 }
else if (!SuppressError && Triple.isAMDGPU() &&
4415 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4416 <<
"HIP" << ArchStr;
4424 llvm::StringMap<bool> Features;
4430 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4431 C.setContainsError();
4443static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4445 llvm::Triple Triple) {
4446 if (!Triple.isAMDGPU())
4447 return std::nullopt;
4449 std::set<StringRef> ArchSet;
4450 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4457 bool SuppressError)
const {
4459 TC = &
C.getDefaultToolChain();
4462 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4463 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4464 options::OPT_no_offload_arch_EQ)) {
4465 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4467 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4469 :
"--no-offload-arch");
4472 if (KnownArchs.contains(TC))
4473 return KnownArchs.lookup(TC);
4476 for (
auto *Arg : Args) {
4478 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4479 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4482 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4483 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4484 Arg = ExtractedArg.get();
4489 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4490 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4491 if (Arch ==
"native" || Arch.empty()) {
4495 llvm::consumeError(GPUsOrErr.takeError());
4498 << llvm::Triple::getArchTypeName(TC->
getArch())
4499 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4503 for (
auto ArchStr : *GPUsOrErr) {
4510 C, Args, Arch, TC->
getTriple(), SuppressError);
4511 if (ArchStr.empty())
4513 Archs.insert(ArchStr);
4516 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4517 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4518 if (Arch ==
"all") {
4522 C, Args, Arch, TC->
getTriple(), SuppressError);
4523 if (ArchStr.empty())
4525 Archs.erase(ArchStr);
4531 if (
auto ConflictingArchs =
4533 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4534 << ConflictingArchs->first << ConflictingArchs->second;
4535 C.setContainsError();
4542 if (Archs.empty()) {
4548 Archs.insert(StringRef());
4550 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4551 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4558 llvm::opt::DerivedArgList &Args,
4560 Action *HostAction)
const {
4565 !(isa<CompileJobAction>(HostAction) ||
4579 auto TCRange =
C.getOffloadToolChains(Kind);
4580 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4581 ToolChains.push_back(TI->second);
4583 if (ToolChains.empty())
4587 const Arg *InputArg = Input.second;
4598 TCAndArchs.push_back(std::make_pair(TC, Arch));
4600 for (
unsigned I = 0, E = TCAndArchs.size(); I != E; ++I)
4601 DeviceActions.push_back(
C.MakeAction<
InputAction>(*InputArg, InputType));
4603 if (DeviceActions.empty())
4610 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4614 auto TCAndArch = TCAndArchs.begin();
4615 for (
Action *&A : DeviceActions) {
4616 if (A->
getType() == types::TY_Nothing)
4624 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4626 HostAction->
getType() != types::TY_Nothing) {
4633 TCAndArch->second.data(), Kind);
4635 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4644 for (
Action *&A : DeviceActions) {
4645 if ((A->
getType() != types::TY_Object &&
4646 A->
getType() != types::TY_LTO_BC) ||
4648 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4654 auto TCAndArch = TCAndArchs.begin();
4655 for (
Action *A : DeviceActions) {
4656 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4658 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4663 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4665 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4673 bool ShouldBundleHIP =
4675 Args.hasFlag(options::OPT_gpu_bundle_output,
4676 options::OPT_no_gpu_bundle_output,
true) &&
4677 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4678 !llvm::any_of(OffloadActions,
4685 if (OffloadActions.empty())
4690 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4694 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4698 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4703 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4712 nullptr,
C.getActiveOffloadKinds());
4721 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4722 return A->
getType() == types::TY_Nothing;
4723 }) && isa<CompileJobAction>(HostAction);
4726 nullptr, SingleDeviceOutput ? DDep : DDeps);
4727 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4733 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4744 llvm_unreachable(
"link action invalid here.");
4746 llvm_unreachable(
"ifsmerge action invalid here.");
4751 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4752 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4753 OutputTy = types::TY_Dependencies;
4758 if (!Args.hasFlag(options::OPT_frewrite_includes,
4759 options::OPT_fno_rewrite_includes,
false) &&
4760 !Args.hasFlag(options::OPT_frewrite_imports,
4761 options::OPT_fno_rewrite_imports,
false) &&
4762 !Args.hasFlag(options::OPT_fdirectives_only,
4763 options::OPT_fno_directives_only,
false) &&
4767 "Cannot preprocess this input type!");
4773 if (Args.hasArg(options::OPT_extract_api))
4780 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
4781 !Args.getLastArg(options::OPT__precompile))
4786 "Cannot precompile this input type!");
4790 const char *ModName =
nullptr;
4791 if (OutputTy == types::TY_PCH) {
4792 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4793 ModName = A->getValue();
4795 OutputTy = types::TY_ModuleFile;
4798 if (Args.hasArg(options::OPT_fsyntax_only)) {
4800 OutputTy = types::TY_Nothing;
4806 if (Args.hasArg(options::OPT_fsyntax_only))
4808 if (Args.hasArg(options::OPT_rewrite_objc))
4810 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
4812 types::TY_RewrittenLegacyObjC);
4813 if (Args.hasArg(options::OPT__analyze))
4815 if (Args.hasArg(options::OPT__migrate))
4817 if (Args.hasArg(options::OPT_emit_ast))
4819 if (Args.hasArg(options::OPT_emit_cir))
4821 if (Args.hasArg(options::OPT_module_file_info))
4823 if (Args.hasArg(options::OPT_verify_pch))
4825 if (Args.hasArg(options::OPT_extract_api))
4832 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
4833 !Args.hasArg(options::OPT_emit_llvm))
4834 Output = types::TY_PP_Asm;
4835 else if (Args.hasArg(options::OPT_S))
4836 Output = types::TY_LTO_IR;
4838 Output = types::TY_LTO_BC;
4844 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
4847 if (Args.hasArg(options::OPT_emit_llvm) ||
4851 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4855 Args.hasArg(options::OPT_S) &&
4859 !Args.hasFlag(options::OPT_offload_new_driver,
4860 options::OPT_no_offload_new_driver,
false)))
4862 : types::TY_LLVM_BC;
4871 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4875 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4877 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
4897 unsigned NumOutputs = 0;
4898 unsigned NumIfsOutputs = 0;
4899 for (
const Action *A :
C.getActions()) {
4900 if (A->
getType() != types::TY_Nothing &&
4901 A->
getType() != types::TY_DX_CONTAINER &&
4903 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
4905 0 == NumIfsOutputs++) ||
4910 A->
getType() == types::TY_Nothing &&
4911 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
4912 NumOutputs += A->
size();
4915 if (NumOutputs > 1) {
4916 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
4917 FinalOutput =
nullptr;
4921 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
4924 llvm::StringSet<> ArchNames;
4925 if (RawTriple.isOSBinFormatMachO())
4926 for (
const Arg *A :
C.getArgs())
4927 if (A->getOption().matches(options::OPT_arch))
4928 ArchNames.insert(A->getValue());
4931 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
4932 for (
Action *A :
C.getActions()) {
4939 const char *LinkingOutput =
nullptr;
4940 if (isa<LipoJobAction>(A)) {
4942 LinkingOutput = FinalOutput->getValue();
4950 ArchNames.size() > 1,
4951 LinkingOutput, CachedResults,
4958 for (
auto &J :
C.getJobs())
4959 J.InProcess =
false;
4962 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
4963 std::optional<llvm::sys::ProcessStatistics> ProcStat =
4964 Cmd.getProcessStatistics();
4968 const char *LinkingOutput =
nullptr;
4970 LinkingOutput = FinalOutput->getValue();
4971 else if (!
Cmd.getOutputFilenames().empty())
4972 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
4977 using namespace llvm;
4979 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
4980 <<
"output=" << LinkingOutput;
4981 outs() <<
", total="
4982 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
4984 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
4985 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
4989 llvm::raw_string_ostream Out(Buffer);
4990 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
4993 llvm::sys::printArg(Out, LinkingOutput, true);
4994 Out <<
',' << ProcStat->TotalTime.count() <<
','
4995 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
4999 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5000 llvm::sys::fs::OF_Append |
5001 llvm::sys::fs::OF_Text);
5006 llvm::errs() <<
"ERROR: Cannot lock file "
5007 << CCPrintStatReportFilename <<
": "
5008 << toString(L.takeError()) <<
"\n";
5019 if (Diags.hasErrorOccurred() ||
5020 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5024 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5026 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5029 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5030 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5032 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5036 return strstr(J.getCreator().getShortName(),
"assembler");
5038 for (Arg *A :
C.getArgs()) {
5042 if (!A->isClaimed()) {
5048 const Option &Opt = A->getOption();
5049 if (Opt.getKind() == Option::FlagClass) {
5050 bool DuplicateClaimed =
false;
5052 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5053 if (AA->isClaimed()) {
5054 DuplicateClaimed =
true;
5059 if (DuplicateClaimed)
5065 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5067 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5072 !
C.getActions().empty()) {
5073 Diag(diag::err_drv_unsupported_opt_for_target)
5074 << A->getSpelling() << getTargetTriple();
5076 Diag(clang::diag::warn_drv_unused_argument)
5077 << A->getAsString(
C.getArgs());
5087class ToolSelector final {
5098 bool IsHostSelector;
5109 bool CanBeCollapsed =
true) {
5111 if (Inputs.size() != 1)
5114 Action *CurAction = *Inputs.begin();
5115 if (CanBeCollapsed &&
5121 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5125 if (!IsHostSelector) {
5126 if (OA->hasSingleDeviceDependence(
true)) {
5128 OA->getSingleDeviceDependence(
true);
5129 if (CanBeCollapsed &&
5132 SavedOffloadAction.push_back(OA);
5133 return dyn_cast<JobAction>(CurAction);
5135 }
else if (OA->hasHostDependence()) {
5136 CurAction = OA->getHostDependence();
5137 if (CanBeCollapsed &&
5140 SavedOffloadAction.push_back(OA);
5141 return dyn_cast<JobAction>(CurAction);
5146 return dyn_cast<JobAction>(CurAction);
5150 bool canCollapseAssembleAction()
const {
5151 return TC.useIntegratedAs() && !SaveTemps &&
5152 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5153 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5154 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5155 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5159 bool canCollapsePreprocessorAction()
const {
5160 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5161 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5162 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5167 struct JobActionInfo final {
5177 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5179 unsigned ElementNum) {
5180 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5181 for (
unsigned I = 0; I < ElementNum; ++I)
5182 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5183 ActionInfo[I].SavedOffloadAction.end());
5199 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5201 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5202 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5203 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5204 if (!AJ || !BJ || !CJ)
5208 const Tool *
T = TC.SelectTool(*CJ);
5215 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5221 const Tool *BT = TC.SelectTool(*BJ);
5226 if (!
T->hasIntegratedAssembler())
5229 Inputs = CJ->getInputs();
5230 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5237 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5239 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5240 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5245 const Tool *
T = TC.SelectTool(*BJ);
5249 if (!
T->hasIntegratedAssembler())
5252 Inputs = BJ->getInputs();
5253 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5260 if (ActionInfo.size() < 2)
5262 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5263 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5272 bool InputIsBitcode =
true;
5273 for (
size_t i = 1; i < ActionInfo.size(); i++)
5274 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5275 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5276 InputIsBitcode =
false;
5279 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5283 const Tool *
T = TC.SelectTool(*CJ);
5290 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5293 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5296 Inputs = CJ->getInputs();
5297 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5308 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5314 for (
Action *A : Inputs) {
5315 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5316 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5317 NewInputs.push_back(A);
5323 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5324 PreprocessJobOffloadActions.end());
5325 NewInputs.append(PJ->input_begin(), PJ->input_end());
5333 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5335 assert(BaseAction &&
"Invalid base action.");
5352 ActionChain.back().JA = BaseAction;
5353 while (ActionChain.back().JA) {
5354 const Action *CurAction = ActionChain.back().JA;
5357 ActionChain.resize(ActionChain.size() + 1);
5358 JobActionInfo &AI = ActionChain.back();
5362 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5366 ActionChain.pop_back();
5374 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5375 CollapsedOffloadAction);
5377 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5379 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5385 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5397 StringRef BoundArch,
5399 std::string TriplePlusArch = TC->
getTriple().normalize();
5400 if (!BoundArch.empty()) {
5401 TriplePlusArch +=
"-";
5402 TriplePlusArch += BoundArch;
5404 TriplePlusArch +=
"-";
5406 return TriplePlusArch;
5411 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5412 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5415 std::pair<const Action *, std::string> ActionTC = {
5417 auto CachedResult = CachedResults.find(ActionTC);
5418 if (CachedResult != CachedResults.end()) {
5419 return CachedResult->second;
5422 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5423 CachedResults, TargetDeviceOffloadKind);
5424 CachedResults[ActionTC] =
Result;
5429 const JobAction *JA,
const char *BaseInput,
5432 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5436 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5437 Path = A->getValue();
5438 if (llvm::sys::fs::is_directory(Path)) {
5440 llvm::sys::path::replace_extension(Tmp,
"json");
5441 llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
5444 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5447 Path = DumpDir->getValue();
5448 Path += llvm::sys::path::filename(BaseInput);
5450 Path =
Result.getFilename();
5452 llvm::sys::path::replace_extension(Path,
"json");
5454 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5455 C.addTimeTraceFile(ResultFile, JA);
5456 C.addResultFile(ResultFile, JA);
5461 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5462 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5465 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5468 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5501 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5503 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5504 const char *DepBoundArch) {
5507 LinkingOutput, CachedResults,
5517 OA->doOnEachDependence(
5518 BuildingForOffloadDevice,
5521 C, DepA, DepTC, DepBoundArch,
false,
5522 !!DepBoundArch, LinkingOutput, CachedResults,
5526 A = BuildingForOffloadDevice
5527 ? OA->getSingleDeviceDependence(
true)
5528 : OA->getHostDependence();
5532 std::pair<const Action *, std::string> ActionTC = {
5533 OA->getHostDependence(),
5535 if (CachedResults.find(ActionTC) != CachedResults.end()) {
5537 Inputs.append(OffloadDependencesInputInfo);
5542 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5545 const Arg &Input = IA->getInputArg();
5547 if (Input.getOption().matches(options::OPT_INPUT)) {
5548 const char *
Name = Input.getValue();
5558 if (!ArchName.empty())
5559 TC = &getToolChain(
C.getArgs(),
5561 C.getArgs(), ArchName));
5563 TC = &
C.getDefaultToolChain();
5566 MultipleArchs, LinkingOutput, CachedResults,
5567 TargetDeviceOffloadKind);
5573 const JobAction *JA = cast<JobAction>(A);
5578 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5585 for (
const auto *OA : CollapsedOffloadActions)
5586 cast<OffloadAction>(OA)->doOnEachDependence(
5587 BuildingForOffloadDevice,
5590 C, DepA, DepTC, DepBoundArch,
false,
5591 !!DepBoundArch, LinkingOutput, CachedResults,
5597 for (
const Action *Input : Inputs) {
5601 bool SubJobAtTopLevel =
5602 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5604 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5609 const char *BaseInput = InputInfos[0].getBaseInput();
5610 for (
auto &Info : InputInfos) {
5611 if (Info.isFilename()) {
5612 BaseInput = Info.getBaseInput();
5619 if (JA->
getType() == types::TY_dSYM)
5620 BaseInput = InputInfos[0].getFilename();
5623 if (!OffloadDependencesInputInfo.empty())
5624 InputInfos.append(OffloadDependencesInputInfo.begin(),
5625 OffloadDependencesInputInfo.end());
5628 llvm::Triple EffectiveTriple;
5630 const ArgList &Args =
5632 if (InputInfos.size() != 1) {
5636 EffectiveTriple = llvm::Triple(
5644 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5648 for (
auto &UI : UA->getDependentActionsInfo()) {
5650 "Unbundling with no offloading??");
5657 UI.DependentOffloadKind,
5658 UI.DependentToolChain->getTriple().normalize(),
5669 UnbundlingResults.push_back(CurI);
5678 Arch = UI.DependentBoundArch;
5683 UI.DependentOffloadKind)}] = {
5689 std::pair<const Action *, std::string> ActionTC = {
5691 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5692 "Result does not exist??");
5693 Result = CachedResults[ActionTC].front();
5694 }
else if (JA->
getType() == types::TY_Nothing)
5701 isa<OffloadPackagerJobAction>(A) ||
5705 AtTopLevel, MultipleArchs,
5708 if (
T->canEmitIR() && OffloadingPrefix.empty())
5713 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5714 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5715 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5716 llvm::errs() << InputInfos[i].getAsString();
5718 llvm::errs() <<
", ";
5720 if (UnbundlingResults.empty())
5721 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5723 llvm::errs() <<
"], outputs: [";
5724 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5725 llvm::errs() << UnbundlingResults[i].getAsString();
5727 llvm::errs() <<
", ";
5729 llvm::errs() <<
"] \n";
5732 if (UnbundlingResults.empty())
5738 T->ConstructJobMultipleOutputs(
5739 C, *JA, UnbundlingResults, InputInfos,
5747 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5748 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5760 if (ArgValue.empty()) {
5763 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
5765 llvm::sys::path::append(
Filename, BaseName);
5768 if (!llvm::sys::path::has_extension(ArgValue)) {
5773 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5778 llvm::sys::path::replace_extension(
Filename, Extension);
5781 return Args.MakeArgString(
Filename.c_str());
5785 if (isa<PreprocessJobAction>(JA))
5787 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
5789 if (isa<OffloadBundlingJobAction>(JA) &&
5796 StringRef Suffix,
bool MultipleArchs,
5797 StringRef BoundArch,
5798 bool NeedUniqueDirectory)
const {
5800 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
5801 std::optional<std::string> CrashDirectory =
5803 ? std::string(A->getValue())
5804 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
5805 if (CrashDirectory) {
5806 if (!
getVFS().exists(*CrashDirectory))
5807 llvm::sys::fs::create_directories(*CrashDirectory);
5809 llvm::sys::path::append(Path, Prefix);
5810 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
5811 if (std::error_code EC =
5812 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
5813 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
5817 if (MultipleArchs && !BoundArch.empty()) {
5818 if (NeedUniqueDirectory) {
5820 llvm::sys::path::append(TmpName,
5821 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
5831 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5846 const char *BaseInput) {
5847 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
5848 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
5849 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
5854 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
5858 const char *BaseInput,
5859 StringRef OrigBoundArch,
bool AtTopLevel,
5861 StringRef OffloadingPrefix)
const {
5862 std::string BoundArch = OrigBoundArch.str();
5863 if (is_style_windows(llvm::sys::path::Style::native)) {
5866 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
5869 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
5871 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
5872 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
5873 return C.addResultFile(FinalOutput->getValue(), &JA);
5877 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
5878 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
5879 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5881 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
5882 NameArg = A->getValue();
5883 return C.addResultFile(
5893 if (JA.
getType() == types::TY_ModuleFile &&
5894 C.getArgs().getLastArg(options::OPT_module_file_info)) {
5898 if (JA.
getType() == types::TY_PP_Asm &&
5899 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
5900 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
5903 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
5906 if (JA.
getType() == types::TY_Object &&
5907 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
5908 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
5911 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
5915 if (JA.
getType() == types::TY_PP_Asm &&
5916 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
5917 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
5919 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5920 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
5921 return C.addResultFile(
5926 if (JA.
getType() == types::TY_API_INFO &&
5927 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
5928 C.getArgs().hasArg(options::OPT_o))
5929 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
5930 <<
C.getArgs().getLastArgValue(options::OPT_o);
5937 bool SpecifiedModuleOutput =
5938 C.getArgs().hasArg(options::OPT_fmodule_output) ||
5939 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
5940 if (MultipleArchs && SpecifiedModuleOutput)
5941 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
5945 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
5946 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
5947 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
5953 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
5955 StringRef
Name = llvm::sys::path::filename(BaseInput);
5956 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5957 const char *Suffix =
5962 llvm::Triple Triple(
C.getDriver().getTargetTriple());
5963 bool NeedUniqueDirectory =
5966 Triple.isOSDarwin();
5967 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
5968 NeedUniqueDirectory);
5976 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
5977 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
5982 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
5983 llvm::sys::path::filename(BasePath));
5984 BaseName = ExternalPath;
5985 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
5986 BaseName = BasePath;
5988 BaseName = llvm::sys::path::filename(BasePath);
5991 const char *NamedOutput;
5993 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
5994 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
5998 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6002 }
else if (JA.
getType() == types::TY_Image &&
6003 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6004 options::OPT__SLASH_o)) {
6008 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6012 }
else if (JA.
getType() == types::TY_Image) {
6022 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6023 options::OPT_fno_gpu_rdc,
false);
6024 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6025 if (UseOutExtension) {
6027 llvm::sys::path::replace_extension(Output,
"");
6029 Output += OffloadingPrefix;
6030 if (MultipleArchs && !BoundArch.empty()) {
6032 Output.append(BoundArch);
6034 if (UseOutExtension)
6036 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6039 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6040 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6041 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6044 .getLastArg(options::OPT__SLASH_o)
6049 const char *Suffix =
6051 assert(Suffix &&
"All types used for output should have a suffix.");
6053 std::string::size_type End = std::string::npos;
6055 End = BaseName.rfind(
'.');
6057 Suffixed += OffloadingPrefix;
6058 if (MultipleArchs && !BoundArch.empty()) {
6060 Suffixed.append(BoundArch);
6065 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6066 const llvm::opt::DerivedArgList &Args) {
6071 return isa<CompileJobAction>(JA) &&
6073 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6078 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6079 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6080 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6084 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6088 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6089 JA.
getType() != types::TY_PCH) {
6090 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6092 llvm::sys::path::remove_filename(TempPath);
6093 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6094 llvm::sys::path::append(TempPath, OutputFileName);
6095 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6101 bool SameFile =
false;
6103 llvm::sys::fs::current_path(
Result);
6104 llvm::sys::path::append(
Result, BaseName);
6105 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6108 StringRef
Name = llvm::sys::path::filename(BaseInput);
6109 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6113 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6119 llvm::sys::path::remove_filename(BasePath);
6120 if (BasePath.empty())
6121 BasePath = NamedOutput;
6123 llvm::sys::path::append(BasePath, NamedOutput);
6124 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6127 return C.addResultFile(NamedOutput, &JA);
6133 -> std::optional<std::string> {
6136 for (
const auto &
Dir :
P) {
6140 llvm::sys::path::append(
P,
Name);
6141 if (llvm::sys::fs::exists(Twine(
P)))
6142 return std::string(
P);
6144 return std::nullopt;
6151 llvm::sys::path::append(R,
Name);
6152 if (llvm::sys::fs::exists(Twine(R)))
6153 return std::string(R);
6156 llvm::sys::path::append(
P,
Name);
6157 if (llvm::sys::fs::exists(Twine(
P)))
6158 return std::string(
P);
6161 llvm::sys::path::append(D,
"..",
Name);
6162 if (llvm::sys::fs::exists(Twine(D)))
6163 return std::string(D);
6171 return std::string(
Name);
6174void Driver::generatePrefixedToolNames(
6178 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6179 Names.emplace_back(
Tool);
6183 llvm::sys::path::append(Dir, Name);
6184 if (llvm::sys::fs::can_execute(Twine(Dir)))
6186 llvm::sys::path::remove_filename(Dir);
6192 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6197 if (llvm::sys::fs::is_directory(PrefixDir)) {
6200 return std::string(
P);
6203 if (llvm::sys::fs::can_execute(Twine(
P)))
6204 return std::string(
P);
6209 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6217 for (
const auto &Path : List) {
6220 return std::string(
P);
6224 if (llvm::ErrorOr<std::string>
P =
6225 llvm::sys::findProgramByName(TargetSpecificExecutable))
6229 return std::string(
Name);
6234 std::string error =
"<NOT PRESENT>";
6238 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6255 llvm::sys::path::remove_filename(path);
6256 llvm::sys::path::append(path,
"libc++.modules.json");
6257 if (TC.
getVFS().exists(path))
6258 return static_cast<std::string
>(path);
6263 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6266 return evaluate(
"libc++.a").value_or(error);
6279 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6281 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6285 return std::string(Path);
6290 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6292 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6296 return std::string(Path);
6301 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6305 Output = FpArg->getValue();
6309 if (!llvm::sys::path::has_extension(Output))
6312 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6313 Output = YcArg->getValue();
6316 llvm::sys::path::replace_extension(Output,
".pch");
6318 return std::string(Output);
6321const ToolChain &Driver::getToolChain(
const ArgList &Args,
6322 const llvm::Triple &
Target)
const {
6324 auto &TC = ToolChains[
Target.str()];
6326 switch (
Target.getOS()) {
6327 case llvm::Triple::AIX:
6328 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6330 case llvm::Triple::Haiku:
6331 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6333 case llvm::Triple::Darwin:
6334 case llvm::Triple::MacOSX:
6335 case llvm::Triple::IOS:
6336 case llvm::Triple::TvOS:
6337 case llvm::Triple::WatchOS:
6338 case llvm::Triple::XROS:
6339 case llvm::Triple::DriverKit:
6340 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6342 case llvm::Triple::DragonFly:
6343 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6345 case llvm::Triple::OpenBSD:
6346 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6348 case llvm::Triple::NetBSD:
6349 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6351 case llvm::Triple::FreeBSD:
6353 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6356 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6358 case llvm::Triple::Linux:
6359 case llvm::Triple::ELFIAMCU:
6360 if (
Target.getArch() == llvm::Triple::hexagon)
6361 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6363 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6364 !
Target.hasEnvironment())
6365 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6368 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6370 else if (
Target.getArch() == llvm::Triple::ve)
6371 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6372 else if (
Target.isOHOSFamily())
6373 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6375 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6377 case llvm::Triple::NaCl:
6378 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6380 case llvm::Triple::Fuchsia:
6381 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6383 case llvm::Triple::Solaris:
6384 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6386 case llvm::Triple::CUDA:
6387 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6389 case llvm::Triple::AMDHSA:
6390 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6392 case llvm::Triple::AMDPAL:
6393 case llvm::Triple::Mesa3D:
6394 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6396 case llvm::Triple::Win32:
6397 switch (
Target.getEnvironment()) {
6399 if (
Target.isOSBinFormatELF())
6400 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6401 else if (
Target.isOSBinFormatMachO())
6402 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6404 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6406 case llvm::Triple::GNU:
6407 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6409 case llvm::Triple::Itanium:
6410 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6413 case llvm::Triple::MSVC:
6414 case llvm::Triple::UnknownEnvironment:
6415 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6416 .starts_with_insensitive(
"bfd"))
6417 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6421 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6425 case llvm::Triple::PS4:
6426 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6428 case llvm::Triple::PS5:
6429 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6431 case llvm::Triple::Hurd:
6432 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6434 case llvm::Triple::LiteOS:
6435 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6437 case llvm::Triple::ZOS:
6438 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6440 case llvm::Triple::ShaderModel:
6441 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6446 switch (
Target.getArch()) {
6447 case llvm::Triple::tce:
6448 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6450 case llvm::Triple::tcele:
6451 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6453 case llvm::Triple::hexagon:
6454 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6457 case llvm::Triple::lanai:
6458 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6460 case llvm::Triple::xcore:
6461 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6463 case llvm::Triple::wasm32:
6464 case llvm::Triple::wasm64:
6465 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6467 case llvm::Triple::avr:
6468 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6470 case llvm::Triple::msp430:
6472 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6474 case llvm::Triple::riscv32:
6475 case llvm::Triple::riscv64:
6478 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6480 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6482 case llvm::Triple::ve:
6483 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6485 case llvm::Triple::spirv32:
6486 case llvm::Triple::spirv64:
6487 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6489 case llvm::Triple::csky:
6490 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6494 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6495 else if (
Target.isOSBinFormatELF())
6496 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6497 else if (
Target.isOSBinFormatMachO())
6498 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6500 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6508const ToolChain &Driver::getOffloadingDeviceToolChain(
6509 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6518 switch (TargetDeviceOffloadKind) {
6520 if (
Target.getArch() == llvm::Triple::amdgcn &&
6521 Target.getVendor() == llvm::Triple::AMD &&
6522 Target.getOS() == llvm::Triple::AMDHSA)
6523 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6525 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6526 Target.getVendor() == llvm::Triple::UnknownVendor &&
6527 Target.getOS() == llvm::Triple::UnknownOS)
6528 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6542 if (JA.
size() != 1 ||
6547 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6548 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6549 !isa<ExtractAPIJobAction>(JA))
6557 if (JA.
size() != 1 ||
6562 if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) &&
6563 !isa<BackendJobAction>(JA))
6571 if (Args.hasArg(options::OPT_emit_static_lib))
6582 unsigned &Micro,
bool &HadExtra) {
6585 Major = Minor = Micro = 0;
6589 if (Str.consumeInteger(10, Major))
6593 if (!Str.consume_front(
"."))
6596 if (Str.consumeInteger(10, Minor))
6600 if (!Str.consume_front(
"."))
6603 if (Str.consumeInteger(10, Micro))
6621 unsigned CurDigit = 0;
6622 while (CurDigit < Digits.size()) {
6624 if (Str.consumeInteger(10, Digit))
6626 Digits[CurDigit] = Digit;
6629 if (!Str.consume_front(
"."))
6638llvm::opt::Visibility
6639Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6652const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6668 llvm_unreachable(
"Unhandled Mode");
6672 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6677 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6678 options::OPT_fno_save_optimization_record,
false))
6682 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6683 options::OPT_fno_save_optimization_record,
false))
6687 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6688 options::OPT_fno_save_optimization_record,
false))
6692 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6693 options::OPT_fno_save_optimization_record,
false))
6700 static StringRef OptName =
6702 llvm::StringRef Opt;
6703 for (StringRef Arg : Args) {
6704 if (!Arg.starts_with(OptName))
6710 return Opt.consume_front(OptName) ? Opt :
"";
6717 llvm::BumpPtrAllocator &Alloc,
6718 llvm::vfs::FileSystem *FS) {
6727 for (
const char *F : Args) {
6728 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6730 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6731 RSPQuoting = Windows;
6739 llvm::cl::TokenizerCallback Tokenizer;
6741 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6743 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6745 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6748 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6749 ECtx.setMarkEOLs(MarkEOLs);
6753 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
6757 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
6758 [](
const char *A) {
return A !=
nullptr; });
6759 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
6762 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
6763 Args.resize(newEnd - Args.begin());
6767 return llvm::Error::success();
6771 return SavedStrings.insert(S).first->getKeyData();
6804 llvm::StringSet<> &SavedStrings) {
6807 if (Edit[0] ==
'^') {
6808 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6809 OS <<
"### Adding argument " << Str <<
" at beginning\n";
6810 Args.insert(Args.begin() + 1, Str);
6811 }
else if (Edit[0] ==
'+') {
6812 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6813 OS <<
"### Adding argument " << Str <<
" at end\n";
6814 Args.push_back(Str);
6815 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
6816 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
6817 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
6818 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
6819 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
6821 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
6823 if (Args[i] ==
nullptr)
6825 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
6827 if (Repl != Args[i]) {
6828 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
6832 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
6833 auto Option = Edit.substr(1);
6834 for (
unsigned i = 1; i < Args.size();) {
6835 if (Option == Args[i]) {
6836 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6837 Args.erase(Args.begin() + i);
6838 if (Edit[0] ==
'X') {
6839 if (i < Args.size()) {
6840 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6841 Args.erase(Args.begin() + i);
6843 OS <<
"### Invalid X edit, end of command line!\n";
6848 }
else if (Edit[0] ==
'O') {
6849 for (
unsigned i = 1; i < Args.size();) {
6850 const char *A = Args[i];
6854 if (A[0] ==
'-' && A[1] ==
'O' &&
6855 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
6856 (
'0' <= A[2] && A[2] <=
'9'))))) {
6857 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6858 Args.erase(Args.begin() + i);
6862 OS <<
"### Adding argument " << Edit <<
" at end\n";
6863 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
6865 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
6870 const char *OverrideStr,
6871 llvm::StringSet<> &SavedStrings,
6874 OS = &llvm::nulls();
6876 if (OverrideStr[0] ==
'#') {
6878 OS = &llvm::nulls();
6881 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
6885 const char *S = OverrideStr;
6887 const char *End = ::strchr(S,
' ');
6889 End = S + strlen(S);
static std::optional< llvm::Triple > getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args)
static void applyOneOverrideOption(raw_ostream &OS, SmallVectorImpl< const char * > &Args, StringRef Edit, llvm::StringSet<> &SavedStrings)
Apply a list of edits to the input argument lists.
static bool HasPreprocessOutput(const Action &JA)
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple, bool SuppressError=false)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static const char * GetModuleOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput)
static const char * MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue, StringRef BaseName, types::ID FileType)
Create output filename based on ArgValue, which could either be a full filename, filename without ext...
static llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef DarwinArchName="")
Compute target triple from args.
static void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static std::string GetTriplePlusArchString(const ToolChain *TC, StringRef BoundArch, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
static void PrintDiagnosticCategories(raw_ostream &OS)
PrintDiagnosticCategories - Implement the –print-diagnostic-categories option.
static bool ContainsCompileOrAssembleAction(const Action *A)
Check whether the given input tree contains any compilation or assembly actions.
static std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictOffloadArchCombination(const llvm::DenseSet< StringRef > &Archs, llvm::Triple Triple)
Checks if the set offloading architectures does not conflict.
static std::optional< llvm::Triple > getNVIDIAOffloadTargetTriple(const Driver &D, const ArgList &Args, const llvm::Triple &HostTriple)
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static driver::LTOKind parseLTOMode(Driver &D, const llvm::opt::ArgList &Args, OptSpecifier OptEq, OptSpecifier OptNeg)
static Arg * MakeInputArg(DerivedArgList &Args, const OptTable &Opts, StringRef Value, bool Claim=true)
static void appendOneArg(InputArgList &Args, const Arg *Opt, const Arg *BaseArg)
static const char BugReporMsg[]
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static std::optional< llvm::Triple > getOffloadTargetTriple(const Driver &D, const ArgList &Args)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool hasErrorOccurred() const
Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const
Based on the way the client configured the DiagnosticsEngine object, classify the specified diagnosti...
Encodes a location in the source.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
unsigned getOffloadingHostActiveKinds() const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
A class to find a viable CUDA installation.
void WarnIfUnsupportedVersion()
bool isValid() const
Check whether we detected a valid Cuda install.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, Action *HostAction) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
llvm::DenseSet< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain *TC, bool SuppressError=false) const
Returns the set of bound architectures active for this offload kind.
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
std::string Name
The name the driver was invoked as.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
std::string ClangExecutable
The original path to the clang executable.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
bool HandleImmediateArgs(const Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
std::pair< types::ID, const llvm::opt::Arg * > InputTy
An input type and its arguments.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError)
ParseArgStrings - Parse the given list of strings into an ArgList.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
bool isUsingLTO(bool IsOffload=false) const
Returns true if we are performing any kind of LTO.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
static std::string GetResourcesPath(StringRef BinaryPath, StringRef CustomResourceDir="")
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
const char * getPhaseName(ID Id)
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
bool isHIP(ID Id)
isHIP - Is this a HIP input.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
const llvm::opt::OptTable & getDriverOptTable()
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
CudaArch StringToCudaArch(llvm::StringRef S)
static bool IsAMDGpuArch(CudaArch A)
@ Result
The result type of a method or function.
static bool IsNVIDIAGpuArch(CudaArch A)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
const FunctionProtoType * T
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
const char * CudaArchToString(CudaArch A)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
llvm::SmallVector< std::string, 4 > TemporaryFiles
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
std::string ModeSuffix
Driver mode part of the executable name, as g++.
std::string TargetPrefix
Target part of the executable name, as i686-linux-android.