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);
237void Driver::setDriverMode(StringRef
Value) {
238 static StringRef OptName =
239 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
240 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
241 .Case(
"gcc", GCCMode)
242 .Case(
"g++", GXXMode)
243 .Case(
"cpp", CPPMode)
245 .Case(
"flang", FlangMode)
246 .Case(
"dxc", DXCMode)
250 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
254 bool UseDriverMode,
bool &ContainsError) {
255 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
256 ContainsError =
false;
258 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
259 unsigned MissingArgIndex, MissingArgCount;
260 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
261 MissingArgCount, VisibilityMask);
264 if (MissingArgCount) {
265 Diag(diag::err_drv_missing_argument)
266 << Args.getArgString(MissingArgIndex) << MissingArgCount;
273 for (
const Arg *A : Args) {
275 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
283 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
284 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
286 diag::warn_drv_empty_joined_argument,
291 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
293 auto ArgString = A->getAsString(Args);
295 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
297 getOpts().findExact(ArgString, Nearest,
299 DiagID = diag::err_drv_unknown_argument_with_suggestion;
300 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
302 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
303 : diag::err_drv_unknown_argument;
304 Diags.
Report(DiagID) << ArgString;
308 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
309 : diag::err_drv_unknown_argument_with_suggestion;
310 Diags.
Report(DiagID) << ArgString << Nearest;
316 for (
const Arg *A : Args.filtered(options::OPT_o)) {
317 if (ArgStrings[A->getIndex()] == A->getSpelling())
321 std::string ArgString = ArgStrings[A->getIndex()];
323 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
324 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
325 << A->getAsString(Args) << Nearest;
335 Arg **FinalPhaseArg)
const {
336 Arg *PhaseArg =
nullptr;
340 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
341 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
342 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
343 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
350 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
351 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
352 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
353 options::OPT_fmodule_header_EQ))) {
356 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
357 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
359 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
360 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
361 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
362 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
368 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
372 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
375 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
383 *FinalPhaseArg = PhaseArg;
389 StringRef
Value,
bool Claim =
true) {
390 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
391 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
392 Args.AddSynthesizedArg(A);
398DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
399 const llvm::opt::OptTable &Opts =
getOpts();
400 DerivedArgList *DAL =
new DerivedArgList(Args);
402 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
403 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
404 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
405 bool IgnoreUnused =
false;
406 for (Arg *A : Args) {
410 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
414 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
415 IgnoreUnused =
false;
425 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
426 A->getOption().matches(options::OPT_Xlinker)) &&
427 A->containsValue(
"--no-demangle")) {
429 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
432 for (StringRef Val : A->getValues())
433 if (Val !=
"--no-demangle")
434 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
442 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
443 (A->getValue(0) == StringRef(
"-MD") ||
444 A->getValue(0) == StringRef(
"-MMD"))) {
446 if (A->getValue(0) == StringRef(
"-MD"))
447 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
449 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
450 if (A->getNumValues() == 2)
451 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
456 if (A->getOption().matches(options::OPT_l)) {
457 StringRef
Value = A->getValue();
460 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
462 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
467 if (
Value ==
"cc_kext") {
468 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
474 if (A->getOption().matches(options::OPT__DASH_DASH)) {
476 for (StringRef Val : A->getValues())
485 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
486 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
489 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
490 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
494#if defined(HOST_LINK_VERSION)
495 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
496 strlen(HOST_LINK_VERSION) > 0) {
497 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
499 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
511 StringRef TargetTriple,
513 StringRef DarwinArchName =
"") {
515 if (
const Arg *A = Args.getLastArg(options::OPT_target))
516 TargetTriple = A->getValue();
518 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
523 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
527 if (
Target.isOSBinFormatMachO()) {
529 if (!DarwinArchName.empty()) {
536 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
537 StringRef ArchName = A->getValue();
544 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
545 options::OPT_mbig_endian)) {
546 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
547 ?
Target.getLittleEndianArchVariant()
548 :
Target.getBigEndianArchVariant();
549 if (
T.getArch() != llvm::Triple::UnknownArch) {
551 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
556 if (
Target.getArch() == llvm::Triple::tce)
561 if (std::optional<std::string> ObjectModeValue =
562 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
563 StringRef ObjectMode = *ObjectModeValue;
564 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
566 if (ObjectMode.equals(
"64")) {
567 AT =
Target.get64BitArchVariant().getArch();
568 }
else if (ObjectMode.equals(
"32")) {
569 AT =
Target.get32BitArchVariant().getArch();
571 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
574 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
580 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
582 D.
Diag(diag::err_drv_unsupported_opt_for_target)
583 << A->getAsString(Args) <<
Target.str();
586 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
587 options::OPT_m32, options::OPT_m16,
588 options::OPT_maix32, options::OPT_maix64);
590 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
592 if (A->getOption().matches(options::OPT_m64) ||
593 A->getOption().matches(options::OPT_maix64)) {
594 AT =
Target.get64BitArchVariant().getArch();
595 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
596 Target.setEnvironment(llvm::Triple::GNU);
597 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
598 Target.setEnvironment(llvm::Triple::Musl);
599 }
else if (A->getOption().matches(options::OPT_mx32) &&
600 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
601 AT = llvm::Triple::x86_64;
602 if (
Target.getEnvironment() == llvm::Triple::Musl)
603 Target.setEnvironment(llvm::Triple::MuslX32);
605 Target.setEnvironment(llvm::Triple::GNUX32);
606 }
else if (A->getOption().matches(options::OPT_m32) ||
607 A->getOption().matches(options::OPT_maix32)) {
608 AT =
Target.get32BitArchVariant().getArch();
609 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
610 Target.setEnvironment(llvm::Triple::GNU);
611 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
612 Target.setEnvironment(llvm::Triple::Musl);
613 }
else if (A->getOption().matches(options::OPT_m16) &&
614 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
615 AT = llvm::Triple::x86;
616 Target.setEnvironment(llvm::Triple::CODE16);
619 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
621 if (
Target.isWindowsGNUEnvironment())
627 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
628 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
629 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
632 if (A && !A->getOption().matches(options::OPT_m32))
633 D.
Diag(diag::err_drv_argument_not_allowed_with)
634 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
636 Target.setArch(llvm::Triple::x86);
637 Target.setArchName(
"i586");
638 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
639 Target.setEnvironmentName(
"");
640 Target.setOS(llvm::Triple::ELFIAMCU);
641 Target.setVendor(llvm::Triple::UnknownVendor);
642 Target.setVendorName(
"intel");
648 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
649 StringRef ABIName = A->getValue();
650 if (ABIName ==
"32") {
652 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
653 Target.getEnvironment() == llvm::Triple::GNUABIN32)
654 Target.setEnvironment(llvm::Triple::GNU);
655 }
else if (ABIName ==
"n32") {
657 if (
Target.getEnvironment() == llvm::Triple::GNU ||
658 Target.getEnvironment() == llvm::Triple::GNUABI64)
659 Target.setEnvironment(llvm::Triple::GNUABIN32);
660 }
else if (ABIName ==
"64") {
662 if (
Target.getEnvironment() == llvm::Triple::GNU ||
663 Target.getEnvironment() == llvm::Triple::GNUABIN32)
664 Target.setEnvironment(llvm::Triple::GNUABI64);
672 if (Args.hasArg(options::OPT_march_EQ) ||
673 Args.hasArg(options::OPT_mcpu_EQ)) {
675 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
677 if (!llvm::errorToBool(ISAInfo.takeError())) {
678 unsigned XLen = (*ISAInfo)->getXLen();
680 Target.setArch(llvm::Triple::riscv32);
682 Target.setArch(llvm::Triple::riscv64);
694 OptSpecifier OptEq, OptSpecifier OptNeg) {
695 if (!Args.hasFlag(OptEq, OptNeg,
false))
698 const Arg *A = Args.getLastArg(OptEq);
699 StringRef LTOName = A->getValue();
707 D.
Diag(diag::err_drv_unsupported_option_argument)
708 << A->getSpelling() << A->getValue();
715void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
717 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
719 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
720 options::OPT_fno_offload_lto);
723 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
724 options::OPT_fno_openmp_target_jit,
false)) {
725 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
726 options::OPT_fno_offload_lto))
728 Diag(diag::err_drv_incompatible_options)
729 << A->getSpelling() <<
"-fopenmp-target-jit";
736 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
738 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
740 RuntimeName = A->getValue();
742 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
750 Diag(diag::err_drv_unsupported_option_argument)
751 << A->getSpelling() << A->getValue();
754 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
769 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
774 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
777 C.getInputArgs().hasArg(options::OPT_hip_link) ||
778 C.getInputArgs().hasArg(options::OPT_hipstdpar);
779 if (IsCuda && IsHIP) {
780 Diag(clang::diag::err_drv_mix_cuda_hip);
785 const llvm::Triple &HostTriple = HostTC->
getTriple();
793 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
795 CudaTC = std::make_unique<toolchains::CudaToolChain>(
796 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
801 if (CudaInstallation.
isValid())
804 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
806 if (
auto *OMPTargetArg =
807 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
808 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
809 << OMPTargetArg->getSpelling() <<
"HIP";
817 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
819 assert(HIPTC &&
"Could not create offloading device tool chain.");
820 C.addOffloadDeviceToolChain(HIPTC, OFK);
828 bool IsOpenMPOffloading =
829 C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
830 options::OPT_fno_openmp,
false) &&
831 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
832 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ));
833 if (IsOpenMPOffloading) {
839 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
843 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
844 llvm::StringMap<StringRef> FoundNormalizedTriples;
845 std::multiset<StringRef> OpenMPTriples;
850 if (Arg *OpenMPTargets =
851 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
852 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
853 Diag(clang::diag::warn_drv_empty_joined_argument)
854 << OpenMPTargets->getAsString(
C.getInputArgs());
857 for (StringRef
T : OpenMPTargets->getValues())
858 OpenMPTriples.insert(
T);
859 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
872 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
873 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
879 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
880 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
885 if (!AMDTriple && !NVPTXTriple) {
886 for (StringRef Arch :
891 for (StringRef Arch : Archs) {
894 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
895 }
else if (AMDTriple &&
898 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
900 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
907 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
912 for (
const auto &TripleAndArchs : DerivedArchs)
913 OpenMPTriples.insert(TripleAndArchs.first());
916 for (StringRef Val : OpenMPTriples) {
918 std::string NormalizedName = TT.normalize();
921 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
922 if (Duplicate != FoundNormalizedTriples.end()) {
923 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
924 << Val << Duplicate->second;
930 FoundNormalizedTriples[NormalizedName] = Val;
933 if (TT.getArch() == llvm::Triple::UnknownArch)
934 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
939 if (TT.isNVPTX() || TT.isAMDGCN()) {
942 assert(HostTC &&
"Host toolchain should be always defined.");
944 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
947 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
948 *
this, TT, *HostTC,
C.getInputArgs());
949 else if (TT.isAMDGCN())
950 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
951 *
this, TT, *HostTC,
C.getInputArgs());
953 assert(DeviceTC &&
"Device toolchain not defined.");
958 TC = &getToolChain(
C.getInputArgs(), TT);
960 if (DerivedArchs.contains(TT.getTriple()))
961 KnownArchs[TC] = DerivedArchs[TT.getTriple()];
964 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
965 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
975 const Arg *BaseArg) {
979 unsigned Index = Args.MakeIndex(Opt->getSpelling());
980 Arg *
Copy =
new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index),
982 Copy->getValues() = Opt->getValues();
983 if (Opt->isClaimed())
985 Copy->setOwnsValues(Opt->getOwnsValues());
986 Opt->setOwnsValues(
false);
990bool Driver::readConfigFile(StringRef
FileName,
991 llvm::cl::ExpansionContext &ExpCtx) {
995 Diag(diag::err_drv_cannot_open_config_file)
996 <<
FileName << Status.getError().message();
999 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1000 Diag(diag::err_drv_cannot_open_config_file)
1001 <<
FileName <<
"not a regular file";
1007 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgArgs)) {
1008 Diag(diag::err_drv_cannot_read_config_file)
1015 llvm::sys::path::native(CfgFileName);
1017 std::unique_ptr<InputArgList> NewOptions = std::make_unique<InputArgList>(
1024 for (Arg *A : *NewOptions)
1028 CfgOptions = std::move(NewOptions);
1031 for (
auto *Opt : *NewOptions) {
1032 const Arg *BaseArg = &Opt->getBaseArg();
1038 ConfigFiles.push_back(std::string(CfgFileName));
1042bool Driver::loadConfigFiles() {
1043 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1044 llvm::cl::tokenizeConfigFile);
1045 ExpCtx.setVFS(&
getVFS());
1049 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1052 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1053 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1058 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1060 llvm::sys::fs::expand_tilde(
1061 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1062 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1071 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1074 if (loadDefaultConfigFiles(ExpCtx))
1080 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1083 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1084 CfgFilePath.assign(CfgFileName);
1085 if (llvm::sys::path::is_relative(CfgFilePath)) {
1086 if (
getVFS().makeAbsolute(CfgFilePath)) {
1087 Diag(diag::err_drv_cannot_open_config_file)
1088 << CfgFilePath <<
"cannot get absolute path";
1092 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1094 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1095 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1096 if (!SearchDir.empty())
1097 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1102 if (readConfigFile(CfgFilePath, ExpCtx))
1111bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1114 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1118 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1121 std::string RealMode = getExecutableForDriverMode(Mode);
1131 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1132 PrefixTriple.isOSUnknown())
1133 Triple = PrefixTriple.str();
1137 if (Triple.empty()) {
1138 llvm::Triple RealTriple =
1140 Triple = RealTriple.str();
1141 assert(!Triple.empty());
1156 std::string CfgFileName = Triple +
'-' + RealMode +
".cfg";
1157 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1158 return readConfigFile(CfgFilePath, ExpCtx);
1162 if (TryModeSuffix) {
1164 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1165 return readConfigFile(CfgFilePath, ExpCtx);
1170 CfgFileName = RealMode +
".cfg";
1171 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1172 if (readConfigFile(CfgFilePath, ExpCtx))
1174 }
else if (TryModeSuffix) {
1176 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1177 readConfigFile(CfgFilePath, ExpCtx))
1182 CfgFileName = Triple +
".cfg";
1183 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1184 return readConfigFile(CfgFilePath, ExpCtx);
1192 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1201 if (!DriverMode.empty())
1202 setDriverMode(DriverMode);
1208 CLOptions = std::make_unique<InputArgList>(
1213 ContainsError = loadConfigFiles();
1214 bool HasConfigFile = !ContainsError && (CfgOptions.get() !=
nullptr);
1217 InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
1218 : std::move(*CLOptions));
1221 for (
auto *Opt : *CLOptions) {
1222 if (Opt->getOption().matches(options::OPT_config))
1224 const Arg *BaseArg = &Opt->getBaseArg();
1231 if (
IsCLMode() && !ContainsError) {
1233 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1235 CLModePassThroughArgList.push_back(A->getValue());
1238 if (!CLModePassThroughArgList.empty()) {
1241 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1246 for (
auto *Opt : *CLModePassThroughOptions) {
1253 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1254 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1255 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1258 bool CCCPrintPhases;
1261 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1262 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1265 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1266 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1269 Args.ClaimAllArgs(options::OPT_pipe);
1277 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1279 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1280 CCCGenericGCCName = A->getValue();
1283 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1287 if (Args.hasArg(options::OPT_fproc_stat_report))
1294 llvm::Triple
T(TargetTriple);
1295 T.setOS(llvm::Triple::Win32);
1296 T.setVendor(llvm::Triple::PC);
1297 T.setEnvironment(llvm::Triple::MSVC);
1298 T.setObjectFormat(llvm::Triple::COFF);
1299 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1300 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1301 TargetTriple =
T.str();
1304 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1305 StringRef TargetProfile = A->getValue();
1308 TargetTriple = *Triple;
1310 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1314 if (Args.hasArg(options::OPT_spirv)) {
1315 llvm::Triple
T(TargetTriple);
1316 T.setArch(llvm::Triple::spirv);
1317 T.setOS(llvm::Triple::Vulkan);
1320 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1321 const llvm::StringSet<> ValidValues = {
"vulkan1.2",
"vulkan1.3"};
1322 if (ValidValues.contains(A->getValue())) {
1323 T.setOSName(A->getValue());
1325 Diag(diag::err_drv_invalid_value)
1326 << A->getAsString(Args) << A->getValue();
1331 TargetTriple =
T.str();
1334 Diag(diag::err_drv_dxc_missing_target_profile);
1338 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1339 TargetTriple = A->getValue();
1340 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1341 Dir =
Dir = A->getValue();
1342 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1346 if (std::optional<std::string> CompilerPathValue =
1347 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1348 StringRef CompilerPath = *CompilerPathValue;
1349 while (!CompilerPath.empty()) {
1350 std::pair<StringRef, StringRef> Split =
1351 CompilerPath.split(llvm::sys::EnvPathSeparator);
1352 PrefixDirs.push_back(std::string(Split.first));
1353 CompilerPath = Split.second;
1356 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1358 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1361 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1364 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1365 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1366 .Case(
"cwd", SaveTempsCwd)
1367 .Case(
"obj", SaveTempsObj)
1368 .Default(SaveTempsCwd);
1371 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1372 options::OPT_offload_device_only,
1373 options::OPT_offload_host_device)) {
1374 if (A->getOption().matches(options::OPT_offload_host_only))
1375 Offload = OffloadHost;
1376 else if (A->getOption().matches(options::OPT_offload_device_only))
1377 Offload = OffloadDevice;
1379 Offload = OffloadHostDevice;
1385 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1386 StringRef
Name = A->getValue();
1387 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1388 .Case(
"off", EmbedNone)
1389 .Case(
"all", EmbedBitcode)
1390 .Case(
"bitcode", EmbedBitcode)
1391 .Case(
"marker", EmbedMarker)
1394 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1397 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1401 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1402 llvm::sys::fs::remove(A->getValue());
1408 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1410 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1411 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1412 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1413 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1414 Std->containsValue(
"c++latest"));
1417 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1418 options::OPT_fmodule_header)) {
1420 ModulesModeCXX20 =
true;
1421 if (A->getOption().matches(options::OPT_fmodule_header))
1424 StringRef ArgName = A->getValue();
1425 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1430 Diags.
Report(diag::err_drv_invalid_value)
1431 << A->getAsString(Args) << ArgName;
1437 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1438 std::make_unique<InputArgList>(std::move(Args));
1441 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1449 if (!Triple.isWasm()) {
1450 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1451 StringRef TripleObjectFormat =
1452 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1453 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1454 TripleVersionName != TripleObjectFormat) {
1455 Diags.
Report(diag::err_drv_triple_version_invalid)
1457 ContainsError =
true;
1462 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1463 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1464 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1472 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1473 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1475 case llvm::Triple::arm:
1476 case llvm::Triple::armeb:
1477 case llvm::Triple::thumb:
1478 case llvm::Triple::thumbeb:
1479 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1480 Diag(diag::warn_target_unrecognized_env)
1482 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1485 case llvm::Triple::aarch64:
1486 case llvm::Triple::aarch64_be:
1487 case llvm::Triple::aarch64_32:
1488 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1489 Diag(diag::warn_target_unrecognized_env)
1491 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1508 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1515 if (TC.
getTriple().isOSBinFormatMachO())
1520 if (CCCPrintPhases) {
1531 llvm::opt::ArgStringList ASL;
1532 for (
const auto *A : Args) {
1536 while (A->getAlias())
1538 A->render(Args, ASL);
1541 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1542 if (I != ASL.begin())
1544 llvm::sys::printArg(OS, *I,
true);
1549bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1551 using namespace llvm::sys;
1552 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1553 "Only knows about .crash files on Darwin");
1558 path::home_directory(CrashDiagDir);
1559 if (CrashDiagDir.starts_with(
"/var/root"))
1561 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1569 fs::file_status FileStatus;
1570 TimePoint<> LastAccessTime;
1574 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1575 File != FileEnd && !EC;
File.increment(EC)) {
1579 if (fs::status(
File->path(), FileStatus))
1581 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1582 llvm::MemoryBuffer::getFile(
File->path());
1587 StringRef
Data = CrashFile.get()->getBuffer();
1588 if (!
Data.starts_with(
"Process:"))
1591 size_t ParentProcPos =
Data.find(
"Parent Process:");
1592 if (ParentProcPos == StringRef::npos)
1594 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1595 if (LineEnd == StringRef::npos)
1597 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1598 int OpenBracket = -1, CloseBracket = -1;
1599 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1600 if (ParentProcess[i] ==
'[')
1602 if (ParentProcess[i] ==
']')
1608 if (OpenBracket < 0 || CloseBracket < 0 ||
1609 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1610 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1620 const auto FileAccessTime = FileStatus.getLastModificationTime();
1621 if (FileAccessTime > LastAccessTime) {
1622 CrashFilePath.assign(
File->path());
1623 LastAccessTime = FileAccessTime;
1628 if (!CrashFilePath.empty()) {
1629 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1639 "\n********************\n\n"
1640 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1641 "Preprocessed source(s) and associated run script(s) are located at:";
1649 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1653 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1654 Level = llvm::StringSwitch<unsigned>(A->getValue())
1656 .Case(
"compiler", 1)
1668 ArgStringList SavedTemps;
1670 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1671 if (!IsLLD || Level < 2)
1678 SavedTemps = std::move(
C.getTempFiles());
1679 assert(!
C.getTempFiles().size());
1696 C.initCompilationForDiagnostics();
1702 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1703 StringRef ReproduceOption =
1704 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1707 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1711 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1713 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1714 Diag(clang::diag::note_drv_command_failed_diag_msg)
1715 <<
"\n\n********************";
1725 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1726 bool IgnoreInput =
false;
1732 }
else if (!strcmp(it->second->getValue(),
"-")) {
1733 Diag(clang::diag::note_drv_command_failed_diag_msg)
1734 <<
"Error generating preprocessed source(s) - "
1735 "ignoring input from stdin.";
1740 it = Inputs.erase(it);
1747 if (Inputs.empty()) {
1748 Diag(clang::diag::note_drv_command_failed_diag_msg)
1749 <<
"Error generating preprocessed source(s) - "
1750 "no preprocessable inputs.";
1756 llvm::StringSet<> ArchNames;
1757 for (
const Arg *A :
C.getArgs()) {
1758 if (A->getOption().matches(options::OPT_arch)) {
1759 StringRef ArchName = A->getValue();
1760 ArchNames.insert(ArchName);
1763 if (ArchNames.size() > 1) {
1764 Diag(clang::diag::note_drv_command_failed_diag_msg)
1765 <<
"Error generating preprocessed source(s) - cannot generate "
1766 "preprocessed source with multiple -arch options.";
1772 const ToolChain &TC =
C.getDefaultToolChain();
1773 if (TC.
getTriple().isOSBinFormatMachO())
1782 Diag(clang::diag::note_drv_command_failed_diag_msg)
1783 <<
"Error generating preprocessed source(s).";
1789 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1792 if (!FailingCommands.empty()) {
1793 Diag(clang::diag::note_drv_command_failed_diag_msg)
1794 <<
"Error generating preprocessed source(s).";
1798 const ArgStringList &TempFiles =
C.getTempFiles();
1799 if (TempFiles.empty()) {
1800 Diag(clang::diag::note_drv_command_failed_diag_msg)
1801 <<
"Error generating preprocessed source(s).";
1809 for (
const char *TempFile : TempFiles) {
1810 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
1813 if (ReproCrashFilename.empty()) {
1814 ReproCrashFilename = TempFile;
1815 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
1817 if (StringRef(TempFile).ends_with(
".cache")) {
1820 VFS = llvm::sys::path::filename(TempFile);
1821 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
1825 for (
const char *TempFile : SavedTemps)
1826 C.addTempFile(TempFile);
1832 llvm::sys::path::replace_extension(Script,
"sh");
1834 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
1835 llvm::sys::fs::FA_Write,
1836 llvm::sys::fs::OF_Text);
1838 Diag(clang::diag::note_drv_command_failed_diag_msg)
1839 <<
"Error generating run script: " << Script <<
" " << EC.message();
1842 <<
"# Driver args: ";
1844 ScriptOS <<
"# Original command: ";
1845 Cmd.Print(ScriptOS,
"\n",
true);
1846 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
1847 if (!AdditionalInformation.empty())
1848 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
1852 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
1856 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
1858 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
1859 Diag(clang::diag::note_drv_command_failed_diag_msg)
1860 << ReproCrashFilename.str();
1862 llvm::sys::path::append(CrashDiagDir,
Name);
1863 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
1864 Diag(clang::diag::note_drv_command_failed_diag_msg)
1865 <<
"Crash backtrace is located in";
1866 Diag(clang::diag::note_drv_command_failed_diag_msg)
1867 << CrashDiagDir.str();
1868 Diag(clang::diag::note_drv_command_failed_diag_msg)
1869 <<
"(choose the .crash file that corresponds to your crash)";
1873 Diag(clang::diag::note_drv_command_failed_diag_msg)
1874 <<
"\n\n********************";
1882 if (
Cmd.getResponseFileSupport().ResponseKind ==
1884 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
1885 Cmd.getArguments()))
1889 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
1895 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
1896 if (
C.getArgs().hasArg(options::OPT_v))
1897 C.getJobs().Print(llvm::errs(),
"\n",
true);
1899 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
1909 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
1910 C.getJobs().Print(llvm::errs(),
"\n",
true);
1919 for (
auto &Job :
C.getJobs())
1920 setUpResponseFiles(
C, Job);
1922 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1925 if (FailingCommands.empty())
1931 for (
const auto &CmdPair : FailingCommands) {
1932 int CommandRes = CmdPair.first;
1933 const Command *FailingCommand = CmdPair.second;
1938 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
1942 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
1947 if (CommandRes == EX_IOERR) {
1964 Diag(clang::diag::err_drv_command_signalled)
1967 Diag(clang::diag::err_drv_command_failed)
1975 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
1977 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
1991 const ToolChain &TC =
C.getDefaultToolChain();
1995 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
1998 OS <<
"Thread model: " << A->getValue();
2004 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2009 if (!llvm::cl::getCompilerBuildConfig().empty())
2010 llvm::cl::printBuildConfig(OS);
2013 for (
auto ConfigFile : ConfigFiles)
2014 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2027 if (PassedFlags ==
"")
2031 std::vector<std::string> SuggestedCompletions;
2032 std::vector<std::string> Flags;
2044 const bool HasSpace = PassedFlags.ends_with(
",");
2048 StringRef TargetFlags = PassedFlags;
2049 while (TargetFlags !=
"") {
2051 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2052 Flags.push_back(std::string(CurFlag));
2057 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2060 const llvm::opt::OptTable &Opts =
getOpts();
2062 Cur = Flags.at(Flags.size() - 1);
2064 if (Flags.size() >= 2) {
2065 Prev = Flags.at(Flags.size() - 2);
2066 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2069 if (SuggestedCompletions.empty())
2070 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2077 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2078 llvm::outs() <<
'\n';
2084 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2088 SuggestedCompletions = Opts.findByPrefix(
2089 Cur, VisibilityMask,
2096 if (S.starts_with(Cur))
2097 SuggestedCompletions.push_back(std::string(S));
2104 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2105 if (
int X = A.compare_insensitive(B))
2107 return A.compare(B) > 0;
2110 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2117 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2118 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2122 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2125 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2129 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2134 if (
C.getArgs().hasArg(options::OPT_help) ||
2135 C.getArgs().hasArg(options::OPT__help_hidden)) {
2136 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2140 if (
C.getArgs().hasArg(options::OPT__version)) {
2146 if (
C.getArgs().hasArg(options::OPT_v) ||
2147 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2148 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2149 C.getArgs().hasArg(options::OPT_print_supported_extensions)) {
2151 SuppressMissingInputWarning =
true;
2154 if (
C.getArgs().hasArg(options::OPT_v)) {
2156 llvm::errs() <<
"System configuration file directory: "
2159 llvm::errs() <<
"User configuration file directory: "
2163 const ToolChain &TC =
C.getDefaultToolChain();
2165 if (
C.getArgs().hasArg(options::OPT_v))
2168 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2173 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2174 llvm::outs() <<
"programs: =";
2175 bool separator =
false;
2179 llvm::outs() << llvm::sys::EnvPathSeparator;
2180 llvm::outs() << Path;
2185 llvm::outs() << llvm::sys::EnvPathSeparator;
2186 llvm::outs() << Path;
2189 llvm::outs() <<
"\n";
2192 StringRef sysroot =
C.getSysRoot();
2196 llvm::outs() << llvm::sys::EnvPathSeparator;
2199 llvm::outs() << sysroot << Path.substr(1);
2201 llvm::outs() << Path;
2203 llvm::outs() <<
"\n";
2207 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2213 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2214 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2215 llvm::outs() << *RuntimePath <<
'\n';
2221 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2223 for (std::size_t I = 0; I != Flags.size(); I += 2)
2224 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2230 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2231 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2235 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2236 StringRef ProgName = A->getValue();
2239 if (! ProgName.empty())
2242 llvm::outs() <<
"\n";
2246 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2247 StringRef PassedFlags = A->getValue();
2252 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2258 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2261 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2267 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2273 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2276 std::set<llvm::StringRef> SortedFlags;
2277 for (
const auto &FlagEntry : ExpandedFlags)
2278 SortedFlags.insert(FlagEntry.getKey());
2279 for (
auto Flag : SortedFlags)
2280 llvm::outs() << Flag <<
'\n';
2284 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2287 llvm::outs() <<
".\n";
2290 assert(Suffix.front() ==
'/');
2291 llvm::outs() << Suffix.substr(1) <<
"\n";
2297 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2302 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2304 llvm::outs() << Triple.getTriple() <<
"\n";
2308 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2309 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2326 std::map<Action *, unsigned> &Ids,
2332 llvm::raw_string_ostream os(str);
2334 auto getSibIndent = [](
int K) -> Twine {
2338 Twine SibIndent = Indent + getSibIndent(Kind);
2342 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2344 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2345 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2346 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2347 bool IsFirst =
true;
2348 OA->doOnEachDependence(
2350 assert(TC &&
"Unknown host toolchain");
2362 os <<
":" << BoundArch;
2365 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2373 const char *Prefix =
"{";
2374 for (
Action *PreRequisite : *AL) {
2375 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2386 std::string offload_str;
2387 llvm::raw_string_ostream offload_os(offload_str);
2388 if (!isa<OffloadAction>(A)) {
2391 offload_os <<
", (" << S;
2398 auto getSelfIndent = [](
int K) -> Twine {
2402 unsigned Id = Ids.size();
2404 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2413 std::map<Action *, unsigned> Ids;
2414 for (
Action *A :
C.getActions())
2421 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2422 isa<AssembleJobAction>(A))
2430 DerivedArgList &Args =
C.getArgs();
2432 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2435 llvm::StringSet<> ArchNames;
2437 for (Arg *A : Args) {
2438 if (A->getOption().matches(options::OPT_arch)) {
2441 llvm::Triple::ArchType Arch =
2443 if (Arch == llvm::Triple::UnknownArch) {
2444 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2449 if (ArchNames.insert(A->getValue()).second)
2450 Archs.push_back(A->getValue());
2464 for (
Action* Act : SingleActions) {
2472 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2476 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2481 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2482 Actions.append(Inputs.begin(), Inputs.end());
2484 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2487 Arg *A = Args.getLastArg(options::OPT_g_Group);
2488 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2489 !A->getOption().matches(options::OPT_gstabs);
2497 if (Act->getType() == types::TY_Image) {
2499 Inputs.push_back(Actions.back());
2506 if (Args.hasArg(options::OPT_verify_debug_info)) {
2507 Action* LastAction = Actions.back();
2510 LastAction, types::TY_Nothing));
2529 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2530 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2542 std::string Nearest;
2543 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2544 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2545 <<
Value << Nearest;
2584 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2587 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2595 return types::TY_CXXUHeader;
2597 return types::TY_CXXSHeader;
2601 llvm_unreachable(
"should not be called in this case");
2603 return types::TY_CXXHUHeader;
2609 const llvm::opt::OptTable &Opts =
getOpts();
2613 types::ID InputType = types::TY_Nothing;
2614 Arg *InputTypeArg =
nullptr;
2617 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2618 options::OPT__SLASH_TP)) {
2619 InputTypeArg = TCTP;
2620 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2625 bool ShowNote =
false;
2627 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2629 Diag(clang::diag::warn_drv_overriding_option)
2630 <<
Previous->getSpelling() << A->getSpelling();
2636 Diag(clang::diag::note_drv_t_option_is_global);
2641 auto LastXArg = Args.getLastArgValue(options::OPT_x);
2642 const llvm::StringSet<> ValidXArgs = {
"cuda",
"hip",
"cui",
"hipi"};
2643 if (!
IsCLMode() || ValidXArgs.contains(LastXArg)) {
2644 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2645 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2646 if (LastXArg && LastInputArg &&
2647 LastInputArg->getIndex() < LastXArg->getIndex())
2648 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2652 if (
auto *A = Args.getLastArg(options::OPT_x))
2653 Diag(diag::err_drv_unsupported_opt_with_suggestion)
2654 << A->getAsString(Args) <<
"/TC' or '/TP";
2657 for (Arg *A : Args) {
2658 if (A->getOption().
getKind() == Option::InputClass) {
2659 const char *
Value = A->getValue();
2663 if (InputType == types::TY_Nothing) {
2666 InputTypeArg->claim();
2669 if (memcmp(
Value,
"-", 2) == 0) {
2671 Ty = types::TY_Fortran;
2673 Ty = types::TY_HLSL;
2682 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2683 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2684 : clang::diag::err_drv_unknown_stdin_type);
2693 if (
const char *Ext = strrchr(
Value,
'.'))
2702 Ty = types::TY_Object;
2713 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2714 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2715 << getTypeName(OldTy) << getTypeName(Ty);
2720 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2721 Ty == types::TY_Object)
2722 Ty = types::TY_LLVM_BC;
2730 if (Ty != types::TY_Object) {
2731 if (Args.hasArg(options::OPT_ObjC))
2732 Ty = types::TY_ObjC;
2733 else if (Args.hasArg(options::OPT_ObjCXX))
2734 Ty = types::TY_ObjCXX;
2741 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
2745 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2746 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2749 const char *Ext = strrchr(
Value,
'.');
2751 Ty = types::TY_Object;
2755 InputTypeArg->claim();
2759 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
2760 Args.hasArgNoClaim(options::OPT_hipstdpar))
2764 Inputs.push_back(std::make_pair(Ty, A));
2766 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2767 StringRef
Value = A->getValue();
2770 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2771 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2774 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2775 StringRef
Value = A->getValue();
2778 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2779 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2785 Inputs.push_back(std::make_pair(types::TY_Object, A));
2787 }
else if (A->getOption().matches(options::OPT_x)) {
2796 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2797 InputType = types::TY_Object;
2804 }
else if (A->getOption().getID() == options::OPT_U) {
2805 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
2806 StringRef Val = A->getValue(0);
2807 if (Val.find_first_of(
"/\\") != StringRef::npos) {
2809 Diag(diag::warn_slash_u_filename) << Val;
2810 Diag(diag::note_use_dashdash);
2814 if (
CCCIsCPP() && Inputs.empty()) {
2818 Inputs.push_back(std::make_pair(types::TY_C, A));
2825class OffloadingActionBuilder final {
2827 bool IsValid =
false;
2833 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
2836 std::map<Action *, const Arg *> HostActionToInputArgMap;
2839 class DeviceActionBuilder {
2843 enum ActionBuilderReturnCode {
2862 DerivedArgList &Args;
2871 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
2874 :
C(
C), Args(Args), Inputs(Inputs),
2875 AssociatedOffloadKind(AssociatedOffloadKind) {}
2876 virtual ~DeviceActionBuilder() {}
2881 virtual ActionBuilderReturnCode
2885 return ABRT_Inactive;
2890 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
2891 return ABRT_Inactive;
2895 virtual void appendTopLevelActions(
ActionList &AL) {}
2898 virtual void appendLinkDeviceActions(
ActionList &AL) {}
2911 virtual bool canUseBundlerUnbundler()
const {
return false; }
2915 bool isValid() {
return !ToolChains.empty(); }
2919 return AssociatedOffloadKind;
2925 class CudaActionBuilderBase :
public DeviceActionBuilder {
2929 bool CompileHostOnly =
false;
2930 bool CompileDeviceOnly =
false;
2932 bool EmitAsm =
false;
2942 TargetID(
const char *
ID) :
ID(
ID) {}
2943 operator const char *() {
return ID; }
2944 operator StringRef() {
return StringRef(
ID); }
2953 Action *CudaFatBinary =
nullptr;
2956 bool IsActive =
false;
2959 bool Relocatable =
false;
2962 CudaArch DefaultCudaArch = CudaArch::UNKNOWN;
2966 enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
2967 UseCUIDKind UseCUID = CUID_Hash;
2970 StringRef FixedCUID;
2973 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
2976 : DeviceActionBuilder(
C, Args, Inputs, OFKind) {
2978 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
2979 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
2980 options::OPT_fno_gpu_rdc,
false);
2983 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
2990 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
2991 assert(!GpuArchList.empty() &&
2992 "We should have at least one GPU architecture.");
2996 if (!(IA->getType() == types::TY_CUDA ||
2997 IA->getType() == types::TY_HIP ||
2998 IA->getType() == types::TY_PP_HIP)) {
3001 return ABRT_Inactive;
3007 if (CompileHostOnly)
3008 return ABRT_Success;
3011 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3012 : types::TY_CUDA_DEVICE;
3013 std::string CUID = FixedCUID.str();
3015 if (UseCUID == CUID_Random)
3016 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
3018 else if (UseCUID == CUID_Hash) {
3020 llvm::MD5::MD5Result Hash;
3022 llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
3024 Hasher.update(RealPath);
3025 for (
auto *A : Args) {
3026 if (A->getOption().matches(options::OPT_INPUT))
3028 Hasher.update(A->getAsString(Args));
3031 CUID = llvm::utohexstr(Hash.low(),
true);
3036 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3037 CudaDeviceActions.push_back(
3038 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3041 return ABRT_Success;
3045 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3049 if (UA->getType() == types::TY_Object && !Relocatable)
3050 return ABRT_Inactive;
3052 CudaDeviceActions.clear();
3053 auto *IA = cast<InputAction>(UA->getInputs().back());
3054 std::string
FileName = IA->getInputArg().getAsString(Args);
3060 const StringRef LibFileExt =
".lib";
3061 if (IA->getType() == types::TY_Object &&
3062 (!llvm::sys::path::has_extension(
FileName) ||
3064 llvm::sys::path::extension(
FileName).drop_front()) !=
3066 llvm::sys::path::extension(
FileName) == LibFileExt))
3067 return ABRT_Inactive;
3069 for (
auto Arch : GpuArchList) {
3070 CudaDeviceActions.push_back(UA);
3071 UA->registerDependentActionInfo(ToolChains[0], Arch,
3072 AssociatedOffloadKind);
3075 return ABRT_Success;
3078 return IsActive ? ABRT_Success : ABRT_Inactive;
3081 void appendTopLevelActions(
ActionList &AL)
override {
3083 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3085 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3090 if (CudaFatBinary) {
3091 AddTopLevel(CudaFatBinary, CudaArch::UNUSED);
3092 CudaDeviceActions.clear();
3093 CudaFatBinary =
nullptr;
3097 if (CudaDeviceActions.empty())
3103 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3104 "Expecting one action per GPU architecture.");
3105 assert(ToolChains.size() == 1 &&
3106 "Expecting to have a single CUDA toolchain.");
3107 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3108 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3110 CudaDeviceActions.clear();
3115 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3117 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3135 assert(HostTC &&
"No toolchain for host compilation.");
3137 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3141 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3146 ToolChains.push_back(
3151 CompileHostOnly =
C.getDriver().offloadHostOnly();
3152 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3153 EmitAsm = Args.getLastArg(options::OPT_S);
3154 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3155 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3156 StringRef UseCUIDStr = A->getValue();
3157 UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3158 .Case(
"hash", CUID_Hash)
3159 .Case(
"random", CUID_Random)
3160 .Case(
"none", CUID_None)
3161 .Default(CUID_Invalid);
3162 if (UseCUID == CUID_Invalid) {
3163 C.getDriver().Diag(diag::err_drv_invalid_value)
3164 << A->getAsString(Args) << UseCUIDStr;
3165 C.setContainsError();
3171 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3172 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3173 options::OPT_no_offload_arch_EQ)) {
3174 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3179 std::set<StringRef> GpuArchs;
3181 for (Arg *A : Args) {
3182 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3183 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3187 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3188 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3191 }
else if (ArchStr ==
"native") {
3192 const ToolChain &TC = *ToolChains.front();
3193 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3196 << llvm::Triple::getArchTypeName(TC.
getArch())
3197 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3201 for (
auto GPU : *GPUsOrErr) {
3202 GpuArchs.insert(Args.MakeArgString(GPU));
3205 ArchStr = getCanonicalOffloadArch(ArchStr);
3206 if (ArchStr.empty()) {
3208 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3209 GpuArchs.insert(ArchStr);
3210 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3211 GpuArchs.erase(ArchStr);
3213 llvm_unreachable(
"Unexpected option.");
3219 if (ConflictingArchs) {
3220 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3221 << ConflictingArchs->first << ConflictingArchs->second;
3222 C.setContainsError();
3227 for (
auto Arch : GpuArchs)
3228 GpuArchList.push_back(Arch.data());
3233 if (GpuArchList.empty()) {
3234 if (ToolChains.front()->getTriple().isSPIRV())
3235 GpuArchList.push_back(CudaArch::Generic);
3237 GpuArchList.push_back(DefaultCudaArch);
3246 class CudaActionBuilder final :
public CudaActionBuilderBase {
3248 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3250 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3251 DefaultCudaArch = CudaArch::CudaDefault;
3254 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3257 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3263 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3265 const std::set<StringRef> &GpuArchs)
override {
3266 return std::nullopt;
3269 ActionBuilderReturnCode
3272 PhasesTy &Phases)
override {
3274 return ABRT_Inactive;
3278 if (CudaDeviceActions.empty())
3279 return ABRT_Success;
3281 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3282 "Expecting one action per GPU architecture.");
3283 assert(!CompileHostOnly &&
3284 "Not expecting CUDA actions in host-only compilation.");
3294 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3297 for (
auto Ph : Phases) {
3302 if (Ph > FinalPhase)
3305 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3315 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3319 Action *AssembleAction = CudaDeviceActions[I];
3320 assert(AssembleAction->
getType() == types::TY_Object);
3321 assert(AssembleAction->
getInputs().size() == 1);
3329 DeviceActions.push_back(
3335 if (!DeviceActions.empty()) {
3337 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3339 if (!CompileDeviceOnly) {
3340 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3344 CudaFatBinary =
nullptr;
3349 CudaDeviceActions.clear();
3353 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3358 return ABRT_Success;
3362 "instructions should only occur "
3363 "before the backend phase!");
3366 for (
Action *&A : CudaDeviceActions)
3367 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3369 return ABRT_Success;
3374 class HIPActionBuilder final :
public CudaActionBuilderBase {
3382 std::optional<bool> BundleOutput;
3383 std::optional<bool> EmitReloc;
3388 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3390 DefaultCudaArch = CudaArch::HIPDefault;
3392 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3393 options::OPT_fno_hip_emit_relocatable)) {
3394 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3395 options::OPT_fno_hip_emit_relocatable,
false);
3399 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3400 <<
"-fhip-emit-relocatable"
3404 if (!CompileDeviceOnly) {
3405 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3406 <<
"-fhip-emit-relocatable"
3407 <<
"--cuda-device-only";
3412 if (Args.hasArg(options::OPT_gpu_bundle_output,
3413 options::OPT_no_gpu_bundle_output))
3414 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3415 options::OPT_no_gpu_bundle_output,
true) &&
3416 (!EmitReloc || !*EmitReloc);
3419 bool canUseBundlerUnbundler()
const override {
return true; }
3421 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3422 llvm::StringMap<bool> Features;
3429 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3430 C.setContainsError();
3434 return Args.MakeArgStringRef(CanId);
3437 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3439 const std::set<StringRef> &GpuArchs)
override {
3443 ActionBuilderReturnCode
3446 PhasesTy &Phases)
override {
3448 return ABRT_Inactive;
3454 if (CudaDeviceActions.empty())
3455 return ABRT_Success;
3458 CudaDeviceActions.size() == GpuArchList.size()) &&
3459 "Expecting one action per GPU architecture.");
3460 assert(!CompileHostOnly &&
3461 "Not expecting HIP actions in host-only compilation.");
3463 bool ShouldLink = !EmitReloc || !*EmitReloc;
3466 !EmitAsm && ShouldLink) {
3472 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3473 if (
C.getDriver().isUsingLTO(
true)) {
3477 AL.push_back(CudaDeviceActions[I]);
3480 CudaDeviceActions[I] =
3487 if (ToolChains.front()->getTriple().isSPIRV()) {
3490 types::ID Output = Args.hasArg(options::OPT_S)
3492 : types::TY_LLVM_BC;
3498 AssociatedOffloadKind);
3499 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3501 AssociatedOffloadKind);
3502 AL.push_back(AssembleAction);
3505 CudaDeviceActions[I] =
3516 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3517 AssociatedOffloadKind);
3519 DDep, CudaDeviceActions[I]->getType());
3522 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3525 types::TY_HIP_FATBIN);
3527 if (!CompileDeviceOnly) {
3528 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3529 AssociatedOffloadKind);
3532 CudaFatBinary =
nullptr;
3537 CudaDeviceActions.clear();
3540 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3543 return ABRT_Success;
3549 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3550 auto LI = DeviceLinkerInputs.begin();
3551 for (
auto *A : CudaDeviceActions) {
3558 CudaDeviceActions.clear();
3559 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3563 for (
Action *&A : CudaDeviceActions)
3564 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3565 AssociatedOffloadKind);
3567 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3569 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3571 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3572 AssociatedOffloadKind);
3574 DDep, CudaDeviceActions[I]->getType());
3578 CudaDeviceActions.clear();
3581 return (CompileDeviceOnly &&
3582 (CurPhase == FinalPhase ||
3588 void appendLinkDeviceActions(
ActionList &AL)
override {
3589 if (DeviceLinkerInputs.size() == 0)
3592 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3593 "Linker inputs and GPU arch list sizes do not match.");
3599 for (
auto &LI : DeviceLinkerInputs) {
3601 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3605 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3609 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3610 GpuArchList[I], AssociatedOffloadKind);
3612 DeviceLinkDeps, DeviceLinkAction->getType()));
3615 DeviceLinkerInputs.clear();
3618 if (Args.hasArg(options::OPT_emit_llvm)) {
3627 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3630 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3631 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3632 AssociatedOffloadKind);
3635 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3641 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3657 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3665 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3668 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3676 unsigned ValidBuilders = 0u;
3677 unsigned ValidBuildersSupportingBundling = 0u;
3678 for (
auto *SB : SpecializedBuilders) {
3679 IsValid = IsValid && !SB->initialize();
3682 if (SB->isValid()) {
3684 if (SB->canUseBundlerUnbundler())
3685 ++ValidBuildersSupportingBundling;
3689 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3692 ~OffloadingActionBuilder() {
3693 for (
auto *SB : SpecializedBuilders)
3698 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3699 assert(HostAction &&
"Invalid host action");
3700 assert(InputArg &&
"Invalid input argument");
3701 auto Loc = HostActionToInputArgMap.find(HostAction);
3702 if (Loc == HostActionToInputArgMap.end())
3703 HostActionToInputArgMap[HostAction] = InputArg;
3704 assert(HostActionToInputArgMap[HostAction] == InputArg &&
3705 "host action mapped to multiple input arguments");
3713 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3715 DeviceActionBuilder::PhasesTy &Phases) {
3719 if (SpecializedBuilders.empty())
3722 assert(HostAction &&
"Invalid host action!");
3723 recordHostAction(HostAction, InputArg);
3728 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3729 unsigned InactiveBuilders = 0u;
3730 unsigned IgnoringBuilders = 0u;
3731 for (
auto *SB : SpecializedBuilders) {
3732 if (!SB->isValid()) {
3737 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3742 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3747 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3748 OffloadKind |= SB->getAssociatedOffloadKind();
3753 if (IgnoringBuilders &&
3754 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3771 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3772 const Arg *InputArg) {
3776 recordHostAction(HostAction, InputArg);
3784 if (CanUseBundler && isa<InputAction>(HostAction) &&
3785 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3787 HostAction->
getType() == types::TY_PP_HIP)) {
3788 auto UnbundlingHostAction =
3793 HostAction = UnbundlingHostAction;
3794 recordHostAction(HostAction, InputArg);
3797 assert(HostAction &&
"Invalid host action!");
3800 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3801 for (
auto *SB : SpecializedBuilders) {
3805 auto RetCode = SB->addDeviceDependences(HostAction);
3809 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3810 "Host dependence not expected to be ignored.!");
3814 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3815 OffloadKind |= SB->getAssociatedOffloadKind();
3820 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
3830 const Arg *InputArg) {
3832 recordHostAction(HostAction, InputArg);
3836 for (
auto *SB : SpecializedBuilders) {
3839 SB->appendTopLevelActions(OffloadAL);
3846 if (CanUseBundler && HostAction &&
3847 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
3849 OffloadAL.push_back(HostAction);
3853 assert(HostAction == AL.back() &&
"Host action not in the list??");
3855 recordHostAction(HostAction, InputArg);
3856 AL.back() = HostAction;
3858 AL.append(OffloadAL.begin(), OffloadAL.end());
3868 void appendDeviceLinkActions(
ActionList &AL) {
3869 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3872 SB->appendLinkDeviceActions(AL);
3876 Action *makeHostLinkAction() {
3879 appendDeviceLinkActions(DeviceAL);
3880 if (DeviceAL.empty())
3885 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3888 HA = SB->appendLinkHostActions(DeviceAL);
3905 for (
auto *SB : SpecializedBuilders) {
3909 SB->appendLinkDependences(DDeps);
3913 unsigned ActiveOffloadKinds = 0u;
3914 for (
auto &I : InputArgToOffloadKindMap)
3915 ActiveOffloadKinds |= I.second;
3927 for (
auto *A : HostAction->
inputs()) {
3928 auto ArgLoc = HostActionToInputArgMap.find(A);
3929 if (ArgLoc == HostActionToInputArgMap.end())
3931 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
3932 if (OFKLoc == InputArgToOffloadKindMap.end())
3944 nullptr, ActiveOffloadKinds);
3950void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
3951 const InputList &Inputs,
3955 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3956 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3957 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3958 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3959 Args.eraseArg(options::OPT__SLASH_Yc);
3960 Args.eraseArg(options::OPT__SLASH_Yu);
3961 YcArg = YuArg =
nullptr;
3963 if (YcArg && Inputs.size() > 1) {
3964 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3965 Args.eraseArg(options::OPT__SLASH_Yc);
3973 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
3974 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
3975 Args.AddFlagArg(
nullptr,
3976 getOpts().getOption(options::OPT_frtlib_add_rpath));
3979 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
3980 Diag(clang::diag::err_drv_emit_llvm_link);
3982 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
3983 .equals_insensitive(
"lld"))
3984 Diag(clang::diag::err_drv_lto_without_lld);
3990 if (!Args.hasArg(options::OPT_dumpdir)) {
3991 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
3992 Arg *Arg = Args.MakeSeparateArg(
3993 nullptr,
getOpts().getOption(options::OPT_dumpdir),
3995 (FinalOutput ? FinalOutput->getValue()
4007 Args.eraseArg(options::OPT__SLASH_Fp);
4008 Args.eraseArg(options::OPT__SLASH_Yc);
4009 Args.eraseArg(options::OPT__SLASH_Yu);
4010 YcArg = YuArg =
nullptr;
4013 unsigned LastPLSize = 0;
4014 for (
auto &I : Inputs) {
4016 const Arg *InputArg = I.second;
4019 LastPLSize = PL.size();
4024 if (InitialPhase > FinalPhase) {
4025 if (InputArg->isClaimed())
4032 if (Args.hasArg(options::OPT_Qunused_arguments))
4038 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4039 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4043 (Args.getLastArg(options::OPT__SLASH_EP,
4044 options::OPT__SLASH_P) ||
4045 Args.getLastArg(options::OPT_E) ||
4046 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4048 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4049 << InputArg->getAsString(Args) << !!FinalPhaseArg
4050 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4052 Diag(clang::diag::warn_drv_input_file_unused)
4053 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4055 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4068 Actions.push_back(ClangClPch);
4082 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4083 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4089 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4091 if (!SuppressMissingInputWarning && Inputs.empty()) {
4092 Diag(clang::diag::err_drv_no_input_files);
4097 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4098 StringRef
V = A->getValue();
4099 if (Inputs.size() > 1 && !
V.empty() &&
4100 !llvm::sys::path::is_separator(
V.back())) {
4102 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4103 << A->getSpelling() <<
V;
4104 Args.eraseArg(options::OPT__SLASH_Fo);
4109 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4110 StringRef
V = A->getValue();
4111 if (Inputs.size() > 1 && !
V.empty() &&
4112 !llvm::sys::path::is_separator(
V.back())) {
4114 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4115 << A->getSpelling() <<
V;
4116 Args.eraseArg(options::OPT__SLASH_Fa);
4121 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4122 if (A->getValue()[0] ==
'\0') {
4124 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4125 Args.eraseArg(options::OPT__SLASH_o);
4129 handleArguments(
C, Args, Inputs, Actions);
4131 bool UseNewOffloadingDriver =
4133 Args.hasFlag(options::OPT_offload_new_driver,
4134 options::OPT_no_offload_new_driver,
false);
4137 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4138 !UseNewOffloadingDriver
4139 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4147 for (
auto &I : Inputs) {
4149 const Arg *InputArg = I.second;
4162 if (!UseNewOffloadingDriver)
4163 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4169 if (!UseNewOffloadingDriver)
4170 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4171 Current, InputArg, Phase, PL.back(), FullPL);
4177 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4180 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4181 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4183 LinkerInputs.push_back(Current);
4193 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4194 MergerInputs.push_back(Current);
4212 if (NewCurrent == Current)
4215 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4218 Current = NewCurrent;
4222 if (UseNewOffloadingDriver)
4226 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4230 if (Current->getType() == types::TY_Nothing)
4236 Actions.push_back(Current);
4239 if (!UseNewOffloadingDriver)
4240 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4242 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4248 if (LinkerInputs.empty()) {
4251 if (!UseNewOffloadingDriver)
4252 OffloadBuilder->appendDeviceLinkActions(Actions);
4255 if (!LinkerInputs.empty()) {
4256 if (!UseNewOffloadingDriver)
4257 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4258 LinkerInputs.push_back(Wrapper);
4263 }
else if (UseNewOffloadingDriver ||
4264 Args.hasArg(options::OPT_offload_link)) {
4271 if (!UseNewOffloadingDriver)
4272 LA = OffloadBuilder->processHostLinkAction(LA);
4273 Actions.push_back(LA);
4277 if (!MergerInputs.empty())
4281 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4288 for (
auto &I : Inputs) {
4290 const Arg *InputArg = I.second;
4295 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4296 InputType == types::TY_Asm)
4301 for (
auto Phase : PhaseList) {
4305 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4310 if (InputType == types::TY_Object)
4317 assert(Phase == PhaseList.back() &&
4318 "merging must be final compilation step.");
4319 MergerInputs.push_back(Current);
4328 Actions.push_back(Current);
4332 if (!MergerInputs.empty())
4337 for (
auto Opt : {options::OPT_print_supported_cpus,
4338 options::OPT_print_supported_extensions}) {
4345 if (Arg *A = Args.getLastArg(Opt)) {
4346 if (Opt == options::OPT_print_supported_extensions &&
4347 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4348 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4349 !
C.getDefaultToolChain().getTriple().isARM()) {
4350 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4351 <<
"--print-supported-extensions";
4360 for (
auto &I : Inputs)
4366 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4370 if (TC.requiresValidation(Args)) {
4371 Action *LastAction = Actions.back();
4373 LastAction, types::TY_DX_CONTAINER));
4378 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4384 const llvm::opt::DerivedArgList &Args,
4386 const llvm::Triple &Triple,
4387 bool SuppressError =
false) {
4391 if (!SuppressError && Triple.isNVPTX() &&
4393 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4394 <<
"CUDA" << ArchStr;
4396 }
else if (!SuppressError && Triple.isAMDGPU() &&
4398 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4399 <<
"HIP" << ArchStr;
4407 llvm::StringMap<bool> Features;
4413 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4414 C.setContainsError();
4426static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4428 llvm::Triple Triple) {
4429 if (!Triple.isAMDGPU())
4430 return std::nullopt;
4432 std::set<StringRef> ArchSet;
4433 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4440 bool SuppressError)
const {
4442 TC = &
C.getDefaultToolChain();
4445 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4446 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4447 options::OPT_no_offload_arch_EQ)) {
4448 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4450 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4452 :
"--no-offload-arch");
4455 if (KnownArchs.contains(TC))
4456 return KnownArchs.lookup(TC);
4459 for (
auto *Arg : Args) {
4461 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4462 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4465 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4466 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4467 Arg = ExtractedArg.get();
4472 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4473 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4474 if (Arch ==
"native" || Arch.empty()) {
4478 llvm::consumeError(GPUsOrErr.takeError());
4481 << llvm::Triple::getArchTypeName(TC->
getArch())
4482 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4486 for (
auto ArchStr : *GPUsOrErr) {
4493 C, Args, Arch, TC->
getTriple(), SuppressError);
4494 if (ArchStr.empty())
4496 Archs.insert(ArchStr);
4499 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4500 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4501 if (Arch ==
"all") {
4505 C, Args, Arch, TC->
getTriple(), SuppressError);
4506 if (ArchStr.empty())
4508 Archs.erase(ArchStr);
4514 if (
auto ConflictingArchs =
4516 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4517 << ConflictingArchs->first << ConflictingArchs->second;
4518 C.setContainsError();
4525 if (Archs.empty()) {
4531 Archs.insert(StringRef());
4533 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4534 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4541 llvm::opt::DerivedArgList &Args,
4543 Action *HostAction)
const {
4548 !(isa<CompileJobAction>(HostAction) ||
4562 auto TCRange =
C.getOffloadToolChains(Kind);
4563 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4564 ToolChains.push_back(TI->second);
4566 if (ToolChains.empty())
4570 const Arg *InputArg = Input.second;
4581 TCAndArchs.push_back(std::make_pair(TC, Arch));
4583 for (
unsigned I = 0, E = TCAndArchs.size(); I != E; ++I)
4584 DeviceActions.push_back(
C.MakeAction<
InputAction>(*InputArg, InputType));
4586 if (DeviceActions.empty())
4593 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4597 auto TCAndArch = TCAndArchs.begin();
4598 for (
Action *&A : DeviceActions) {
4599 if (A->
getType() == types::TY_Nothing)
4607 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4609 HostAction->
getType() != types::TY_Nothing) {
4616 TCAndArch->second.data(), Kind);
4618 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4627 for (
Action *&A : DeviceActions) {
4628 if ((A->
getType() != types::TY_Object &&
4629 A->
getType() != types::TY_LTO_BC) ||
4631 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4637 auto TCAndArch = TCAndArchs.begin();
4638 for (
Action *A : DeviceActions) {
4639 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4641 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4646 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4648 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4656 bool ShouldBundleHIP =
4658 Args.hasFlag(options::OPT_gpu_bundle_output,
4659 options::OPT_no_gpu_bundle_output,
true) &&
4660 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4661 !llvm::any_of(OffloadActions,
4668 if (OffloadActions.empty())
4673 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4677 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4681 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4686 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4695 nullptr,
C.getActiveOffloadKinds());
4704 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4705 return A->
getType() == types::TY_Nothing;
4706 }) && isa<CompileJobAction>(HostAction);
4709 nullptr, SingleDeviceOutput ? DDep : DDeps);
4710 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4716 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4727 llvm_unreachable(
"link action invalid here.");
4729 llvm_unreachable(
"ifsmerge action invalid here.");
4734 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4735 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4736 OutputTy = types::TY_Dependencies;
4741 if (!Args.hasFlag(options::OPT_frewrite_includes,
4742 options::OPT_fno_rewrite_includes,
false) &&
4743 !Args.hasFlag(options::OPT_frewrite_imports,
4744 options::OPT_fno_rewrite_imports,
false) &&
4745 !Args.hasFlag(options::OPT_fdirectives_only,
4746 options::OPT_fno_directives_only,
false) &&
4750 "Cannot preprocess this input type!");
4756 if (Args.hasArg(options::OPT_extract_api))
4763 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
4764 !Args.getLastArg(options::OPT__precompile))
4769 "Cannot precompile this input type!");
4773 const char *ModName =
nullptr;
4774 if (OutputTy == types::TY_PCH) {
4775 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4776 ModName = A->getValue();
4778 OutputTy = types::TY_ModuleFile;
4781 if (Args.hasArg(options::OPT_fsyntax_only)) {
4783 OutputTy = types::TY_Nothing;
4789 if (Args.hasArg(options::OPT_fsyntax_only))
4791 if (Args.hasArg(options::OPT_rewrite_objc))
4793 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
4795 types::TY_RewrittenLegacyObjC);
4796 if (Args.hasArg(options::OPT__analyze))
4798 if (Args.hasArg(options::OPT__migrate))
4800 if (Args.hasArg(options::OPT_emit_ast))
4802 if (Args.hasArg(options::OPT_module_file_info))
4804 if (Args.hasArg(options::OPT_verify_pch))
4806 if (Args.hasArg(options::OPT_extract_api))
4813 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
4814 !Args.hasArg(options::OPT_emit_llvm))
4815 Output = types::TY_PP_Asm;
4816 else if (Args.hasArg(options::OPT_S))
4817 Output = types::TY_LTO_IR;
4819 Output = types::TY_LTO_BC;
4825 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
4828 if (Args.hasArg(options::OPT_emit_llvm) ||
4832 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4836 Args.hasArg(options::OPT_S) &&
4840 !Args.hasFlag(options::OPT_offload_new_driver,
4841 options::OPT_no_offload_new_driver,
false)))
4843 : types::TY_LLVM_BC;
4852 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4856 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4858 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
4878 unsigned NumOutputs = 0;
4879 unsigned NumIfsOutputs = 0;
4880 for (
const Action *A :
C.getActions()) {
4881 if (A->
getType() != types::TY_Nothing &&
4882 A->
getType() != types::TY_DX_CONTAINER &&
4884 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
4886 0 == NumIfsOutputs++) ||
4891 A->
getType() == types::TY_Nothing &&
4892 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
4893 NumOutputs += A->
size();
4896 if (NumOutputs > 1) {
4897 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
4898 FinalOutput =
nullptr;
4902 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
4905 llvm::StringSet<> ArchNames;
4906 if (RawTriple.isOSBinFormatMachO())
4907 for (
const Arg *A :
C.getArgs())
4908 if (A->getOption().matches(options::OPT_arch))
4909 ArchNames.insert(A->getValue());
4912 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
4913 for (
Action *A :
C.getActions()) {
4920 const char *LinkingOutput =
nullptr;
4921 if (isa<LipoJobAction>(A)) {
4923 LinkingOutput = FinalOutput->getValue();
4931 ArchNames.size() > 1,
4932 LinkingOutput, CachedResults,
4939 for (
auto &J :
C.getJobs())
4940 J.InProcess =
false;
4943 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
4944 std::optional<llvm::sys::ProcessStatistics> ProcStat =
4945 Cmd.getProcessStatistics();
4949 const char *LinkingOutput =
nullptr;
4951 LinkingOutput = FinalOutput->getValue();
4952 else if (!
Cmd.getOutputFilenames().empty())
4953 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
4958 using namespace llvm;
4960 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
4961 <<
"output=" << LinkingOutput;
4962 outs() <<
", total="
4963 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
4965 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
4966 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
4970 llvm::raw_string_ostream Out(Buffer);
4971 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
4974 llvm::sys::printArg(Out, LinkingOutput, true);
4975 Out <<
',' << ProcStat->TotalTime.count() <<
','
4976 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
4980 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
4981 llvm::sys::fs::OF_Append |
4982 llvm::sys::fs::OF_Text);
4987 llvm::errs() <<
"ERROR: Cannot lock file "
4988 << CCPrintStatReportFilename <<
": "
4989 << toString(L.takeError()) <<
"\n";
5000 if (Diags.hasErrorOccurred() ||
5001 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5005 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5007 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5010 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5011 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5013 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5017 return strstr(J.getCreator().getShortName(),
"assembler");
5019 for (Arg *A :
C.getArgs()) {
5023 if (!A->isClaimed()) {
5029 const Option &Opt = A->getOption();
5030 if (Opt.getKind() == Option::FlagClass) {
5031 bool DuplicateClaimed =
false;
5033 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5034 if (AA->isClaimed()) {
5035 DuplicateClaimed =
true;
5040 if (DuplicateClaimed)
5046 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5048 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5053 !
C.getActions().empty()) {
5054 Diag(diag::err_drv_unsupported_opt_for_target)
5055 << A->getSpelling() << getTargetTriple();
5057 Diag(clang::diag::warn_drv_unused_argument)
5058 << A->getAsString(
C.getArgs());
5068class ToolSelector final {
5079 bool IsHostSelector;
5090 bool CanBeCollapsed =
true) {
5092 if (Inputs.size() != 1)
5095 Action *CurAction = *Inputs.begin();
5096 if (CanBeCollapsed &&
5102 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5106 if (!IsHostSelector) {
5107 if (OA->hasSingleDeviceDependence(
true)) {
5109 OA->getSingleDeviceDependence(
true);
5110 if (CanBeCollapsed &&
5113 SavedOffloadAction.push_back(OA);
5114 return dyn_cast<JobAction>(CurAction);
5116 }
else if (OA->hasHostDependence()) {
5117 CurAction = OA->getHostDependence();
5118 if (CanBeCollapsed &&
5121 SavedOffloadAction.push_back(OA);
5122 return dyn_cast<JobAction>(CurAction);
5127 return dyn_cast<JobAction>(CurAction);
5131 bool canCollapseAssembleAction()
const {
5132 return TC.useIntegratedAs() && !SaveTemps &&
5133 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5134 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5135 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5136 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5140 bool canCollapsePreprocessorAction()
const {
5141 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5142 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5143 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5148 struct JobActionInfo final {
5158 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5160 unsigned ElementNum) {
5161 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5162 for (
unsigned I = 0; I < ElementNum; ++I)
5163 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5164 ActionInfo[I].SavedOffloadAction.end());
5180 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5182 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5183 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5184 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5185 if (!AJ || !BJ || !CJ)
5189 const Tool *
T = TC.SelectTool(*CJ);
5196 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5202 const Tool *BT = TC.SelectTool(*BJ);
5207 if (!
T->hasIntegratedAssembler())
5210 Inputs = CJ->getInputs();
5211 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5218 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5220 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5221 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5226 const Tool *
T = TC.SelectTool(*BJ);
5230 if (!
T->hasIntegratedAssembler())
5233 Inputs = BJ->getInputs();
5234 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5241 if (ActionInfo.size() < 2)
5243 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5244 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5253 bool InputIsBitcode =
true;
5254 for (
size_t i = 1; i < ActionInfo.size(); i++)
5255 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5256 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5257 InputIsBitcode =
false;
5260 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5264 const Tool *
T = TC.SelectTool(*CJ);
5271 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5274 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5277 Inputs = CJ->getInputs();
5278 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5289 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5295 for (
Action *A : Inputs) {
5296 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5297 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5298 NewInputs.push_back(A);
5304 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5305 PreprocessJobOffloadActions.end());
5306 NewInputs.append(PJ->input_begin(), PJ->input_end());
5314 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5316 assert(BaseAction &&
"Invalid base action.");
5333 ActionChain.back().JA = BaseAction;
5334 while (ActionChain.back().JA) {
5335 const Action *CurAction = ActionChain.back().JA;
5338 ActionChain.resize(ActionChain.size() + 1);
5339 JobActionInfo &AI = ActionChain.back();
5343 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5347 ActionChain.pop_back();
5355 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5356 CollapsedOffloadAction);
5358 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5360 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5366 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5378 StringRef BoundArch,
5380 std::string TriplePlusArch = TC->
getTriple().normalize();
5381 if (!BoundArch.empty()) {
5382 TriplePlusArch +=
"-";
5383 TriplePlusArch += BoundArch;
5385 TriplePlusArch +=
"-";
5387 return TriplePlusArch;
5392 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5393 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5396 std::pair<const Action *, std::string> ActionTC = {
5398 auto CachedResult = CachedResults.find(ActionTC);
5399 if (CachedResult != CachedResults.end()) {
5400 return CachedResult->second;
5403 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5404 CachedResults, TargetDeviceOffloadKind);
5405 CachedResults[ActionTC] =
Result;
5410 const JobAction *JA,
const char *BaseInput,
5413 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5417 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5418 Path = A->getValue();
5419 if (llvm::sys::fs::is_directory(Path)) {
5421 llvm::sys::path::replace_extension(Tmp,
"json");
5422 llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
5425 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5428 Path = DumpDir->getValue();
5429 Path += llvm::sys::path::filename(BaseInput);
5431 Path =
Result.getFilename();
5433 llvm::sys::path::replace_extension(Path,
"json");
5435 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5436 C.addTimeTraceFile(ResultFile, JA);
5437 C.addResultFile(ResultFile, JA);
5442 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5443 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5446 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5449 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5482 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5484 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5485 const char *DepBoundArch) {
5488 LinkingOutput, CachedResults,
5498 OA->doOnEachDependence(
5499 BuildingForOffloadDevice,
5502 C, DepA, DepTC, DepBoundArch,
false,
5503 !!DepBoundArch, LinkingOutput, CachedResults,
5507 A = BuildingForOffloadDevice
5508 ? OA->getSingleDeviceDependence(
true)
5509 : OA->getHostDependence();
5513 std::pair<const Action *, std::string> ActionTC = {
5514 OA->getHostDependence(),
5516 if (CachedResults.find(ActionTC) != CachedResults.end()) {
5518 Inputs.append(OffloadDependencesInputInfo);
5523 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5526 const Arg &Input = IA->getInputArg();
5528 if (Input.getOption().matches(options::OPT_INPUT)) {
5529 const char *
Name = Input.getValue();
5539 if (!ArchName.empty())
5540 TC = &getToolChain(
C.getArgs(),
5542 C.getArgs(), ArchName));
5544 TC = &
C.getDefaultToolChain();
5547 MultipleArchs, LinkingOutput, CachedResults,
5548 TargetDeviceOffloadKind);
5554 const JobAction *JA = cast<JobAction>(A);
5559 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5566 for (
const auto *OA : CollapsedOffloadActions)
5567 cast<OffloadAction>(OA)->doOnEachDependence(
5568 BuildingForOffloadDevice,
5571 C, DepA, DepTC, DepBoundArch,
false,
5572 !!DepBoundArch, LinkingOutput, CachedResults,
5578 for (
const Action *Input : Inputs) {
5582 bool SubJobAtTopLevel =
5583 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5585 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5590 const char *BaseInput = InputInfos[0].getBaseInput();
5591 for (
auto &Info : InputInfos) {
5592 if (Info.isFilename()) {
5593 BaseInput = Info.getBaseInput();
5600 if (JA->
getType() == types::TY_dSYM)
5601 BaseInput = InputInfos[0].getFilename();
5604 if (!OffloadDependencesInputInfo.empty())
5605 InputInfos.append(OffloadDependencesInputInfo.begin(),
5606 OffloadDependencesInputInfo.end());
5609 llvm::Triple EffectiveTriple;
5611 const ArgList &Args =
5613 if (InputInfos.size() != 1) {
5617 EffectiveTriple = llvm::Triple(
5625 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5629 for (
auto &UI : UA->getDependentActionsInfo()) {
5631 "Unbundling with no offloading??");
5638 UI.DependentOffloadKind,
5639 UI.DependentToolChain->getTriple().normalize(),
5650 UnbundlingResults.push_back(CurI);
5659 Arch = UI.DependentBoundArch;
5664 UI.DependentOffloadKind)}] = {
5670 std::pair<const Action *, std::string> ActionTC = {
5672 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5673 "Result does not exist??");
5674 Result = CachedResults[ActionTC].front();
5675 }
else if (JA->
getType() == types::TY_Nothing)
5682 isa<OffloadPackagerJobAction>(A) ||
5686 AtTopLevel, MultipleArchs,
5689 if (
T->canEmitIR() && OffloadingPrefix.empty())
5694 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5695 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5696 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5697 llvm::errs() << InputInfos[i].getAsString();
5699 llvm::errs() <<
", ";
5701 if (UnbundlingResults.empty())
5702 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5704 llvm::errs() <<
"], outputs: [";
5705 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5706 llvm::errs() << UnbundlingResults[i].getAsString();
5708 llvm::errs() <<
", ";
5710 llvm::errs() <<
"] \n";
5713 if (UnbundlingResults.empty())
5719 T->ConstructJobMultipleOutputs(
5720 C, *JA, UnbundlingResults, InputInfos,
5728 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5729 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5741 if (ArgValue.empty()) {
5744 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
5746 llvm::sys::path::append(
Filename, BaseName);
5749 if (!llvm::sys::path::has_extension(ArgValue)) {
5754 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5759 llvm::sys::path::replace_extension(
Filename, Extension);
5762 return Args.MakeArgString(
Filename.c_str());
5766 if (isa<PreprocessJobAction>(JA))
5768 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
5770 if (isa<OffloadBundlingJobAction>(JA) &&
5777 StringRef Suffix,
bool MultipleArchs,
5778 StringRef BoundArch,
5779 bool NeedUniqueDirectory)
const {
5781 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
5782 std::optional<std::string> CrashDirectory =
5784 ? std::string(A->getValue())
5785 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
5786 if (CrashDirectory) {
5787 if (!
getVFS().exists(*CrashDirectory))
5788 llvm::sys::fs::create_directories(*CrashDirectory);
5790 llvm::sys::path::append(Path, Prefix);
5791 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
5792 if (std::error_code EC =
5793 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
5794 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
5798 if (MultipleArchs && !BoundArch.empty()) {
5799 if (NeedUniqueDirectory) {
5801 llvm::sys::path::append(TmpName,
5802 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
5812 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5827 const char *BaseInput) {
5828 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
5829 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
5830 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
5835 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
5839 const char *BaseInput,
5840 StringRef OrigBoundArch,
bool AtTopLevel,
5842 StringRef OffloadingPrefix)
const {
5843 std::string BoundArch = OrigBoundArch.str();
5844 if (is_style_windows(llvm::sys::path::Style::native)) {
5847 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
5850 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
5852 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
5853 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
5854 return C.addResultFile(FinalOutput->getValue(), &JA);
5858 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
5859 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
5860 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5862 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
5863 NameArg = A->getValue();
5864 return C.addResultFile(
5874 if (JA.
getType() == types::TY_ModuleFile &&
5875 C.getArgs().getLastArg(options::OPT_module_file_info)) {
5879 if (JA.
getType() == types::TY_PP_Asm &&
5880 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
5881 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
5884 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
5887 if (JA.
getType() == types::TY_Object &&
5888 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
5889 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
5892 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
5896 if (JA.
getType() == types::TY_PP_Asm &&
5897 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
5898 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
5900 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5901 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
5902 return C.addResultFile(
5907 if (JA.
getType() == types::TY_API_INFO &&
5908 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
5909 C.getArgs().hasArg(options::OPT_o))
5910 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
5911 <<
C.getArgs().getLastArgValue(options::OPT_o);
5918 bool SpecifiedModuleOutput =
5919 C.getArgs().hasArg(options::OPT_fmodule_output) ||
5920 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
5921 if (MultipleArchs && SpecifiedModuleOutput)
5922 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
5926 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
5927 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
5928 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
5934 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
5936 StringRef
Name = llvm::sys::path::filename(BaseInput);
5937 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5938 const char *Suffix =
5943 llvm::Triple Triple(
C.getDriver().getTargetTriple());
5944 bool NeedUniqueDirectory =
5947 Triple.isOSDarwin();
5948 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
5949 NeedUniqueDirectory);
5957 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
5958 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
5963 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
5964 llvm::sys::path::filename(BasePath));
5965 BaseName = ExternalPath;
5966 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
5967 BaseName = BasePath;
5969 BaseName = llvm::sys::path::filename(BasePath);
5972 const char *NamedOutput;
5974 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
5975 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
5979 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
5983 }
else if (JA.
getType() == types::TY_Image &&
5984 C.getArgs().hasArg(options::OPT__SLASH_Fe,
5985 options::OPT__SLASH_o)) {
5989 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
5993 }
else if (JA.
getType() == types::TY_Image) {
6003 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6004 options::OPT_fno_gpu_rdc,
false);
6005 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6006 if (UseOutExtension) {
6008 llvm::sys::path::replace_extension(Output,
"");
6010 Output += OffloadingPrefix;
6011 if (MultipleArchs && !BoundArch.empty()) {
6013 Output.append(BoundArch);
6015 if (UseOutExtension)
6017 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6020 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6021 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6022 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6025 .getLastArg(options::OPT__SLASH_o)
6030 const char *Suffix =
6032 assert(Suffix &&
"All types used for output should have a suffix.");
6034 std::string::size_type End = std::string::npos;
6036 End = BaseName.rfind(
'.');
6038 Suffixed += OffloadingPrefix;
6039 if (MultipleArchs && !BoundArch.empty()) {
6041 Suffixed.append(BoundArch);
6046 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6047 const llvm::opt::DerivedArgList &Args) {
6052 return isa<CompileJobAction>(JA) &&
6054 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6059 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6060 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6061 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6065 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6069 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6070 JA.
getType() != types::TY_PCH) {
6071 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6073 llvm::sys::path::remove_filename(TempPath);
6074 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6075 llvm::sys::path::append(TempPath, OutputFileName);
6076 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6082 bool SameFile =
false;
6084 llvm::sys::fs::current_path(
Result);
6085 llvm::sys::path::append(
Result, BaseName);
6086 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6089 StringRef
Name = llvm::sys::path::filename(BaseInput);
6090 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6094 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6100 llvm::sys::path::remove_filename(BasePath);
6101 if (BasePath.empty())
6102 BasePath = NamedOutput;
6104 llvm::sys::path::append(BasePath, NamedOutput);
6105 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6108 return C.addResultFile(NamedOutput, &JA);
6114 -> std::optional<std::string> {
6117 for (
const auto &
Dir :
P) {
6121 llvm::sys::path::append(
P,
Name);
6122 if (llvm::sys::fs::exists(Twine(
P)))
6123 return std::string(
P);
6125 return std::nullopt;
6132 llvm::sys::path::append(R,
Name);
6133 if (llvm::sys::fs::exists(Twine(R)))
6134 return std::string(R);
6137 llvm::sys::path::append(
P,
Name);
6138 if (llvm::sys::fs::exists(Twine(
P)))
6139 return std::string(
P);
6142 llvm::sys::path::append(D,
"..",
Name);
6143 if (llvm::sys::fs::exists(Twine(D)))
6144 return std::string(D);
6152 return std::string(
Name);
6155void Driver::generatePrefixedToolNames(
6159 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6160 Names.emplace_back(
Tool);
6164 llvm::sys::path::append(Dir, Name);
6165 if (llvm::sys::fs::can_execute(Twine(Dir)))
6167 llvm::sys::path::remove_filename(Dir);
6173 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6178 if (llvm::sys::fs::is_directory(PrefixDir)) {
6181 return std::string(
P);
6184 if (llvm::sys::fs::can_execute(Twine(
P)))
6185 return std::string(
P);
6190 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6198 for (
const auto &Path : List) {
6201 return std::string(
P);
6205 if (llvm::ErrorOr<std::string>
P =
6206 llvm::sys::findProgramByName(TargetSpecificExecutable))
6210 return std::string(
Name);
6215 std::string error =
"<NOT PRESENT>";
6219 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6236 llvm::sys::path::remove_filename(path);
6237 llvm::sys::path::append(path,
"libc++.modules.json");
6238 if (TC.
getVFS().exists(path))
6239 return static_cast<std::string
>(path);
6244 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6247 return evaluate(
"libc++.a").value_or(error);
6260 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6262 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6266 return std::string(Path);
6271 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6273 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6277 return std::string(Path);
6282 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6286 Output = FpArg->getValue();
6290 if (!llvm::sys::path::has_extension(Output))
6293 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6294 Output = YcArg->getValue();
6297 llvm::sys::path::replace_extension(Output,
".pch");
6299 return std::string(Output);
6302const ToolChain &Driver::getToolChain(
const ArgList &Args,
6303 const llvm::Triple &
Target)
const {
6305 auto &TC = ToolChains[
Target.str()];
6307 switch (
Target.getOS()) {
6308 case llvm::Triple::AIX:
6309 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6311 case llvm::Triple::Haiku:
6312 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6314 case llvm::Triple::Darwin:
6315 case llvm::Triple::MacOSX:
6316 case llvm::Triple::IOS:
6317 case llvm::Triple::TvOS:
6318 case llvm::Triple::WatchOS:
6319 case llvm::Triple::XROS:
6320 case llvm::Triple::DriverKit:
6321 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6323 case llvm::Triple::DragonFly:
6324 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6326 case llvm::Triple::OpenBSD:
6327 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6329 case llvm::Triple::NetBSD:
6330 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6332 case llvm::Triple::FreeBSD:
6334 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6337 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6339 case llvm::Triple::Linux:
6340 case llvm::Triple::ELFIAMCU:
6341 if (
Target.getArch() == llvm::Triple::hexagon)
6342 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6344 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6345 !
Target.hasEnvironment())
6346 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6349 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6351 else if (
Target.getArch() == llvm::Triple::ve)
6352 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6353 else if (
Target.isOHOSFamily())
6354 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6356 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6358 case llvm::Triple::NaCl:
6359 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6361 case llvm::Triple::Fuchsia:
6362 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6364 case llvm::Triple::Solaris:
6365 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6367 case llvm::Triple::CUDA:
6368 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6370 case llvm::Triple::AMDHSA:
6371 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6373 case llvm::Triple::AMDPAL:
6374 case llvm::Triple::Mesa3D:
6375 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6377 case llvm::Triple::Win32:
6378 switch (
Target.getEnvironment()) {
6380 if (
Target.isOSBinFormatELF())
6381 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6382 else if (
Target.isOSBinFormatMachO())
6383 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6385 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6387 case llvm::Triple::GNU:
6388 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6390 case llvm::Triple::Itanium:
6391 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6394 case llvm::Triple::MSVC:
6395 case llvm::Triple::UnknownEnvironment:
6396 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6397 .starts_with_insensitive(
"bfd"))
6398 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6402 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6406 case llvm::Triple::PS4:
6407 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6409 case llvm::Triple::PS5:
6410 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6412 case llvm::Triple::Hurd:
6413 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6415 case llvm::Triple::LiteOS:
6416 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6418 case llvm::Triple::ZOS:
6419 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6421 case llvm::Triple::ShaderModel:
6422 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6427 switch (
Target.getArch()) {
6428 case llvm::Triple::tce:
6429 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6431 case llvm::Triple::tcele:
6432 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6434 case llvm::Triple::hexagon:
6435 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6438 case llvm::Triple::lanai:
6439 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6441 case llvm::Triple::xcore:
6442 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6444 case llvm::Triple::wasm32:
6445 case llvm::Triple::wasm64:
6446 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6448 case llvm::Triple::avr:
6449 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6451 case llvm::Triple::msp430:
6453 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6455 case llvm::Triple::riscv32:
6456 case llvm::Triple::riscv64:
6459 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6461 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6463 case llvm::Triple::ve:
6464 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6466 case llvm::Triple::spirv32:
6467 case llvm::Triple::spirv64:
6468 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6470 case llvm::Triple::csky:
6471 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6475 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6476 else if (
Target.isOSBinFormatELF())
6477 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6478 else if (
Target.isOSBinFormatMachO())
6479 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6481 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6489const ToolChain &Driver::getOffloadingDeviceToolChain(
6490 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6499 switch (TargetDeviceOffloadKind) {
6501 if (
Target.getArch() == llvm::Triple::amdgcn &&
6502 Target.getVendor() == llvm::Triple::AMD &&
6503 Target.getOS() == llvm::Triple::AMDHSA)
6504 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6506 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6507 Target.getVendor() == llvm::Triple::UnknownVendor &&
6508 Target.getOS() == llvm::Triple::UnknownOS)
6509 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6523 if (JA.
size() != 1 ||
6528 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6529 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6530 !isa<ExtractAPIJobAction>(JA))
6538 if (JA.
size() != 1 ||
6543 if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) &&
6544 !isa<BackendJobAction>(JA))
6552 if (Args.hasArg(options::OPT_emit_static_lib))
6563 unsigned &Micro,
bool &HadExtra) {
6566 Major = Minor = Micro = 0;
6570 if (Str.consumeInteger(10, Major))
6574 if (!Str.consume_front(
"."))
6577 if (Str.consumeInteger(10, Minor))
6581 if (!Str.consume_front(
"."))
6584 if (Str.consumeInteger(10, Micro))
6602 unsigned CurDigit = 0;
6603 while (CurDigit < Digits.size()) {
6605 if (Str.consumeInteger(10, Digit))
6607 Digits[CurDigit] = Digit;
6610 if (!Str.consume_front(
"."))
6619llvm::opt::Visibility
6620Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6633const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6649 llvm_unreachable(
"Unhandled Mode");
6653 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6658 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6659 options::OPT_fno_save_optimization_record,
false))
6663 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6664 options::OPT_fno_save_optimization_record,
false))
6668 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6669 options::OPT_fno_save_optimization_record,
false))
6673 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6674 options::OPT_fno_save_optimization_record,
false))
6681 static StringRef OptName =
6683 llvm::StringRef Opt;
6684 for (StringRef Arg : Args) {
6685 if (!Arg.starts_with(OptName))
6691 return Opt.consume_front(OptName) ? Opt :
"";
6698 llvm::BumpPtrAllocator &Alloc,
6699 llvm::vfs::FileSystem *FS) {
6708 for (
const char *F : Args) {
6709 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6711 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6712 RSPQuoting = Windows;
6720 llvm::cl::TokenizerCallback Tokenizer;
6722 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6724 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6726 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6729 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6730 ECtx.setMarkEOLs(MarkEOLs);
6734 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
6738 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
6739 [](
const char *A) {
return A !=
nullptr; });
6740 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
6743 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
6744 Args.resize(newEnd - Args.begin());
6748 return llvm::Error::success();
6752 return SavedStrings.insert(S).first->getKeyData();
6785 llvm::StringSet<> &SavedStrings) {
6788 if (Edit[0] ==
'^') {
6789 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6790 OS <<
"### Adding argument " << Str <<
" at beginning\n";
6791 Args.insert(Args.begin() + 1, Str);
6792 }
else if (Edit[0] ==
'+') {
6793 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6794 OS <<
"### Adding argument " << Str <<
" at end\n";
6795 Args.push_back(Str);
6796 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
6797 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
6798 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
6799 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
6800 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
6802 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
6804 if (Args[i] ==
nullptr)
6806 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
6808 if (Repl != Args[i]) {
6809 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
6813 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
6814 auto Option = Edit.substr(1);
6815 for (
unsigned i = 1; i < Args.size();) {
6816 if (Option == Args[i]) {
6817 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6818 Args.erase(Args.begin() + i);
6819 if (Edit[0] ==
'X') {
6820 if (i < Args.size()) {
6821 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6822 Args.erase(Args.begin() + i);
6824 OS <<
"### Invalid X edit, end of command line!\n";
6829 }
else if (Edit[0] ==
'O') {
6830 for (
unsigned i = 1; i < Args.size();) {
6831 const char *A = Args[i];
6835 if (A[0] ==
'-' && A[1] ==
'O' &&
6836 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
6837 (
'0' <= A[2] && A[2] <=
'9'))))) {
6838 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6839 Args.erase(Args.begin() + i);
6843 OS <<
"### Adding argument " << Edit <<
" at end\n";
6844 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
6846 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
6851 const char *OverrideStr,
6852 llvm::StringSet<> &SavedStrings,
6855 OS = &llvm::nulls();
6857 if (OverrideStr[0] ==
'#') {
6859 OS = &llvm::nulls();
6862 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
6866 const char *S = OverrideStr;
6868 const char *End = ::strchr(S,
' ');
6870 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.