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 auto OffloadArchs = Args.getAllArgValues(options::OPT_offload_arch_EQ);
151 if (llvm::is_contained(OffloadArchs,
"amdgcnspirv")) {
152 if (OffloadArchs.size() == 1)
153 return llvm::Triple(
"spirv64-amd-amdhsa");
155 D.Diag(diag::err_drv_only_one_offload_target_supported);
158 return llvm::Triple(
"amdgcn-amd-amdhsa");
163 if (TT->getArch() == llvm::Triple::amdgcn &&
164 TT->getVendor() == llvm::Triple::AMD &&
165 TT->getOS() == llvm::Triple::AMDHSA)
167 if (TT->getArch() == llvm::Triple::spirv64)
169 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
175 StringRef CustomResourceDir) {
181 std::string
Dir = std::string(llvm::sys::path::parent_path(BinaryPath));
184 if (CustomResourceDir !=
"") {
185 llvm::sys::path::append(
P, CustomResourceDir);
192 P = llvm::sys::path::parent_path(
Dir);
195 llvm::sys::path::append(
P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
196 CLANG_VERSION_MAJOR_STRING);
199 return std::string(
P);
205 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
206 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
209 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
210 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
211 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
212 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
213 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
214 CheckInputsExist(
true), ProbePrecompiled(
true),
215 SuppressMissingInputWarning(
false) {
218 this->VFS = llvm::vfs::getRealFileSystem();
223 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
226 llvm::sys::path::append(
P,
SysRoot);
230#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
233#if defined(CLANG_CONFIG_FILE_USER_DIR)
236 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
245void Driver::setDriverMode(StringRef
Value) {
246 static StringRef OptName =
247 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
248 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
249 .Case(
"gcc", GCCMode)
250 .Case(
"g++", GXXMode)
251 .Case(
"cpp", CPPMode)
253 .Case(
"flang", FlangMode)
254 .Case(
"dxc", DXCMode)
258 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
262 bool UseDriverMode,
bool &ContainsError) {
263 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
264 ContainsError =
false;
266 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
267 unsigned MissingArgIndex, MissingArgCount;
268 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
269 MissingArgCount, VisibilityMask);
272 if (MissingArgCount) {
273 Diag(diag::err_drv_missing_argument)
274 << Args.getArgString(MissingArgIndex) << MissingArgCount;
281 for (
const Arg *A : Args) {
283 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
291 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
292 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
294 diag::warn_drv_empty_joined_argument,
299 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
301 auto ArgString = A->getAsString(Args);
303 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
305 getOpts().findExact(ArgString, Nearest,
307 DiagID = diag::err_drv_unknown_argument_with_suggestion;
308 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
310 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
311 : diag::err_drv_unknown_argument;
312 Diags.
Report(DiagID) << ArgString;
316 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
317 : diag::err_drv_unknown_argument_with_suggestion;
318 Diags.
Report(DiagID) << ArgString << Nearest;
324 for (
const Arg *A : Args.filtered(options::OPT_o)) {
325 if (ArgStrings[A->getIndex()] == A->getSpelling())
329 std::string ArgString = ArgStrings[A->getIndex()];
331 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
332 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
333 << A->getAsString(Args) << Nearest;
343 Arg **FinalPhaseArg)
const {
344 Arg *PhaseArg =
nullptr;
348 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
349 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
350 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
351 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
358 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
359 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
360 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
361 options::OPT_fmodule_header_EQ))) {
364 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
368 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
369 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
370 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
371 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
372 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
373 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
374 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
378 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
382 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
385 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
393 *FinalPhaseArg = PhaseArg;
399 StringRef
Value,
bool Claim =
true) {
400 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
401 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
402 Args.AddSynthesizedArg(A);
408DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
409 const llvm::opt::OptTable &Opts =
getOpts();
410 DerivedArgList *DAL =
new DerivedArgList(Args);
412 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
413 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
414 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
415 bool IgnoreUnused =
false;
416 for (Arg *A : Args) {
420 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
424 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
425 IgnoreUnused =
false;
435 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
436 A->getOption().matches(options::OPT_Xlinker)) &&
437 A->containsValue(
"--no-demangle")) {
439 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
442 for (StringRef Val : A->getValues())
443 if (Val !=
"--no-demangle")
444 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
452 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
453 (A->getValue(0) == StringRef(
"-MD") ||
454 A->getValue(0) == StringRef(
"-MMD"))) {
456 if (A->getValue(0) == StringRef(
"-MD"))
457 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
459 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
460 if (A->getNumValues() == 2)
461 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
466 if (A->getOption().matches(options::OPT_l)) {
467 StringRef
Value = A->getValue();
470 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
472 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
477 if (
Value ==
"cc_kext") {
478 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
484 if (A->getOption().matches(options::OPT__DASH_DASH)) {
486 for (StringRef Val : A->getValues())
495 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
496 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
499 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
500 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
504#if defined(HOST_LINK_VERSION)
505 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
506 strlen(HOST_LINK_VERSION) > 0) {
507 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
509 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
521 StringRef TargetTriple,
523 StringRef DarwinArchName =
"") {
525 if (
const Arg *A = Args.getLastArg(options::OPT_target))
526 TargetTriple = A->getValue();
528 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
533 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
537 if (
Target.isOSBinFormatMachO()) {
539 if (!DarwinArchName.empty()) {
546 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
547 StringRef ArchName = A->getValue();
554 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
555 options::OPT_mbig_endian)) {
556 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
557 ?
Target.getLittleEndianArchVariant()
558 :
Target.getBigEndianArchVariant();
559 if (
T.getArch() != llvm::Triple::UnknownArch) {
561 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
566 if (
Target.getArch() == llvm::Triple::tce)
571 if (std::optional<std::string> ObjectModeValue =
572 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
573 StringRef ObjectMode = *ObjectModeValue;
574 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
576 if (ObjectMode ==
"64") {
577 AT =
Target.get64BitArchVariant().getArch();
578 }
else if (ObjectMode ==
"32") {
579 AT =
Target.get32BitArchVariant().getArch();
581 D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
584 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
590 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
592 D.Diag(diag::err_drv_unsupported_opt_for_target)
593 << A->getAsString(Args) <<
Target.str();
596 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
597 options::OPT_m32, options::OPT_m16,
598 options::OPT_maix32, options::OPT_maix64);
600 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
602 if (A->getOption().matches(options::OPT_m64) ||
603 A->getOption().matches(options::OPT_maix64)) {
604 AT =
Target.get64BitArchVariant().getArch();
605 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
606 Target.setEnvironment(llvm::Triple::GNU);
607 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
608 Target.setEnvironment(llvm::Triple::Musl);
609 }
else if (A->getOption().matches(options::OPT_mx32) &&
610 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
611 AT = llvm::Triple::x86_64;
612 if (
Target.getEnvironment() == llvm::Triple::Musl)
613 Target.setEnvironment(llvm::Triple::MuslX32);
615 Target.setEnvironment(llvm::Triple::GNUX32);
616 }
else if (A->getOption().matches(options::OPT_m32) ||
617 A->getOption().matches(options::OPT_maix32)) {
618 AT =
Target.get32BitArchVariant().getArch();
619 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
620 Target.setEnvironment(llvm::Triple::GNU);
621 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
622 Target.setEnvironment(llvm::Triple::Musl);
623 }
else if (A->getOption().matches(options::OPT_m16) &&
624 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
625 AT = llvm::Triple::x86;
626 Target.setEnvironment(llvm::Triple::CODE16);
629 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
631 if (
Target.isWindowsGNUEnvironment())
637 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
638 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
639 D.Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
642 if (A && !A->getOption().matches(options::OPT_m32))
643 D.Diag(diag::err_drv_argument_not_allowed_with)
644 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
646 Target.setArch(llvm::Triple::x86);
647 Target.setArchName(
"i586");
648 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
649 Target.setEnvironmentName(
"");
650 Target.setOS(llvm::Triple::ELFIAMCU);
651 Target.setVendor(llvm::Triple::UnknownVendor);
652 Target.setVendorName(
"intel");
658 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
659 StringRef ABIName = A->getValue();
660 if (ABIName ==
"32") {
662 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
663 Target.getEnvironment() == llvm::Triple::GNUABIN32)
664 Target.setEnvironment(llvm::Triple::GNU);
665 }
else if (ABIName ==
"n32") {
667 if (
Target.getEnvironment() == llvm::Triple::GNU ||
668 Target.getEnvironment() == llvm::Triple::GNUABI64)
669 Target.setEnvironment(llvm::Triple::GNUABIN32);
670 }
else if (ABIName ==
"64") {
672 if (
Target.getEnvironment() == llvm::Triple::GNU ||
673 Target.getEnvironment() == llvm::Triple::GNUABIN32)
674 Target.setEnvironment(llvm::Triple::GNUABI64);
682 if (Args.hasArg(options::OPT_march_EQ) ||
683 Args.hasArg(options::OPT_mcpu_EQ)) {
685 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
687 if (!llvm::errorToBool(ISAInfo.takeError())) {
688 unsigned XLen = (*ISAInfo)->getXLen();
690 Target.setArch(llvm::Triple::riscv32);
692 Target.setArch(llvm::Triple::riscv64);
704 OptSpecifier OptEq, OptSpecifier OptNeg) {
705 if (!Args.hasFlag(OptEq, OptNeg,
false))
708 const Arg *A = Args.getLastArg(OptEq);
709 StringRef LTOName = A->getValue();
717 D.Diag(diag::err_drv_unsupported_option_argument)
718 << A->getSpelling() << A->getValue();
725void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
727 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
729 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
730 options::OPT_fno_offload_lto);
733 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
734 options::OPT_fno_openmp_target_jit,
false)) {
735 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
736 options::OPT_fno_offload_lto))
738 Diag(diag::err_drv_incompatible_options)
739 << A->getSpelling() <<
"-fopenmp-target-jit";
746 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
748 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
750 RuntimeName = A->getValue();
752 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
760 Diag(diag::err_drv_unsupported_option_argument)
761 << A->getSpelling() << A->getValue();
764 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
779 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
784 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
787 C.getInputArgs().hasArg(options::OPT_hip_link) ||
788 C.getInputArgs().hasArg(options::OPT_hipstdpar);
789 bool UseLLVMOffload =
C.getInputArgs().hasArg(
790 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
791 if (IsCuda && IsHIP) {
792 Diag(clang::diag::err_drv_mix_cuda_hip);
795 if (IsCuda && !UseLLVMOffload) {
797 const llvm::Triple &HostTriple = HostTC->
getTriple();
805 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
807 CudaTC = std::make_unique<toolchains::CudaToolChain>(
808 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
813 if (CudaInstallation.
isValid())
816 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
817 }
else if (IsHIP && !UseLLVMOffload) {
818 if (
auto *OMPTargetArg =
819 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
820 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
821 << OMPTargetArg->getSpelling() <<
"HIP";
829 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
831 assert(HIPTC &&
"Could not create offloading device tool chain.");
832 C.addOffloadDeviceToolChain(HIPTC, OFK);
840 bool IsOpenMPOffloading =
841 ((IsCuda || IsHIP) && UseLLVMOffload) ||
842 (
C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
843 options::OPT_fno_openmp,
false) &&
844 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
845 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ)));
846 if (IsOpenMPOffloading) {
852 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
856 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
857 llvm::StringMap<StringRef> FoundNormalizedTriples;
858 std::multiset<StringRef> OpenMPTriples;
863 if (Arg *OpenMPTargets =
864 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
865 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
866 Diag(clang::diag::warn_drv_empty_joined_argument)
867 << OpenMPTargets->getAsString(
C.getInputArgs());
870 for (StringRef
T : OpenMPTargets->getValues())
871 OpenMPTriples.insert(
T);
872 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
873 ((!IsHIP && !IsCuda) || UseLLVMOffload)) {
883 llvm::DenseSet<StringRef> Archs;
885 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
886 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
892 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
893 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
898 if (!AMDTriple && !NVPTXTriple) {
899 for (StringRef Arch :
904 for (StringRef Arch : Archs) {
907 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
908 }
else if (AMDTriple &&
911 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
913 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
920 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
925 for (
const auto &TripleAndArchs : DerivedArchs)
926 OpenMPTriples.insert(TripleAndArchs.first());
929 for (StringRef Val : OpenMPTriples) {
931 std::string NormalizedName = TT.normalize();
934 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
935 if (Duplicate != FoundNormalizedTriples.end()) {
936 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
937 << Val << Duplicate->second;
943 FoundNormalizedTriples[NormalizedName] = Val;
946 if (TT.getArch() == llvm::Triple::UnknownArch)
947 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
952 if (TT.isNVPTX() || TT.isAMDGCN()) {
955 assert(HostTC &&
"Host toolchain should be always defined.");
957 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
960 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
961 *
this, TT, *HostTC,
C.getInputArgs());
962 else if (TT.isAMDGCN())
963 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
964 *
this, TT, *HostTC,
C.getInputArgs());
966 assert(DeviceTC &&
"Device toolchain not defined.");
971 TC = &getToolChain(
C.getInputArgs(), TT);
973 if (DerivedArchs.contains(TT.getTriple()))
974 KnownArchs[TC] = DerivedArchs[TT.getTriple()];
977 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
978 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
988 const Arg *BaseArg) {
992 unsigned Index = Args.MakeIndex(Opt->getSpelling());
993 Arg *
Copy =
new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index),
995 Copy->getValues() = Opt->getValues();
996 if (Opt->isClaimed())
998 Copy->setOwnsValues(Opt->getOwnsValues());
999 Opt->setOwnsValues(
false);
1003bool Driver::readConfigFile(StringRef
FileName,
1004 llvm::cl::ExpansionContext &ExpCtx) {
1008 Diag(diag::err_drv_cannot_open_config_file)
1009 <<
FileName << Status.getError().message();
1012 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1013 Diag(diag::err_drv_cannot_open_config_file)
1014 <<
FileName <<
"not a regular file";
1020 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgArgs)) {
1021 Diag(diag::err_drv_cannot_read_config_file)
1028 llvm::sys::path::native(CfgFileName);
1030 std::unique_ptr<InputArgList> NewOptions = std::make_unique<InputArgList>(
1037 for (Arg *A : *NewOptions)
1041 CfgOptions = std::move(NewOptions);
1044 for (
auto *Opt : *NewOptions) {
1045 const Arg *BaseArg = &Opt->getBaseArg();
1051 ConfigFiles.push_back(std::string(CfgFileName));
1055bool Driver::loadConfigFiles() {
1056 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1057 llvm::cl::tokenizeConfigFile);
1058 ExpCtx.setVFS(&
getVFS());
1062 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1065 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1066 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1071 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1073 llvm::sys::fs::expand_tilde(
1074 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1075 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1084 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1087 if (loadDefaultConfigFiles(ExpCtx))
1093 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1096 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1097 CfgFilePath.assign(CfgFileName);
1098 if (llvm::sys::path::is_relative(CfgFilePath)) {
1099 if (
getVFS().makeAbsolute(CfgFilePath)) {
1100 Diag(diag::err_drv_cannot_open_config_file)
1101 << CfgFilePath <<
"cannot get absolute path";
1105 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1107 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1108 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1109 if (!SearchDir.empty())
1110 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1115 if (readConfigFile(CfgFilePath, ExpCtx))
1124bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1127 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1131 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1134 std::string RealMode = getExecutableForDriverMode(Mode);
1144 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1145 PrefixTriple.isOSUnknown())
1146 Triple = PrefixTriple.str();
1150 if (Triple.empty()) {
1151 llvm::Triple RealTriple =
1153 Triple = RealTriple.str();
1154 assert(!Triple.empty());
1169 std::string CfgFileName = Triple +
'-' + RealMode +
".cfg";
1170 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1171 return readConfigFile(CfgFilePath, ExpCtx);
1175 if (TryModeSuffix) {
1177 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1178 return readConfigFile(CfgFilePath, ExpCtx);
1183 CfgFileName = RealMode +
".cfg";
1184 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1185 if (readConfigFile(CfgFilePath, ExpCtx))
1187 }
else if (TryModeSuffix) {
1189 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1190 readConfigFile(CfgFilePath, ExpCtx))
1195 CfgFileName = Triple +
".cfg";
1196 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1197 return readConfigFile(CfgFilePath, ExpCtx);
1205 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1214 if (!DriverMode.empty())
1215 setDriverMode(DriverMode);
1221 CLOptions = std::make_unique<InputArgList>(
1226 ContainsError = loadConfigFiles();
1227 bool HasConfigFile = !ContainsError && (CfgOptions.get() !=
nullptr);
1230 InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
1231 : std::move(*CLOptions));
1234 for (
auto *Opt : *CLOptions) {
1235 if (Opt->getOption().matches(options::OPT_config))
1237 const Arg *BaseArg = &Opt->getBaseArg();
1244 if (
IsCLMode() && !ContainsError) {
1246 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1248 CLModePassThroughArgList.push_back(A->getValue());
1251 if (!CLModePassThroughArgList.empty()) {
1254 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1259 for (
auto *Opt : *CLModePassThroughOptions) {
1266 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1267 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1268 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1272 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1273 if (!VFS->exists(IncludeDir))
1274 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1279 bool CCCPrintPhases;
1282 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1283 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1286 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1287 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1290 Args.ClaimAllArgs(options::OPT_pipe);
1298 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1300 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1301 CCCGenericGCCName = A->getValue();
1304 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1308 if (Args.hasArg(options::OPT_fproc_stat_report))
1315 llvm::Triple
T(TargetTriple);
1316 T.setOS(llvm::Triple::Win32);
1317 T.setVendor(llvm::Triple::PC);
1318 T.setEnvironment(llvm::Triple::MSVC);
1319 T.setObjectFormat(llvm::Triple::COFF);
1320 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1321 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1322 TargetTriple =
T.str();
1325 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1326 StringRef TargetProfile = A->getValue();
1329 TargetTriple = *Triple;
1331 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1335 if (Args.hasArg(options::OPT_spirv)) {
1336 llvm::Triple
T(TargetTriple);
1337 T.setArch(llvm::Triple::spirv);
1338 T.setOS(llvm::Triple::Vulkan);
1341 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1342 const llvm::StringSet<> ValidValues = {
"vulkan1.2",
"vulkan1.3"};
1343 if (ValidValues.contains(A->getValue())) {
1344 T.setOSName(A->getValue());
1346 Diag(diag::err_drv_invalid_value)
1347 << A->getAsString(Args) << A->getValue();
1352 TargetTriple =
T.str();
1355 Diag(diag::err_drv_dxc_missing_target_profile);
1359 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1360 TargetTriple = A->getValue();
1361 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1362 Dir =
Dir = A->getValue();
1363 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1367 if (std::optional<std::string> CompilerPathValue =
1368 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1369 StringRef CompilerPath = *CompilerPathValue;
1370 while (!CompilerPath.empty()) {
1371 std::pair<StringRef, StringRef> Split =
1372 CompilerPath.split(llvm::sys::EnvPathSeparator);
1373 PrefixDirs.push_back(std::string(Split.first));
1374 CompilerPath = Split.second;
1377 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1379 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1382 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1385 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1386 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1387 .Case(
"cwd", SaveTempsCwd)
1388 .Case(
"obj", SaveTempsObj)
1389 .Default(SaveTempsCwd);
1392 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1393 options::OPT_offload_device_only,
1394 options::OPT_offload_host_device)) {
1395 if (A->getOption().matches(options::OPT_offload_host_only))
1396 Offload = OffloadHost;
1397 else if (A->getOption().matches(options::OPT_offload_device_only))
1398 Offload = OffloadDevice;
1400 Offload = OffloadHostDevice;
1406 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1407 StringRef
Name = A->getValue();
1408 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1409 .Case(
"off", EmbedNone)
1410 .Case(
"all", EmbedBitcode)
1411 .Case(
"bitcode", EmbedBitcode)
1412 .Case(
"marker", EmbedMarker)
1415 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1418 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1422 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1423 llvm::sys::fs::remove(A->getValue());
1429 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1431 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1432 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1433 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1434 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1435 Std->containsValue(
"c++latest"));
1438 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1439 options::OPT_fmodule_header)) {
1441 ModulesModeCXX20 =
true;
1442 if (A->getOption().matches(options::OPT_fmodule_header))
1445 StringRef ArgName = A->getValue();
1446 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1451 Diags.
Report(diag::err_drv_invalid_value)
1452 << A->getAsString(Args) << ArgName;
1458 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1459 std::make_unique<InputArgList>(std::move(Args));
1462 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1470 if (!Triple.isWasm()) {
1471 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1472 StringRef TripleObjectFormat =
1473 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1474 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1475 TripleVersionName != TripleObjectFormat) {
1476 Diags.
Report(diag::err_drv_triple_version_invalid)
1478 ContainsError =
true;
1483 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1484 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1485 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1493 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1494 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1496 case llvm::Triple::arm:
1497 case llvm::Triple::armeb:
1498 case llvm::Triple::thumb:
1499 case llvm::Triple::thumbeb:
1500 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1501 Diag(diag::warn_target_unrecognized_env)
1503 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1506 case llvm::Triple::aarch64:
1507 case llvm::Triple::aarch64_be:
1508 case llvm::Triple::aarch64_32:
1509 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1510 Diag(diag::warn_target_unrecognized_env)
1512 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1529 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1536 if (TC.
getTriple().isOSBinFormatMachO())
1541 if (CCCPrintPhases) {
1552 llvm::opt::ArgStringList ASL;
1553 for (
const auto *A : Args) {
1557 while (A->getAlias())
1559 A->render(Args, ASL);
1562 for (
auto I = ASL.begin(),
E = ASL.end(); I !=
E; ++I) {
1563 if (I != ASL.begin())
1565 llvm::sys::printArg(OS, *I,
true);
1570bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1572 using namespace llvm::sys;
1573 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1574 "Only knows about .crash files on Darwin");
1579 path::home_directory(CrashDiagDir);
1580 if (CrashDiagDir.starts_with(
"/var/root"))
1582 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1590 fs::file_status FileStatus;
1591 TimePoint<> LastAccessTime;
1595 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1596 File != FileEnd && !EC;
File.increment(EC)) {
1600 if (fs::status(
File->path(), FileStatus))
1602 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1603 llvm::MemoryBuffer::getFile(
File->path());
1608 StringRef
Data = CrashFile.get()->getBuffer();
1609 if (!
Data.starts_with(
"Process:"))
1612 size_t ParentProcPos =
Data.find(
"Parent Process:");
1613 if (ParentProcPos == StringRef::npos)
1615 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1616 if (LineEnd == StringRef::npos)
1618 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1619 int OpenBracket = -1, CloseBracket = -1;
1620 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1621 if (ParentProcess[i] ==
'[')
1623 if (ParentProcess[i] ==
']')
1629 if (OpenBracket < 0 || CloseBracket < 0 ||
1630 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1631 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1641 const auto FileAccessTime = FileStatus.getLastModificationTime();
1642 if (FileAccessTime > LastAccessTime) {
1643 CrashFilePath.assign(
File->path());
1644 LastAccessTime = FileAccessTime;
1649 if (!CrashFilePath.empty()) {
1650 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1660 "\n********************\n\n"
1661 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1662 "Preprocessed source(s) and associated run script(s) are located at:";
1670 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1674 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1675 Level = llvm::StringSwitch<unsigned>(A->getValue())
1677 .Case(
"compiler", 1)
1689 ArgStringList SavedTemps;
1691 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1692 if (!IsLLD || Level < 2)
1699 SavedTemps = std::move(
C.getTempFiles());
1700 assert(!
C.getTempFiles().size());
1717 C.initCompilationForDiagnostics();
1723 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1724 StringRef ReproduceOption =
1725 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1728 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1732 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1734 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1735 Diag(clang::diag::note_drv_command_failed_diag_msg)
1736 <<
"\n\n********************";
1746 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1747 bool IgnoreInput =
false;
1753 }
else if (!strcmp(it->second->getValue(),
"-")) {
1754 Diag(clang::diag::note_drv_command_failed_diag_msg)
1755 <<
"Error generating preprocessed source(s) - "
1756 "ignoring input from stdin.";
1761 it = Inputs.erase(it);
1768 if (Inputs.empty()) {
1769 Diag(clang::diag::note_drv_command_failed_diag_msg)
1770 <<
"Error generating preprocessed source(s) - "
1771 "no preprocessable inputs.";
1777 llvm::StringSet<> ArchNames;
1778 for (
const Arg *A :
C.getArgs()) {
1779 if (A->getOption().matches(options::OPT_arch)) {
1780 StringRef ArchName = A->getValue();
1781 ArchNames.insert(ArchName);
1784 if (ArchNames.size() > 1) {
1785 Diag(clang::diag::note_drv_command_failed_diag_msg)
1786 <<
"Error generating preprocessed source(s) - cannot generate "
1787 "preprocessed source with multiple -arch options.";
1793 const ToolChain &TC =
C.getDefaultToolChain();
1794 if (TC.
getTriple().isOSBinFormatMachO())
1803 Diag(clang::diag::note_drv_command_failed_diag_msg)
1804 <<
"Error generating preprocessed source(s).";
1810 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1813 if (!FailingCommands.empty()) {
1814 Diag(clang::diag::note_drv_command_failed_diag_msg)
1815 <<
"Error generating preprocessed source(s).";
1819 const ArgStringList &TempFiles =
C.getTempFiles();
1820 if (TempFiles.empty()) {
1821 Diag(clang::diag::note_drv_command_failed_diag_msg)
1822 <<
"Error generating preprocessed source(s).";
1830 for (
const char *TempFile : TempFiles) {
1831 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
1834 if (ReproCrashFilename.empty()) {
1835 ReproCrashFilename = TempFile;
1836 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
1838 if (StringRef(TempFile).ends_with(
".cache")) {
1841 VFS = llvm::sys::path::filename(TempFile);
1842 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
1846 for (
const char *TempFile : SavedTemps)
1847 C.addTempFile(TempFile);
1853 llvm::sys::path::replace_extension(Script,
"sh");
1855 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
1856 llvm::sys::fs::FA_Write,
1857 llvm::sys::fs::OF_Text);
1859 Diag(clang::diag::note_drv_command_failed_diag_msg)
1860 <<
"Error generating run script: " << Script <<
" " << EC.message();
1863 <<
"# Driver args: ";
1865 ScriptOS <<
"# Original command: ";
1866 Cmd.Print(ScriptOS,
"\n",
true);
1867 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
1868 if (!AdditionalInformation.empty())
1869 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
1873 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
1877 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
1879 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
1880 Diag(clang::diag::note_drv_command_failed_diag_msg)
1881 << ReproCrashFilename.str();
1883 llvm::sys::path::append(CrashDiagDir,
Name);
1884 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
1885 Diag(clang::diag::note_drv_command_failed_diag_msg)
1886 <<
"Crash backtrace is located in";
1887 Diag(clang::diag::note_drv_command_failed_diag_msg)
1888 << CrashDiagDir.str();
1889 Diag(clang::diag::note_drv_command_failed_diag_msg)
1890 <<
"(choose the .crash file that corresponds to your crash)";
1894 Diag(clang::diag::note_drv_command_failed_diag_msg)
1895 <<
"\n\n********************";
1903 if (
Cmd.getResponseFileSupport().ResponseKind ==
1905 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
1906 Cmd.getArguments()))
1910 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
1916 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
1917 if (
C.getArgs().hasArg(options::OPT_v))
1918 C.getJobs().Print(llvm::errs(),
"\n",
true);
1920 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
1930 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
1931 C.getJobs().Print(llvm::errs(),
"\n",
true);
1940 for (
auto &Job :
C.getJobs())
1941 setUpResponseFiles(
C, Job);
1943 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1946 if (FailingCommands.empty())
1952 for (
const auto &CmdPair : FailingCommands) {
1953 int CommandRes = CmdPair.first;
1954 const Command *FailingCommand = CmdPair.second;
1959 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
1963 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
1968 if (CommandRes == EX_IOERR) {
1985 Diag(clang::diag::err_drv_command_signalled)
1988 Diag(clang::diag::err_drv_command_failed)
1996 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
1998 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2012 const ToolChain &TC =
C.getDefaultToolChain();
2016 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2019 OS <<
"Thread model: " << A->getValue();
2025 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2030 if (!llvm::cl::getCompilerBuildConfig().empty())
2031 llvm::cl::printBuildConfig(OS);
2034 for (
auto ConfigFile : ConfigFiles)
2035 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2048 if (PassedFlags ==
"")
2052 std::vector<std::string> SuggestedCompletions;
2053 std::vector<std::string> Flags;
2065 const bool HasSpace = PassedFlags.ends_with(
",");
2069 StringRef TargetFlags = PassedFlags;
2070 while (TargetFlags !=
"") {
2072 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2073 Flags.push_back(std::string(CurFlag));
2078 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2081 const llvm::opt::OptTable &Opts =
getOpts();
2083 Cur = Flags.at(Flags.size() - 1);
2085 if (Flags.size() >= 2) {
2086 Prev = Flags.at(Flags.size() - 2);
2087 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2090 if (SuggestedCompletions.empty())
2091 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2098 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2099 llvm::outs() <<
'\n';
2105 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2109 SuggestedCompletions = Opts.findByPrefix(
2110 Cur, VisibilityMask,
2117 if (S.starts_with(Cur))
2118 SuggestedCompletions.push_back(std::string(S));
2125 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2126 if (
int X = A.compare_insensitive(B))
2128 return A.compare(B) > 0;
2131 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2138 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2139 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2143 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2146 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2150 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2155 if (
C.getArgs().hasArg(options::OPT_help) ||
2156 C.getArgs().hasArg(options::OPT__help_hidden)) {
2157 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2161 if (
C.getArgs().hasArg(options::OPT__version)) {
2167 if (
C.getArgs().hasArg(options::OPT_v) ||
2168 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2169 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2170 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2171 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2173 SuppressMissingInputWarning =
true;
2176 if (
C.getArgs().hasArg(options::OPT_v)) {
2178 llvm::errs() <<
"System configuration file directory: "
2181 llvm::errs() <<
"User configuration file directory: "
2185 const ToolChain &TC =
C.getDefaultToolChain();
2187 if (
C.getArgs().hasArg(options::OPT_v))
2190 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2195 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2196 llvm::outs() <<
"programs: =";
2197 bool separator =
false;
2201 llvm::outs() << llvm::sys::EnvPathSeparator;
2202 llvm::outs() <<
Path;
2207 llvm::outs() << llvm::sys::EnvPathSeparator;
2208 llvm::outs() <<
Path;
2211 llvm::outs() <<
"\n";
2214 StringRef sysroot =
C.getSysRoot();
2218 llvm::outs() << llvm::sys::EnvPathSeparator;
2221 llvm::outs() << sysroot <<
Path.substr(1);
2223 llvm::outs() <<
Path;
2225 llvm::outs() <<
"\n";
2229 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2235 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2236 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2237 llvm::outs() << *RuntimePath <<
'\n';
2243 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2245 for (std::size_t I = 0; I != Flags.size(); I += 2)
2246 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2252 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2253 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2257 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2258 StringRef ProgName = A->getValue();
2261 if (! ProgName.empty())
2264 llvm::outs() <<
"\n";
2268 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2269 StringRef PassedFlags = A->getValue();
2274 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2288 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2291 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2297 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2303 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2306 std::set<llvm::StringRef> SortedFlags;
2307 for (
const auto &FlagEntry : ExpandedFlags)
2308 SortedFlags.insert(FlagEntry.getKey());
2309 for (
auto Flag : SortedFlags)
2310 llvm::outs() << Flag <<
'\n';
2314 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2317 llvm::outs() <<
".\n";
2320 assert(Suffix.front() ==
'/');
2321 llvm::outs() << Suffix.substr(1) <<
"\n";
2327 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2332 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2334 llvm::outs() << Triple.getTriple() <<
"\n";
2338 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2339 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2356 std::map<Action *, unsigned> &Ids,
2362 llvm::raw_string_ostream os(str);
2364 auto getSibIndent = [](
int K) -> Twine {
2368 Twine SibIndent = Indent + getSibIndent(Kind);
2372 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2374 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2375 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2376 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2377 bool IsFirst =
true;
2378 OA->doOnEachDependence(
2380 assert(TC &&
"Unknown host toolchain");
2392 os <<
":" << BoundArch;
2395 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2403 const char *Prefix =
"{";
2404 for (
Action *PreRequisite : *AL) {
2405 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2416 std::string offload_str;
2417 llvm::raw_string_ostream offload_os(offload_str);
2418 if (!isa<OffloadAction>(A)) {
2421 offload_os <<
", (" << S;
2428 auto getSelfIndent = [](
int K) -> Twine {
2432 unsigned Id = Ids.size();
2434 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2443 std::map<Action *, unsigned> Ids;
2444 for (
Action *A :
C.getActions())
2451 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2452 isa<AssembleJobAction>(A))
2460 DerivedArgList &Args =
C.getArgs();
2462 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2465 llvm::StringSet<> ArchNames;
2467 for (Arg *A : Args) {
2468 if (A->getOption().matches(options::OPT_arch)) {
2471 llvm::Triple::ArchType Arch =
2473 if (Arch == llvm::Triple::UnknownArch) {
2474 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2479 if (ArchNames.insert(A->getValue()).second)
2480 Archs.push_back(A->getValue());
2494 for (
Action* Act : SingleActions) {
2502 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2506 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2511 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2512 Actions.append(Inputs.begin(), Inputs.end());
2514 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2517 Arg *A = Args.getLastArg(options::OPT_g_Group);
2518 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2519 !A->getOption().matches(options::OPT_gstabs);
2527 if (Act->getType() == types::TY_Image) {
2529 Inputs.push_back(Actions.back());
2536 if (Args.hasArg(options::OPT_verify_debug_info)) {
2537 Action* LastAction = Actions.back();
2540 LastAction, types::TY_Nothing));
2559 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2560 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2572 std::string Nearest;
2573 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2574 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2575 <<
Value << Nearest;
2614 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2617 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2625 return types::TY_CXXUHeader;
2627 return types::TY_CXXSHeader;
2631 llvm_unreachable(
"should not be called in this case");
2633 return types::TY_CXXHUHeader;
2639 const llvm::opt::OptTable &Opts =
getOpts();
2643 types::ID InputType = types::TY_Nothing;
2644 Arg *InputTypeArg =
nullptr;
2647 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2648 options::OPT__SLASH_TP)) {
2649 InputTypeArg = TCTP;
2650 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2655 bool ShowNote =
false;
2657 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2659 Diag(clang::diag::warn_drv_overriding_option)
2660 <<
Previous->getSpelling() << A->getSpelling();
2666 Diag(clang::diag::note_drv_t_option_is_global);
2671 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2672 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2673 if (LastXArg && LastInputArg &&
2674 LastInputArg->getIndex() < LastXArg->getIndex())
2675 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2678 for (Arg *A : Args) {
2679 if (A->getOption().
getKind() == Option::InputClass) {
2680 const char *
Value = A->getValue();
2684 if (InputType == types::TY_Nothing) {
2687 InputTypeArg->claim();
2690 if (memcmp(
Value,
"-", 2) == 0) {
2692 Ty = types::TY_Fortran;
2694 Ty = types::TY_HLSL;
2703 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2704 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2705 : clang::diag::err_drv_unknown_stdin_type);
2714 if (
const char *Ext = strrchr(
Value,
'.'))
2723 Ty = types::TY_Object;
2734 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2735 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2736 << getTypeName(OldTy) << getTypeName(Ty);
2741 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2742 Ty == types::TY_Object)
2743 Ty = types::TY_LLVM_BC;
2751 if (Ty != types::TY_Object) {
2752 if (Args.hasArg(options::OPT_ObjC))
2753 Ty = types::TY_ObjC;
2754 else if (Args.hasArg(options::OPT_ObjCXX))
2755 Ty = types::TY_ObjCXX;
2762 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
2766 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2767 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2770 const char *Ext = strrchr(
Value,
'.');
2772 Ty = types::TY_Object;
2776 InputTypeArg->claim();
2780 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
2781 Args.hasArgNoClaim(options::OPT_hipstdpar))
2785 Inputs.push_back(std::make_pair(Ty, A));
2787 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2788 StringRef
Value = A->getValue();
2791 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2792 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2795 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2796 StringRef
Value = A->getValue();
2799 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2800 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2806 Inputs.push_back(std::make_pair(types::TY_Object, A));
2808 }
else if (A->getOption().matches(options::OPT_x)) {
2817 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2818 InputType = types::TY_Object;
2825 }
else if (A->getOption().getID() == options::OPT_U) {
2826 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
2827 StringRef Val = A->getValue(0);
2828 if (Val.find_first_of(
"/\\") != StringRef::npos) {
2830 Diag(diag::warn_slash_u_filename) << Val;
2831 Diag(diag::note_use_dashdash);
2835 if (
CCCIsCPP() && Inputs.empty()) {
2839 Inputs.push_back(std::make_pair(types::TY_C, A));
2846class OffloadingActionBuilder final {
2848 bool IsValid =
false;
2854 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
2857 std::map<Action *, const Arg *> HostActionToInputArgMap;
2860 class DeviceActionBuilder {
2864 enum ActionBuilderReturnCode {
2883 DerivedArgList &Args;
2892 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
2895 :
C(
C), Args(Args), Inputs(Inputs),
2896 AssociatedOffloadKind(AssociatedOffloadKind) {}
2897 virtual ~DeviceActionBuilder() {}
2902 virtual ActionBuilderReturnCode
2906 return ABRT_Inactive;
2911 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
2912 return ABRT_Inactive;
2916 virtual void appendTopLevelActions(
ActionList &AL) {}
2919 virtual void appendLinkDeviceActions(
ActionList &AL) {}
2932 virtual bool canUseBundlerUnbundler()
const {
return false; }
2936 bool isValid() {
return !ToolChains.empty(); }
2940 return AssociatedOffloadKind;
2946 class CudaActionBuilderBase :
public DeviceActionBuilder {
2950 bool CompileHostOnly =
false;
2951 bool CompileDeviceOnly =
false;
2953 bool EmitAsm =
false;
2963 TargetID(
const char *
ID) :
ID(
ID) {}
2964 operator const char *() {
return ID; }
2965 operator StringRef() {
return StringRef(
ID); }
2974 Action *CudaFatBinary =
nullptr;
2977 bool IsActive =
false;
2980 bool Relocatable =
false;
2983 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
2987 enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
2988 UseCUIDKind UseCUID = CUID_Hash;
2991 StringRef FixedCUID;
2994 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
2997 : DeviceActionBuilder(
C, Args, Inputs, OFKind) {
2999 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3000 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3001 options::OPT_fno_gpu_rdc,
false);
3004 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3011 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3012 assert(!GpuArchList.empty() &&
3013 "We should have at least one GPU architecture.");
3017 if (!(IA->getType() == types::TY_CUDA ||
3018 IA->getType() == types::TY_HIP ||
3019 IA->getType() == types::TY_PP_HIP)) {
3022 return ABRT_Inactive;
3028 if (CompileHostOnly)
3029 return ABRT_Success;
3032 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3033 : types::TY_CUDA_DEVICE;
3034 std::string CUID = FixedCUID.str();
3036 if (UseCUID == CUID_Random)
3037 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
3039 else if (UseCUID == CUID_Hash) {
3041 llvm::MD5::MD5Result Hash;
3043 llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
3045 Hasher.update(RealPath);
3046 for (
auto *A : Args) {
3047 if (A->getOption().matches(options::OPT_INPUT))
3049 Hasher.update(A->getAsString(Args));
3052 CUID = llvm::utohexstr(Hash.low(),
true);
3057 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3058 CudaDeviceActions.push_back(
3059 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3062 return ABRT_Success;
3066 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3070 if (UA->getType() == types::TY_Object && !Relocatable)
3071 return ABRT_Inactive;
3073 CudaDeviceActions.clear();
3074 auto *IA = cast<InputAction>(UA->getInputs().back());
3075 std::string
FileName = IA->getInputArg().getAsString(Args);
3081 const StringRef LibFileExt =
".lib";
3082 if (IA->getType() == types::TY_Object &&
3083 (!llvm::sys::path::has_extension(
FileName) ||
3085 llvm::sys::path::extension(
FileName).drop_front()) !=
3087 llvm::sys::path::extension(
FileName) == LibFileExt))
3088 return ABRT_Inactive;
3090 for (
auto Arch : GpuArchList) {
3091 CudaDeviceActions.push_back(UA);
3092 UA->registerDependentActionInfo(ToolChains[0], Arch,
3093 AssociatedOffloadKind);
3096 return ABRT_Success;
3099 return IsActive ? ABRT_Success : ABRT_Inactive;
3102 void appendTopLevelActions(
ActionList &AL)
override {
3104 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3106 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3111 if (CudaFatBinary) {
3112 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3113 CudaDeviceActions.clear();
3114 CudaFatBinary =
nullptr;
3118 if (CudaDeviceActions.empty())
3124 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3125 "Expecting one action per GPU architecture.");
3126 assert(ToolChains.size() == 1 &&
3127 "Expecting to have a single CUDA toolchain.");
3128 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I)
3129 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3131 CudaDeviceActions.clear();
3136 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3138 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3156 assert(HostTC &&
"No toolchain for host compilation.");
3158 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3162 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3167 ToolChains.push_back(
3172 CompileHostOnly =
C.getDriver().offloadHostOnly();
3173 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3174 EmitAsm = Args.getLastArg(options::OPT_S);
3175 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3176 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3177 StringRef UseCUIDStr = A->getValue();
3178 UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3179 .Case(
"hash", CUID_Hash)
3180 .Case(
"random", CUID_Random)
3181 .Case(
"none", CUID_None)
3182 .Default(CUID_Invalid);
3183 if (UseCUID == CUID_Invalid) {
3184 C.getDriver().Diag(diag::err_drv_invalid_value)
3185 << A->getAsString(Args) << UseCUIDStr;
3186 C.setContainsError();
3192 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3193 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3194 options::OPT_no_offload_arch_EQ)) {
3195 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3200 std::set<StringRef> GpuArchs;
3202 for (Arg *A : Args) {
3203 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3204 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3208 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3209 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3212 }
else if (ArchStr ==
"native") {
3213 const ToolChain &TC = *ToolChains.front();
3214 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3217 << llvm::Triple::getArchTypeName(TC.
getArch())
3218 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3222 for (
auto GPU : *GPUsOrErr) {
3223 GpuArchs.insert(Args.MakeArgString(GPU));
3226 ArchStr = getCanonicalOffloadArch(ArchStr);
3227 if (ArchStr.empty()) {
3229 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3230 GpuArchs.insert(ArchStr);
3231 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3232 GpuArchs.erase(ArchStr);
3234 llvm_unreachable(
"Unexpected option.");
3240 if (ConflictingArchs) {
3241 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3242 << ConflictingArchs->first << ConflictingArchs->second;
3243 C.setContainsError();
3248 for (
auto Arch : GpuArchs)
3249 GpuArchList.push_back(Arch.data());
3254 if (GpuArchList.empty()) {
3255 if (ToolChains.front()->getTriple().isSPIRV()) {
3256 if (ToolChains.front()->getTriple().getVendor() == llvm::Triple::AMD)
3257 GpuArchList.push_back(OffloadArch::AMDGCNSPIRV);
3259 GpuArchList.push_back(OffloadArch::Generic);
3261 GpuArchList.push_back(DefaultOffloadArch);
3271 class CudaActionBuilder final :
public CudaActionBuilderBase {
3273 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3275 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3276 DefaultOffloadArch = OffloadArch::CudaDefault;
3279 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3282 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3288 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3290 const std::set<StringRef> &GpuArchs)
override {
3291 return std::nullopt;
3294 ActionBuilderReturnCode
3297 PhasesTy &Phases)
override {
3299 return ABRT_Inactive;
3303 if (CudaDeviceActions.empty())
3304 return ABRT_Success;
3306 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3307 "Expecting one action per GPU architecture.");
3308 assert(!CompileHostOnly &&
3309 "Not expecting CUDA actions in host-only compilation.");
3319 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3322 for (
auto Ph : Phases) {
3327 if (Ph > FinalPhase)
3330 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3340 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3344 Action *AssembleAction = CudaDeviceActions[I];
3345 assert(AssembleAction->
getType() == types::TY_Object);
3346 assert(AssembleAction->
getInputs().size() == 1);
3354 DeviceActions.push_back(
3360 if (!DeviceActions.empty()) {
3362 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3364 if (!CompileDeviceOnly) {
3365 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3369 CudaFatBinary =
nullptr;
3374 CudaDeviceActions.clear();
3378 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3383 return ABRT_Success;
3387 "instructions should only occur "
3388 "before the backend phase!");
3391 for (
Action *&A : CudaDeviceActions)
3392 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3394 return ABRT_Success;
3399 class HIPActionBuilder final :
public CudaActionBuilderBase {
3407 std::optional<bool> BundleOutput;
3408 std::optional<bool> EmitReloc;
3413 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3415 DefaultOffloadArch = OffloadArch::HIPDefault;
3417 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3418 options::OPT_fno_hip_emit_relocatable)) {
3419 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3420 options::OPT_fno_hip_emit_relocatable,
false);
3424 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3425 <<
"-fhip-emit-relocatable"
3429 if (!CompileDeviceOnly) {
3430 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3431 <<
"-fhip-emit-relocatable"
3432 <<
"--cuda-device-only";
3437 if (Args.hasArg(options::OPT_gpu_bundle_output,
3438 options::OPT_no_gpu_bundle_output))
3439 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3440 options::OPT_no_gpu_bundle_output,
true) &&
3441 (!EmitReloc || !*EmitReloc);
3444 bool canUseBundlerUnbundler()
const override {
return true; }
3446 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3447 llvm::StringMap<bool> Features;
3454 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3455 C.setContainsError();
3459 return Args.MakeArgStringRef(CanId);
3462 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3464 const std::set<StringRef> &GpuArchs)
override {
3468 ActionBuilderReturnCode
3471 PhasesTy &Phases)
override {
3473 return ABRT_Inactive;
3479 if (CudaDeviceActions.empty())
3480 return ABRT_Success;
3483 CudaDeviceActions.size() == GpuArchList.size()) &&
3484 "Expecting one action per GPU architecture.");
3485 assert(!CompileHostOnly &&
3486 "Not expecting HIP actions in host-only compilation.");
3488 bool ShouldLink = !EmitReloc || !*EmitReloc;
3491 !EmitAsm && ShouldLink) {
3497 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3498 if (
C.getDriver().isUsingOffloadLTO()) {
3502 AL.push_back(CudaDeviceActions[I]);
3505 CudaDeviceActions[I] =
3512 if (ToolChains.front()->getTriple().isSPIRV()) {
3515 types::ID Output = Args.hasArg(options::OPT_S)
3517 : types::TY_LLVM_BC;
3523 AssociatedOffloadKind);
3524 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3526 AssociatedOffloadKind);
3527 AL.push_back(AssembleAction);
3530 CudaDeviceActions[I] =
3541 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3542 AssociatedOffloadKind);
3544 DDep, CudaDeviceActions[I]->getType());
3547 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3550 types::TY_HIP_FATBIN);
3552 if (!CompileDeviceOnly) {
3553 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3554 AssociatedOffloadKind);
3557 CudaFatBinary =
nullptr;
3562 CudaDeviceActions.clear();
3565 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3568 return ABRT_Success;
3574 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3575 auto LI = DeviceLinkerInputs.begin();
3576 for (
auto *A : CudaDeviceActions) {
3583 CudaDeviceActions.clear();
3584 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3588 for (
Action *&A : CudaDeviceActions)
3589 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3590 AssociatedOffloadKind);
3592 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3594 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3596 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3597 AssociatedOffloadKind);
3599 DDep, CudaDeviceActions[I]->getType());
3603 CudaDeviceActions.clear();
3606 return (CompileDeviceOnly &&
3607 (CurPhase == FinalPhase ||
3613 void appendLinkDeviceActions(
ActionList &AL)
override {
3614 if (DeviceLinkerInputs.size() == 0)
3617 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3618 "Linker inputs and GPU arch list sizes do not match.");
3624 for (
auto &LI : DeviceLinkerInputs) {
3626 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3630 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3634 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3635 GpuArchList[I], AssociatedOffloadKind);
3637 DeviceLinkDeps, DeviceLinkAction->getType()));
3640 DeviceLinkerInputs.clear();
3643 if (Args.hasArg(options::OPT_emit_llvm)) {
3652 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3655 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3656 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3657 AssociatedOffloadKind);
3660 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3666 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3682 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3690 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3693 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3701 unsigned ValidBuilders = 0u;
3702 unsigned ValidBuildersSupportingBundling = 0u;
3703 for (
auto *SB : SpecializedBuilders) {
3704 IsValid = IsValid && !SB->initialize();
3707 if (SB->isValid()) {
3709 if (SB->canUseBundlerUnbundler())
3710 ++ValidBuildersSupportingBundling;
3714 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3717 ~OffloadingActionBuilder() {
3718 for (
auto *SB : SpecializedBuilders)
3723 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3724 assert(HostAction &&
"Invalid host action");
3725 assert(InputArg &&
"Invalid input argument");
3726 auto Loc = HostActionToInputArgMap.find(HostAction);
3727 if (
Loc == HostActionToInputArgMap.end())
3728 HostActionToInputArgMap[HostAction] = InputArg;
3729 assert(HostActionToInputArgMap[HostAction] == InputArg &&
3730 "host action mapped to multiple input arguments");
3738 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3740 DeviceActionBuilder::PhasesTy &Phases) {
3744 if (SpecializedBuilders.empty())
3747 assert(HostAction &&
"Invalid host action!");
3748 recordHostAction(HostAction, InputArg);
3753 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3754 unsigned InactiveBuilders = 0u;
3755 unsigned IgnoringBuilders = 0u;
3756 for (
auto *SB : SpecializedBuilders) {
3757 if (!SB->isValid()) {
3762 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3767 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3772 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3773 OffloadKind |= SB->getAssociatedOffloadKind();
3778 if (IgnoringBuilders &&
3779 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3796 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3797 const Arg *InputArg) {
3801 recordHostAction(HostAction, InputArg);
3809 if (CanUseBundler && isa<InputAction>(HostAction) &&
3810 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3812 HostAction->
getType() == types::TY_PP_HIP)) {
3813 auto UnbundlingHostAction =
3818 HostAction = UnbundlingHostAction;
3819 recordHostAction(HostAction, InputArg);
3822 assert(HostAction &&
"Invalid host action!");
3825 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3826 for (
auto *SB : SpecializedBuilders) {
3830 auto RetCode = SB->addDeviceDependences(HostAction);
3834 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3835 "Host dependence not expected to be ignored.!");
3839 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3840 OffloadKind |= SB->getAssociatedOffloadKind();
3845 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
3855 const Arg *InputArg) {
3857 recordHostAction(HostAction, InputArg);
3861 for (
auto *SB : SpecializedBuilders) {
3864 SB->appendTopLevelActions(OffloadAL);
3871 if (CanUseBundler && HostAction &&
3872 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
3874 OffloadAL.push_back(HostAction);
3878 assert(HostAction == AL.back() &&
"Host action not in the list??");
3880 recordHostAction(HostAction, InputArg);
3881 AL.back() = HostAction;
3883 AL.append(OffloadAL.begin(), OffloadAL.end());
3893 void appendDeviceLinkActions(
ActionList &AL) {
3894 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3897 SB->appendLinkDeviceActions(AL);
3901 Action *makeHostLinkAction() {
3904 appendDeviceLinkActions(DeviceAL);
3905 if (DeviceAL.empty())
3910 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3913 HA = SB->appendLinkHostActions(DeviceAL);
3930 for (
auto *SB : SpecializedBuilders) {
3934 SB->appendLinkDependences(DDeps);
3938 unsigned ActiveOffloadKinds = 0u;
3939 for (
auto &I : InputArgToOffloadKindMap)
3940 ActiveOffloadKinds |= I.second;
3952 for (
auto *A : HostAction->
inputs()) {
3953 auto ArgLoc = HostActionToInputArgMap.find(A);
3954 if (ArgLoc == HostActionToInputArgMap.end())
3956 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
3957 if (OFKLoc == InputArgToOffloadKindMap.end())
3969 nullptr, ActiveOffloadKinds);
3975void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
3976 const InputList &Inputs,
3980 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3981 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3982 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3983 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3984 Args.eraseArg(options::OPT__SLASH_Yc);
3985 Args.eraseArg(options::OPT__SLASH_Yu);
3986 YcArg = YuArg =
nullptr;
3988 if (YcArg && Inputs.size() > 1) {
3989 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3990 Args.eraseArg(options::OPT__SLASH_Yc);
3998 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
3999 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4000 Args.AddFlagArg(
nullptr,
4001 getOpts().getOption(options::OPT_frtlib_add_rpath));
4004 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4005 Diag(clang::diag::err_drv_emit_llvm_link);
4007 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4008 .equals_insensitive(
"lld"))
4009 Diag(clang::diag::err_drv_lto_without_lld);
4015 if (!Args.hasArg(options::OPT_dumpdir)) {
4016 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4017 Arg *Arg = Args.MakeSeparateArg(
4018 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4020 (FinalOutput ? FinalOutput->getValue()
4032 Args.eraseArg(options::OPT__SLASH_Fp);
4033 Args.eraseArg(options::OPT__SLASH_Yc);
4034 Args.eraseArg(options::OPT__SLASH_Yu);
4035 YcArg = YuArg =
nullptr;
4038 unsigned LastPLSize = 0;
4039 for (
auto &I : Inputs) {
4041 const Arg *InputArg = I.second;
4044 LastPLSize = PL.size();
4049 if (InitialPhase > FinalPhase) {
4050 if (InputArg->isClaimed())
4057 if (Args.hasArg(options::OPT_Qunused_arguments))
4063 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4064 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4068 (Args.getLastArg(options::OPT__SLASH_EP,
4069 options::OPT__SLASH_P) ||
4070 Args.getLastArg(options::OPT_E) ||
4071 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4073 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4074 << InputArg->getAsString(Args) << !!FinalPhaseArg
4075 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4077 Diag(clang::diag::warn_drv_input_file_unused)
4078 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4080 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4093 Actions.push_back(ClangClPch);
4107 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4108 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4114 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4116 if (!SuppressMissingInputWarning && Inputs.empty()) {
4117 Diag(clang::diag::err_drv_no_input_files);
4122 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4123 StringRef
V = A->getValue();
4124 if (Inputs.size() > 1 && !
V.empty() &&
4125 !llvm::sys::path::is_separator(
V.back())) {
4127 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4128 << A->getSpelling() <<
V;
4129 Args.eraseArg(options::OPT__SLASH_Fo);
4134 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4135 StringRef
V = A->getValue();
4136 if (Inputs.size() > 1 && !
V.empty() &&
4137 !llvm::sys::path::is_separator(
V.back())) {
4139 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4140 << A->getSpelling() <<
V;
4141 Args.eraseArg(options::OPT__SLASH_Fa);
4146 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4147 if (A->getValue()[0] ==
'\0') {
4149 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4150 Args.eraseArg(options::OPT__SLASH_o);
4154 handleArguments(
C, Args, Inputs, Actions);
4156 bool UseNewOffloadingDriver =
4158 Args.hasFlag(options::OPT_foffload_via_llvm,
4159 options::OPT_fno_offload_via_llvm,
false) ||
4160 Args.hasFlag(options::OPT_offload_new_driver,
4161 options::OPT_no_offload_new_driver,
false);
4164 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4165 !UseNewOffloadingDriver
4166 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4174 for (
auto &I : Inputs) {
4176 const Arg *InputArg = I.second;
4189 if (!UseNewOffloadingDriver)
4190 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4196 if (!UseNewOffloadingDriver)
4197 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4198 Current, InputArg, Phase, PL.back(), FullPL);
4204 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4207 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4208 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4210 LinkerInputs.push_back(Current);
4220 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4221 MergerInputs.push_back(Current);
4239 if (NewCurrent == Current)
4242 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4245 Current = NewCurrent;
4249 if (UseNewOffloadingDriver)
4253 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4257 if (Current->getType() == types::TY_Nothing)
4263 Actions.push_back(Current);
4266 if (!UseNewOffloadingDriver)
4267 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4269 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4275 if (LinkerInputs.empty()) {
4278 if (!UseNewOffloadingDriver)
4279 OffloadBuilder->appendDeviceLinkActions(Actions);
4282 if (!LinkerInputs.empty()) {
4283 if (!UseNewOffloadingDriver)
4284 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4285 LinkerInputs.push_back(Wrapper);
4290 }
else if (UseNewOffloadingDriver ||
4291 Args.hasArg(options::OPT_offload_link)) {
4298 if (!UseNewOffloadingDriver)
4299 LA = OffloadBuilder->processHostLinkAction(LA);
4300 Actions.push_back(LA);
4304 if (!MergerInputs.empty())
4308 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4315 for (
auto &I : Inputs) {
4317 const Arg *InputArg = I.second;
4322 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4323 InputType == types::TY_Asm)
4328 for (
auto Phase : PhaseList) {
4332 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4337 if (InputType == types::TY_Object)
4344 assert(Phase == PhaseList.back() &&
4345 "merging must be final compilation step.");
4346 MergerInputs.push_back(Current);
4355 Actions.push_back(Current);
4359 if (!MergerInputs.empty())
4364 for (
auto Opt : {options::OPT_print_supported_cpus,
4365 options::OPT_print_supported_extensions,
4366 options::OPT_print_enabled_extensions}) {
4373 if (Arg *A = Args.getLastArg(Opt)) {
4374 if (Opt == options::OPT_print_supported_extensions &&
4375 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4376 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4377 !
C.getDefaultToolChain().getTriple().isARM()) {
4378 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4379 <<
"--print-supported-extensions";
4382 if (Opt == options::OPT_print_enabled_extensions &&
4383 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4384 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4385 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4386 <<
"--print-enabled-extensions";
4395 for (
auto &I : Inputs)
4401 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4405 if (TC.requiresValidation(Args)) {
4406 Action *LastAction = Actions.back();
4408 LastAction, types::TY_DX_CONTAINER));
4413 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4419 const llvm::opt::DerivedArgList &Args,
4421 const llvm::Triple &Triple,
4422 bool SuppressError =
false) {
4427 if (!SuppressError && Triple.isNVPTX() &&
4429 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4430 <<
"CUDA" << ArchStr;
4432 }
else if (!SuppressError && Triple.isAMDGPU() &&
4434 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4435 <<
"HIP" << ArchStr;
4443 llvm::StringMap<bool> Features;
4449 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4450 C.setContainsError();
4462static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4464 llvm::Triple Triple) {
4465 if (!Triple.isAMDGPU())
4466 return std::nullopt;
4468 std::set<StringRef> ArchSet;
4469 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4473llvm::DenseSet<StringRef>
4476 bool SuppressError)
const {
4478 TC = &
C.getDefaultToolChain();
4481 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4482 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4483 options::OPT_no_offload_arch_EQ)) {
4484 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4486 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4488 :
"--no-offload-arch");
4491 if (KnownArchs.contains(TC))
4492 return KnownArchs.lookup(TC);
4494 llvm::DenseSet<StringRef> Archs;
4495 for (
auto *Arg : Args) {
4497 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4498 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4501 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4502 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4503 Arg = ExtractedArg.get();
4508 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4509 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4510 if (Arch ==
"native" || Arch.empty()) {
4514 llvm::consumeError(GPUsOrErr.takeError());
4517 << llvm::Triple::getArchTypeName(TC->
getArch())
4518 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4522 for (
auto ArchStr : *GPUsOrErr) {
4529 C, Args, Arch, TC->
getTriple(), SuppressError);
4530 if (ArchStr.empty())
4532 Archs.insert(ArchStr);
4535 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4536 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4537 if (Arch ==
"all") {
4541 C, Args, Arch, TC->
getTriple(), SuppressError);
4542 if (ArchStr.empty())
4544 Archs.erase(ArchStr);
4550 if (
auto ConflictingArchs =
4552 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4553 << ConflictingArchs->first << ConflictingArchs->second;
4554 C.setContainsError();
4561 if (Archs.empty()) {
4567 Archs.insert(StringRef());
4569 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4570 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4577 llvm::opt::DerivedArgList &Args,
4579 Action *HostAction)
const {
4584 !(isa<CompileJobAction>(HostAction) ||
4598 auto TCRange =
C.getOffloadToolChains(Kind);
4599 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4600 ToolChains.push_back(TI->second);
4602 if (ToolChains.empty())
4606 const Arg *InputArg = Input.second;
4615 for (
const ToolChain *TC : ToolChains) {
4619 for (StringRef Arch : Sorted)
4620 TCAndArchs.push_back(std::make_pair(TC, Arch));
4623 for (
unsigned I = 0,
E = TCAndArchs.size(); I !=
E; ++I)
4624 DeviceActions.push_back(
C.MakeAction<
InputAction>(*InputArg, InputType));
4626 if (DeviceActions.empty())
4633 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4637 auto TCAndArch = TCAndArchs.begin();
4638 for (
Action *&A : DeviceActions) {
4639 if (A->
getType() == types::TY_Nothing)
4647 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4649 HostAction->
getType() != types::TY_Nothing) {
4656 TCAndArch->second.data(), Kind);
4658 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4667 for (
Action *&A : DeviceActions) {
4668 if ((A->
getType() != types::TY_Object &&
4669 A->
getType() != types::TY_LTO_BC) ||
4671 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4677 auto TCAndArch = TCAndArchs.begin();
4678 for (
Action *A : DeviceActions) {
4679 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4681 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4686 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4688 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4696 bool ShouldBundleHIP =
4698 Args.hasFlag(options::OPT_gpu_bundle_output,
4699 options::OPT_no_gpu_bundle_output,
true) &&
4700 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4701 !llvm::any_of(OffloadActions,
4708 if (OffloadActions.empty())
4713 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4717 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4721 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4726 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4735 nullptr,
C.getActiveOffloadKinds());
4744 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4745 return A->
getType() == types::TY_Nothing;
4746 }) && isa<CompileJobAction>(HostAction);
4749 nullptr, SingleDeviceOutput ? DDep : DDeps);
4750 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4756 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4767 llvm_unreachable(
"link action invalid here.");
4769 llvm_unreachable(
"ifsmerge action invalid here.");
4774 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4775 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4776 OutputTy = types::TY_Dependencies;
4781 if (!Args.hasFlag(options::OPT_frewrite_includes,
4782 options::OPT_fno_rewrite_includes,
false) &&
4783 !Args.hasFlag(options::OPT_frewrite_imports,
4784 options::OPT_fno_rewrite_imports,
false) &&
4785 !Args.hasFlag(options::OPT_fdirectives_only,
4786 options::OPT_fno_directives_only,
false) &&
4790 "Cannot preprocess this input type!");
4796 if (Args.hasArg(options::OPT_extract_api))
4803 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
4804 !Args.getLastArg(options::OPT__precompile))
4809 "Cannot precompile this input type!");
4813 const char *ModName =
nullptr;
4814 if (OutputTy == types::TY_PCH) {
4815 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4816 ModName = A->getValue();
4818 OutputTy = types::TY_ModuleFile;
4821 if (Args.hasArg(options::OPT_fsyntax_only)) {
4823 OutputTy = types::TY_Nothing;
4829 if (Args.hasArg(options::OPT_fsyntax_only))
4831 if (Args.hasArg(options::OPT_rewrite_objc))
4833 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
4835 types::TY_RewrittenLegacyObjC);
4836 if (Args.hasArg(options::OPT__analyze))
4838 if (Args.hasArg(options::OPT__migrate))
4840 if (Args.hasArg(options::OPT_emit_ast))
4842 if (Args.hasArg(options::OPT_emit_cir))
4844 if (Args.hasArg(options::OPT_module_file_info))
4846 if (Args.hasArg(options::OPT_verify_pch))
4848 if (Args.hasArg(options::OPT_extract_api))
4855 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
4856 !Args.hasArg(options::OPT_emit_llvm))
4857 Output = types::TY_PP_Asm;
4858 else if (Args.hasArg(options::OPT_S))
4859 Output = types::TY_LTO_IR;
4861 Output = types::TY_LTO_BC;
4866 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
4869 if (Args.hasArg(options::OPT_emit_llvm) ||
4873 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4877 Args.hasArg(options::OPT_S) &&
4881 !Args.hasFlag(options::OPT_offload_new_driver,
4882 options::OPT_no_offload_new_driver,
false)))
4884 : types::TY_LLVM_BC;
4893 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4897 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4899 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
4919 unsigned NumOutputs = 0;
4920 unsigned NumIfsOutputs = 0;
4921 for (
const Action *A :
C.getActions()) {
4922 if (A->
getType() != types::TY_Nothing &&
4923 A->
getType() != types::TY_DX_CONTAINER &&
4925 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
4927 0 == NumIfsOutputs++) ||
4932 A->
getType() == types::TY_Nothing &&
4933 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
4934 NumOutputs += A->
size();
4937 if (NumOutputs > 1) {
4938 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
4939 FinalOutput =
nullptr;
4943 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
4946 llvm::StringSet<> ArchNames;
4947 if (RawTriple.isOSBinFormatMachO())
4948 for (
const Arg *A :
C.getArgs())
4949 if (A->getOption().matches(options::OPT_arch))
4950 ArchNames.insert(A->getValue());
4953 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
4954 for (
Action *A :
C.getActions()) {
4961 const char *LinkingOutput =
nullptr;
4962 if (isa<LipoJobAction>(A)) {
4964 LinkingOutput = FinalOutput->getValue();
4972 ArchNames.size() > 1,
4973 LinkingOutput, CachedResults,
4980 for (
auto &J :
C.getJobs())
4981 J.InProcess =
false;
4984 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
4985 std::optional<llvm::sys::ProcessStatistics> ProcStat =
4986 Cmd.getProcessStatistics();
4990 const char *LinkingOutput =
nullptr;
4992 LinkingOutput = FinalOutput->getValue();
4993 else if (!
Cmd.getOutputFilenames().empty())
4994 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
4999 using namespace llvm;
5001 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
5002 <<
"output=" << LinkingOutput;
5003 outs() <<
", total="
5004 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5006 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5007 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5011 llvm::raw_string_ostream Out(Buffer);
5012 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
5015 llvm::sys::printArg(Out, LinkingOutput, true);
5016 Out <<
',' << ProcStat->TotalTime.count() <<
','
5017 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5021 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5022 llvm::sys::fs::OF_Append |
5023 llvm::sys::fs::OF_Text);
5028 llvm::errs() <<
"ERROR: Cannot lock file "
5029 << CCPrintStatReportFilename <<
": "
5030 << toString(L.takeError()) <<
"\n";
5041 if (Diags.hasErrorOccurred() ||
5042 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5046 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5048 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5051 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5052 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5054 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5058 return strstr(J.getCreator().getShortName(),
"assembler");
5060 for (Arg *A :
C.getArgs()) {
5064 if (!A->isClaimed()) {
5070 const Option &Opt = A->getOption();
5071 if (Opt.getKind() == Option::FlagClass) {
5072 bool DuplicateClaimed =
false;
5074 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5075 if (AA->isClaimed()) {
5076 DuplicateClaimed =
true;
5081 if (DuplicateClaimed)
5087 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5089 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5094 !
C.getActions().empty()) {
5095 Diag(diag::err_drv_unsupported_opt_for_target)
5096 << A->getSpelling() << getTargetTriple();
5098 Diag(clang::diag::warn_drv_unused_argument)
5099 << A->getAsString(
C.getArgs());
5109class ToolSelector final {
5120 bool IsHostSelector;
5131 bool CanBeCollapsed =
true) {
5133 if (Inputs.size() != 1)
5136 Action *CurAction = *Inputs.begin();
5137 if (CanBeCollapsed &&
5143 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5147 if (!IsHostSelector) {
5148 if (OA->hasSingleDeviceDependence(
true)) {
5150 OA->getSingleDeviceDependence(
true);
5151 if (CanBeCollapsed &&
5154 SavedOffloadAction.push_back(OA);
5155 return dyn_cast<JobAction>(CurAction);
5157 }
else if (OA->hasHostDependence()) {
5158 CurAction = OA->getHostDependence();
5159 if (CanBeCollapsed &&
5162 SavedOffloadAction.push_back(OA);
5163 return dyn_cast<JobAction>(CurAction);
5168 return dyn_cast<JobAction>(CurAction);
5172 bool canCollapseAssembleAction()
const {
5173 return TC.useIntegratedAs() && !SaveTemps &&
5174 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5175 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5176 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5177 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5181 bool canCollapsePreprocessorAction()
const {
5182 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5183 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5184 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5189 struct JobActionInfo final {
5199 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5201 unsigned ElementNum) {
5202 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5203 for (
unsigned I = 0; I < ElementNum; ++I)
5204 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5205 ActionInfo[I].SavedOffloadAction.end());
5221 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5223 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5224 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5225 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5226 if (!AJ || !BJ || !CJ)
5230 const Tool *
T = TC.SelectTool(*CJ);
5237 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5243 const Tool *BT = TC.SelectTool(*BJ);
5248 if (!
T->hasIntegratedAssembler())
5251 Inputs = CJ->getInputs();
5252 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5259 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5261 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5262 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5267 const Tool *
T = TC.SelectTool(*BJ);
5271 if (!
T->hasIntegratedAssembler())
5274 Inputs = BJ->getInputs();
5275 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5282 if (ActionInfo.size() < 2)
5284 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5285 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5294 bool InputIsBitcode =
true;
5295 for (
size_t i = 1; i < ActionInfo.size(); i++)
5296 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5297 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5298 InputIsBitcode =
false;
5301 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5305 const Tool *
T = TC.SelectTool(*CJ);
5312 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5315 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5318 Inputs = CJ->getInputs();
5319 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5330 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5336 for (
Action *A : Inputs) {
5337 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5338 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5339 NewInputs.push_back(A);
5345 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5346 PreprocessJobOffloadActions.end());
5347 NewInputs.append(PJ->input_begin(), PJ->input_end());
5355 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5357 assert(BaseAction &&
"Invalid base action.");
5374 ActionChain.back().JA = BaseAction;
5375 while (ActionChain.back().JA) {
5376 const Action *CurAction = ActionChain.back().JA;
5379 ActionChain.resize(ActionChain.size() + 1);
5380 JobActionInfo &AI = ActionChain.back();
5384 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5388 ActionChain.pop_back();
5396 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5397 CollapsedOffloadAction);
5399 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5401 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5407 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5419 StringRef BoundArch,
5421 std::string TriplePlusArch = TC->
getTriple().normalize();
5422 if (!BoundArch.empty()) {
5423 TriplePlusArch +=
"-";
5424 TriplePlusArch += BoundArch;
5426 TriplePlusArch +=
"-";
5428 return TriplePlusArch;
5433 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5434 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5437 std::pair<const Action *, std::string> ActionTC = {
5439 auto CachedResult = CachedResults.find(ActionTC);
5440 if (CachedResult != CachedResults.end()) {
5441 return CachedResult->second;
5444 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5445 CachedResults, TargetDeviceOffloadKind);
5446 CachedResults[ActionTC] =
Result;
5451 const JobAction *JA,
const char *BaseInput,
5454 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5458 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5459 Path = A->getValue();
5460 if (llvm::sys::fs::is_directory(
Path)) {
5462 llvm::sys::path::replace_extension(Tmp,
"json");
5463 llvm::sys::path::append(
Path, llvm::sys::path::filename(Tmp));
5466 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5469 Path = DumpDir->getValue();
5470 Path += llvm::sys::path::filename(BaseInput);
5474 llvm::sys::path::replace_extension(
Path,
"json");
5476 const char *ResultFile =
C.getArgs().MakeArgString(
Path);
5477 C.addTimeTraceFile(ResultFile, JA);
5478 C.addResultFile(ResultFile, JA);
5483 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5484 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5487 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5490 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5523 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5525 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5526 const char *DepBoundArch) {
5529 LinkingOutput, CachedResults,
5539 OA->doOnEachDependence(
5540 BuildingForOffloadDevice,
5543 C, DepA, DepTC, DepBoundArch,
false,
5544 !!DepBoundArch, LinkingOutput, CachedResults,
5548 A = BuildingForOffloadDevice
5549 ? OA->getSingleDeviceDependence(
true)
5550 : OA->getHostDependence();
5554 std::pair<const Action *, std::string> ActionTC = {
5555 OA->getHostDependence(),
5557 if (CachedResults.find(ActionTC) != CachedResults.end()) {
5559 Inputs.append(OffloadDependencesInputInfo);
5564 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5567 const Arg &Input = IA->getInputArg();
5569 if (Input.getOption().matches(options::OPT_INPUT)) {
5570 const char *
Name = Input.getValue();
5580 if (!ArchName.empty())
5581 TC = &getToolChain(
C.getArgs(),
5583 C.getArgs(), ArchName));
5585 TC = &
C.getDefaultToolChain();
5588 MultipleArchs, LinkingOutput, CachedResults,
5589 TargetDeviceOffloadKind);
5595 const JobAction *JA = cast<JobAction>(A);
5600 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5607 for (
const auto *OA : CollapsedOffloadActions)
5608 cast<OffloadAction>(OA)->doOnEachDependence(
5609 BuildingForOffloadDevice,
5612 C, DepA, DepTC, DepBoundArch,
false,
5613 !!DepBoundArch, LinkingOutput, CachedResults,
5619 for (
const Action *Input : Inputs) {
5623 bool SubJobAtTopLevel =
5624 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5626 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5631 const char *BaseInput = InputInfos[0].getBaseInput();
5632 for (
auto &Info : InputInfos) {
5633 if (Info.isFilename()) {
5634 BaseInput = Info.getBaseInput();
5641 if (JA->
getType() == types::TY_dSYM)
5642 BaseInput = InputInfos[0].getFilename();
5645 if (!OffloadDependencesInputInfo.empty())
5646 InputInfos.append(OffloadDependencesInputInfo.begin(),
5647 OffloadDependencesInputInfo.end());
5650 llvm::Triple EffectiveTriple;
5652 const ArgList &Args =
5654 if (InputInfos.size() != 1) {
5658 EffectiveTriple = llvm::Triple(
5666 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5670 for (
auto &UI : UA->getDependentActionsInfo()) {
5672 "Unbundling with no offloading??");
5679 UI.DependentOffloadKind,
5680 UI.DependentToolChain->getTriple().normalize(),
5691 UnbundlingResults.push_back(CurI);
5700 Arch = UI.DependentBoundArch;
5705 UI.DependentOffloadKind)}] = {
5711 std::pair<const Action *, std::string> ActionTC = {
5713 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5714 "Result does not exist??");
5715 Result = CachedResults[ActionTC].front();
5716 }
else if (JA->
getType() == types::TY_Nothing)
5723 isa<OffloadPackagerJobAction>(A) ||
5727 AtTopLevel, MultipleArchs,
5730 if (
T->canEmitIR() && OffloadingPrefix.empty())
5735 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5736 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5737 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5738 llvm::errs() << InputInfos[i].getAsString();
5740 llvm::errs() <<
", ";
5742 if (UnbundlingResults.empty())
5743 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5745 llvm::errs() <<
"], outputs: [";
5746 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5747 llvm::errs() << UnbundlingResults[i].getAsString();
5749 llvm::errs() <<
", ";
5751 llvm::errs() <<
"] \n";
5754 if (UnbundlingResults.empty())
5760 T->ConstructJobMultipleOutputs(
5761 C, *JA, UnbundlingResults, InputInfos,
5769 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5770 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5782 if (ArgValue.empty()) {
5785 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
5787 llvm::sys::path::append(
Filename, BaseName);
5790 if (!llvm::sys::path::has_extension(ArgValue)) {
5795 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5800 llvm::sys::path::replace_extension(
Filename, Extension);
5803 return Args.MakeArgString(
Filename.c_str());
5807 if (isa<PreprocessJobAction>(JA))
5809 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
5811 if (isa<OffloadBundlingJobAction>(JA) &&
5818 StringRef Suffix,
bool MultipleArchs,
5819 StringRef BoundArch,
5820 bool NeedUniqueDirectory)
const {
5822 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
5823 std::optional<std::string> CrashDirectory =
5825 ? std::string(A->getValue())
5826 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
5827 if (CrashDirectory) {
5828 if (!
getVFS().exists(*CrashDirectory))
5829 llvm::sys::fs::create_directories(*CrashDirectory);
5831 llvm::sys::path::append(
Path, Prefix);
5832 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
5833 if (std::error_code EC =
5834 llvm::sys::fs::createUniqueFile(
Path + Middle + Suffix, TmpName)) {
5835 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
5839 if (MultipleArchs && !BoundArch.empty()) {
5840 if (NeedUniqueDirectory) {
5842 llvm::sys::path::append(TmpName,
5843 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
5853 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5868 const char *BaseInput) {
5869 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
5870 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
5871 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
5876 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
5880 const char *BaseInput,
5881 StringRef OrigBoundArch,
bool AtTopLevel,
5883 StringRef OffloadingPrefix)
const {
5884 std::string BoundArch = OrigBoundArch.str();
5885 if (is_style_windows(llvm::sys::path::Style::native)) {
5888 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
5891 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
5893 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
5894 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
5895 return C.addResultFile(FinalOutput->getValue(), &JA);
5899 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
5900 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
5901 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5903 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
5904 NameArg = A->getValue();
5905 return C.addResultFile(
5915 if (JA.
getType() == types::TY_ModuleFile &&
5916 C.getArgs().getLastArg(options::OPT_module_file_info)) {
5920 if (JA.
getType() == types::TY_PP_Asm &&
5921 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
5922 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
5925 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
5928 if (JA.
getType() == types::TY_Object &&
5929 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
5930 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
5933 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
5937 if (JA.
getType() == types::TY_PP_Asm &&
5938 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
5939 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
5941 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5942 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
5943 return C.addResultFile(
5948 if (JA.
getType() == types::TY_API_INFO &&
5949 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
5950 C.getArgs().hasArg(options::OPT_o))
5951 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
5952 <<
C.getArgs().getLastArgValue(options::OPT_o);
5959 bool SpecifiedModuleOutput =
5960 C.getArgs().hasArg(options::OPT_fmodule_output) ||
5961 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
5962 if (MultipleArchs && SpecifiedModuleOutput)
5963 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
5967 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
5968 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
5969 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
5975 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
5977 StringRef
Name = llvm::sys::path::filename(BaseInput);
5978 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5979 const char *Suffix =
5984 llvm::Triple Triple(
C.getDriver().getTargetTriple());
5985 bool NeedUniqueDirectory =
5988 Triple.isOSDarwin();
5989 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
5990 NeedUniqueDirectory);
5998 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
5999 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6004 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6005 llvm::sys::path::filename(BasePath));
6006 BaseName = ExternalPath;
6007 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
6008 BaseName = BasePath;
6010 BaseName = llvm::sys::path::filename(BasePath);
6013 const char *NamedOutput;
6015 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6016 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6020 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6024 }
else if (JA.
getType() == types::TY_Image &&
6025 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6026 options::OPT__SLASH_o)) {
6030 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6034 }
else if (JA.
getType() == types::TY_Image) {
6044 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6045 options::OPT_fno_gpu_rdc,
false);
6046 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6047 if (UseOutExtension) {
6049 llvm::sys::path::replace_extension(Output,
"");
6051 Output += OffloadingPrefix;
6052 if (MultipleArchs && !BoundArch.empty()) {
6054 Output.append(BoundArch);
6056 if (UseOutExtension)
6058 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6061 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6062 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6063 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6066 .getLastArg(options::OPT__SLASH_o)
6071 const char *Suffix =
6073 assert(Suffix &&
"All types used for output should have a suffix.");
6075 std::string::size_type End = std::string::npos;
6077 End = BaseName.rfind(
'.');
6079 Suffixed += OffloadingPrefix;
6080 if (MultipleArchs && !BoundArch.empty()) {
6082 Suffixed.append(BoundArch);
6087 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6088 const llvm::opt::DerivedArgList &Args) {
6093 return isa<CompileJobAction>(JA) &&
6095 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6100 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6101 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6102 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6106 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6110 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6111 JA.
getType() != types::TY_PCH) {
6112 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6114 llvm::sys::path::remove_filename(TempPath);
6115 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6116 llvm::sys::path::append(TempPath, OutputFileName);
6117 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6123 bool SameFile =
false;
6125 llvm::sys::fs::current_path(
Result);
6126 llvm::sys::path::append(
Result, BaseName);
6127 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6130 StringRef
Name = llvm::sys::path::filename(BaseInput);
6131 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6135 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6141 llvm::sys::path::remove_filename(BasePath);
6142 if (BasePath.empty())
6143 BasePath = NamedOutput;
6145 llvm::sys::path::append(BasePath, NamedOutput);
6146 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6149 return C.addResultFile(NamedOutput, &JA);
6155 -> std::optional<std::string> {
6158 for (
const auto &
Dir :
P) {
6162 llvm::sys::path::append(
P,
Name);
6163 if (llvm::sys::fs::exists(Twine(
P)))
6164 return std::string(
P);
6166 return std::nullopt;
6173 llvm::sys::path::append(R,
Name);
6174 if (llvm::sys::fs::exists(Twine(R)))
6175 return std::string(R);
6178 llvm::sys::path::append(
P,
Name);
6179 if (llvm::sys::fs::exists(Twine(
P)))
6180 return std::string(
P);
6183 llvm::sys::path::append(
D,
"..",
Name);
6184 if (llvm::sys::fs::exists(Twine(
D)))
6185 return std::string(
D);
6193 return std::string(
Name);
6196void Driver::generatePrefixedToolNames(
6200 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6201 Names.emplace_back(
Tool);
6205 llvm::sys::path::append(Dir, Name);
6206 if (llvm::sys::fs::can_execute(Twine(Dir)))
6208 llvm::sys::path::remove_filename(Dir);
6214 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6219 if (llvm::sys::fs::is_directory(PrefixDir)) {
6222 return std::string(
P);
6225 if (llvm::sys::fs::can_execute(Twine(
P)))
6226 return std::string(
P);
6231 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6239 for (
const auto &
Path : List) {
6242 return std::string(
P);
6246 if (llvm::ErrorOr<std::string>
P =
6247 llvm::sys::findProgramByName(TargetSpecificExecutable))
6251 return std::string(
Name);
6256 std::string error =
"<NOT PRESENT>";
6260 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6277 llvm::sys::path::remove_filename(path);
6278 llvm::sys::path::append(path,
"libc++.modules.json");
6279 if (TC.
getVFS().exists(path))
6280 return static_cast<std::string
>(path);
6285 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6288 return evaluate(
"libc++.a").value_or(error);
6301 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix,
Path);
6303 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6307 return std::string(
Path);
6312 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix,
Path);
6314 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6318 return std::string(
Path);
6323 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6327 Output = FpArg->getValue();
6331 if (!llvm::sys::path::has_extension(Output))
6334 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6335 Output = YcArg->getValue();
6338 llvm::sys::path::replace_extension(Output,
".pch");
6340 return std::string(Output);
6343const ToolChain &Driver::getToolChain(
const ArgList &Args,
6344 const llvm::Triple &
Target)
const {
6346 auto &TC = ToolChains[
Target.str()];
6348 switch (
Target.getOS()) {
6349 case llvm::Triple::AIX:
6350 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6352 case llvm::Triple::Haiku:
6353 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6355 case llvm::Triple::Darwin:
6356 case llvm::Triple::MacOSX:
6357 case llvm::Triple::IOS:
6358 case llvm::Triple::TvOS:
6359 case llvm::Triple::WatchOS:
6360 case llvm::Triple::XROS:
6361 case llvm::Triple::DriverKit:
6362 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6364 case llvm::Triple::DragonFly:
6365 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6367 case llvm::Triple::OpenBSD:
6368 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6370 case llvm::Triple::NetBSD:
6371 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6373 case llvm::Triple::FreeBSD:
6375 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6378 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6380 case llvm::Triple::Linux:
6381 case llvm::Triple::ELFIAMCU:
6382 if (
Target.getArch() == llvm::Triple::hexagon)
6383 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6385 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6386 !
Target.hasEnvironment())
6387 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6390 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6392 else if (
Target.getArch() == llvm::Triple::ve)
6393 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6394 else if (
Target.isOHOSFamily())
6395 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6397 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6399 case llvm::Triple::NaCl:
6400 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6402 case llvm::Triple::Fuchsia:
6403 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6405 case llvm::Triple::Solaris:
6406 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6408 case llvm::Triple::CUDA:
6409 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6411 case llvm::Triple::AMDHSA:
6412 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6414 case llvm::Triple::AMDPAL:
6415 case llvm::Triple::Mesa3D:
6416 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6418 case llvm::Triple::Win32:
6419 switch (
Target.getEnvironment()) {
6421 if (
Target.isOSBinFormatELF())
6422 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6423 else if (
Target.isOSBinFormatMachO())
6424 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6426 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6428 case llvm::Triple::GNU:
6429 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6431 case llvm::Triple::Itanium:
6432 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6435 case llvm::Triple::MSVC:
6436 case llvm::Triple::UnknownEnvironment:
6437 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6438 .starts_with_insensitive(
"bfd"))
6439 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6443 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6447 case llvm::Triple::PS4:
6448 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6450 case llvm::Triple::PS5:
6451 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6453 case llvm::Triple::Hurd:
6454 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6456 case llvm::Triple::LiteOS:
6457 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6459 case llvm::Triple::ZOS:
6460 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6462 case llvm::Triple::ShaderModel:
6463 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6468 switch (
Target.getArch()) {
6469 case llvm::Triple::tce:
6470 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6472 case llvm::Triple::tcele:
6473 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6475 case llvm::Triple::hexagon:
6476 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6479 case llvm::Triple::lanai:
6480 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6482 case llvm::Triple::xcore:
6483 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6485 case llvm::Triple::wasm32:
6486 case llvm::Triple::wasm64:
6487 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6489 case llvm::Triple::avr:
6490 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6492 case llvm::Triple::msp430:
6494 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6496 case llvm::Triple::riscv32:
6497 case llvm::Triple::riscv64:
6500 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6502 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6504 case llvm::Triple::ve:
6505 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6507 case llvm::Triple::spirv32:
6508 case llvm::Triple::spirv64:
6509 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6511 case llvm::Triple::csky:
6512 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6516 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6517 else if (
Target.isOSBinFormatELF())
6518 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6519 else if (
Target.isOSBinFormatMachO())
6520 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6522 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6530const ToolChain &Driver::getOffloadingDeviceToolChain(
6531 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6540 switch (TargetDeviceOffloadKind) {
6542 if (((
Target.getArch() == llvm::Triple::amdgcn ||
6543 Target.getArch() == llvm::Triple::spirv64) &&
6544 Target.getVendor() == llvm::Triple::AMD &&
6545 Target.getOS() == llvm::Triple::AMDHSA) ||
6546 !Args.hasArgNoClaim(options::OPT_offload_EQ))
6547 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6549 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6550 Target.getVendor() == llvm::Triple::UnknownVendor &&
6551 Target.getOS() == llvm::Triple::UnknownOS)
6552 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6566 if (JA.
size() != 1 ||
6571 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6572 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6573 !isa<ExtractAPIJobAction>(JA))
6581 if (JA.
size() != 1 ||
6586 if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) &&
6587 !isa<BackendJobAction>(JA))
6595 if (Args.hasArg(options::OPT_emit_static_lib))
6606 unsigned &Micro,
bool &HadExtra) {
6609 Major = Minor = Micro = 0;
6613 if (Str.consumeInteger(10, Major))
6617 if (!Str.consume_front(
"."))
6620 if (Str.consumeInteger(10, Minor))
6624 if (!Str.consume_front(
"."))
6627 if (Str.consumeInteger(10, Micro))
6645 unsigned CurDigit = 0;
6646 while (CurDigit < Digits.size()) {
6648 if (Str.consumeInteger(10, Digit))
6650 Digits[CurDigit] = Digit;
6653 if (!Str.consume_front(
"."))
6662llvm::opt::Visibility
6663Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6676const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6692 llvm_unreachable(
"Unhandled Mode");
6696 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6701 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6702 options::OPT_fno_save_optimization_record,
false))
6706 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6707 options::OPT_fno_save_optimization_record,
false))
6711 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6712 options::OPT_fno_save_optimization_record,
false))
6716 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6717 options::OPT_fno_save_optimization_record,
false))
6724 static StringRef OptName =
6726 llvm::StringRef Opt;
6727 for (StringRef Arg : Args) {
6728 if (!Arg.starts_with(OptName))
6734 return Opt.consume_front(OptName) ? Opt :
"";
6741 llvm::BumpPtrAllocator &Alloc,
6742 llvm::vfs::FileSystem *FS) {
6751 for (
const char *F : Args) {
6752 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6754 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6755 RSPQuoting = Windows;
6763 llvm::cl::TokenizerCallback Tokenizer;
6765 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6767 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6769 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6772 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6773 ECtx.setMarkEOLs(MarkEOLs);
6777 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
6781 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
6782 [](
const char *A) {
return A !=
nullptr; });
6783 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
6786 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
6787 Args.resize(newEnd - Args.begin());
6791 return llvm::Error::success();
6795 return SavedStrings.insert(S).first->getKeyData();
6828 llvm::StringSet<> &SavedStrings) {
6831 if (Edit[0] ==
'^') {
6832 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6833 OS <<
"### Adding argument " << Str <<
" at beginning\n";
6834 Args.insert(Args.begin() + 1, Str);
6835 }
else if (Edit[0] ==
'+') {
6836 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6837 OS <<
"### Adding argument " << Str <<
" at end\n";
6838 Args.push_back(Str);
6839 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
6840 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
6841 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
6842 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
6843 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
6845 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
6847 if (Args[i] ==
nullptr)
6849 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
6851 if (Repl != Args[i]) {
6852 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
6856 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
6857 auto Option = Edit.substr(1);
6858 for (
unsigned i = 1; i < Args.size();) {
6859 if (Option == Args[i]) {
6860 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6861 Args.erase(Args.begin() + i);
6862 if (Edit[0] ==
'X') {
6863 if (i < Args.size()) {
6864 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6865 Args.erase(Args.begin() + i);
6867 OS <<
"### Invalid X edit, end of command line!\n";
6872 }
else if (Edit[0] ==
'O') {
6873 for (
unsigned i = 1; i < Args.size();) {
6874 const char *A = Args[i];
6878 if (A[0] ==
'-' && A[1] ==
'O' &&
6879 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
6880 (
'0' <= A[2] && A[2] <=
'9'))))) {
6881 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6882 Args.erase(Args.begin() + i);
6886 OS <<
"### Adding argument " << Edit <<
" at end\n";
6887 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
6889 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
6894 const char *OverrideStr,
6895 llvm::StringSet<> &SavedStrings,
6898 OS = &llvm::nulls();
6900 if (OverrideStr[0] ==
'#') {
6902 OS = &llvm::nulls();
6905 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
6909 const char *S = OverrideStr;
6911 const char *End = ::strchr(S,
' ');
6913 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
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const
Based on the way the client configured the DiagnosticsEngine object, classify the specified diagnosti...
Encodes a location in the source.
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.
bool HandleImmediateArgs(Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
std::string Name
The name the driver was invoked as.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
std::string ClangExecutable
The original path to the clang executable.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
std::pair< types::ID, const llvm::opt::Arg * > InputTy
An input type and its arguments.
bool isUsingOffloadLTO() const
Returns true if we are performing any kind of offload LTO.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError)
ParseArgStrings - Parse the given list of strings into an ArgList.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
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.
static bool IsAMDOffloadArch(OffloadArch A)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
@ Result
The result type of a method or function.
static bool IsNVIDIAOffloadArch(OffloadArch A)
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
const FunctionProtoType * T
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
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.