58#include "clang/Config/config.h"
69#include "llvm/ADT/ArrayRef.h"
70#include "llvm/ADT/STLExtras.h"
71#include "llvm/ADT/StringExtras.h"
72#include "llvm/ADT/StringRef.h"
73#include "llvm/ADT/StringSet.h"
74#include "llvm/ADT/StringSwitch.h"
75#include "llvm/Config/llvm-config.h"
76#include "llvm/MC/TargetRegistry.h"
77#include "llvm/Option/Arg.h"
78#include "llvm/Option/ArgList.h"
79#include "llvm/Option/OptSpecifier.h"
80#include "llvm/Option/OptTable.h"
81#include "llvm/Option/Option.h"
82#include "llvm/Support/CommandLine.h"
83#include "llvm/Support/ErrorHandling.h"
84#include "llvm/Support/ExitCodes.h"
85#include "llvm/Support/FileSystem.h"
86#include "llvm/Support/FormatVariadic.h"
87#include "llvm/Support/MD5.h"
88#include "llvm/Support/Path.h"
89#include "llvm/Support/PrettyStackTrace.h"
90#include "llvm/Support/Process.h"
91#include "llvm/Support/Program.h"
92#include "llvm/Support/Regex.h"
93#include "llvm/Support/StringSaver.h"
94#include "llvm/Support/VirtualFileSystem.h"
95#include "llvm/Support/raw_ostream.h"
96#include "llvm/TargetParser/Host.h"
97#include "llvm/TargetParser/RISCVISAInfo.h"
109using namespace clang;
113 const ArgList &Args) {
114 auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
118 switch (OffloadTargets.size()) {
120 D.Diag(diag::err_drv_only_one_offload_target_supported);
123 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) <<
"";
128 return llvm::Triple(OffloadTargets[0]);
131static std::optional<llvm::Triple>
133 const llvm::Triple &HostTriple) {
134 if (!Args.hasArg(options::OPT_offload_EQ)) {
135 return llvm::Triple(HostTriple.isArch64Bit() ?
"nvptx64-nvidia-cuda"
136 :
"nvptx-nvidia-cuda");
139 if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
140 TT->getArch() == llvm::Triple::spirv64)) {
141 if (Args.hasArg(options::OPT_emit_llvm))
143 D.Diag(diag::err_drv_cuda_offload_only_emit_bc);
146 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
149static std::optional<llvm::Triple>
151 if (!Args.hasArg(options::OPT_offload_EQ)) {
152 auto OffloadArchs = Args.getAllArgValues(options::OPT_offload_arch_EQ);
153 if (llvm::is_contained(OffloadArchs,
"amdgcnspirv") &&
154 OffloadArchs.size() == 1)
155 return llvm::Triple(
"spirv64-amd-amdhsa");
156 return llvm::Triple(
"amdgcn-amd-amdhsa");
161 if (TT->getArch() == llvm::Triple::amdgcn &&
162 TT->getVendor() == llvm::Triple::AMD &&
163 TT->getOS() == llvm::Triple::AMDHSA)
165 if (TT->getArch() == llvm::Triple::spirv64)
167 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
178 StringRef
Dir = llvm::sys::path::parent_path(BinaryPath);
181 StringRef ConfiguredResourceDir(CLANG_RESOURCE_DIR);
182 if (!ConfiguredResourceDir.empty()) {
183 llvm::sys::path::append(
P, ConfiguredResourceDir);
190 P = llvm::sys::path::parent_path(
Dir);
193 llvm::sys::path::append(
P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
194 CLANG_VERSION_MAJOR_STRING);
197 return std::string(
P);
201 : UseCUID(
Kind::Hash) {
202 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
203 StringRef UseCUIDStr = A->getValue();
204 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
210 D.Diag(clang::diag::err_drv_invalid_value)
211 << A->getAsString(Args) << UseCUIDStr;
214 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
215 if (!FixedCUID.empty())
220 llvm::opt::DerivedArgList &Args)
const {
221 std::string CUID = FixedCUID.str();
224 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
228 llvm::MD5::MD5Result
Hash;
230 llvm::sys::fs::real_path(InputFile, RealPath,
232 Hasher.update(RealPath);
233 for (
auto *A : Args) {
234 if (A->getOption().matches(options::OPT_INPUT))
236 Hasher.update(A->getAsString(Args));
239 CUID = llvm::utohexstr(
Hash.low(),
true);
247 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
248 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
251 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
252 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
253 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
254 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
255 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
256 CheckInputsExist(
true), ProbePrecompiled(
true),
257 SuppressMissingInputWarning(
false) {
260 this->VFS = llvm::vfs::getRealFileSystem();
265 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
268 llvm::sys::path::append(
P,
SysRoot);
272#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
273 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
277 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
278 llvm::sys::path::remove_dots(configFileDir,
true);
282#if defined(CLANG_CONFIG_FILE_USER_DIR)
285 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
294void Driver::setDriverMode(StringRef
Value) {
295 static StringRef OptName =
296 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
297 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
298 .Case(
"gcc", GCCMode)
299 .Case(
"g++", GXXMode)
300 .Case(
"cpp", CPPMode)
302 .Case(
"flang", FlangMode)
303 .Case(
"dxc", DXCMode)
307 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
312 bool &ContainsError)
const {
313 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
314 ContainsError =
false;
316 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
317 unsigned MissingArgIndex, MissingArgCount;
318 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
319 MissingArgCount, VisibilityMask);
322 if (MissingArgCount) {
323 Diag(diag::err_drv_missing_argument)
324 << Args.getArgString(MissingArgIndex) << MissingArgCount;
331 for (
const Arg *A : Args) {
333 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
341 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
342 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
344 diag::warn_drv_empty_joined_argument,
349 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
351 auto ArgString = A->getAsString(Args);
353 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
355 getOpts().findExact(ArgString, Nearest,
357 DiagID = diag::err_drv_unknown_argument_with_suggestion;
358 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
360 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
361 : diag::err_drv_unknown_argument;
362 Diags.
Report(DiagID) << ArgString;
366 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
367 : diag::err_drv_unknown_argument_with_suggestion;
368 Diags.
Report(DiagID) << ArgString << Nearest;
374 for (
const Arg *A : Args.filtered(options::OPT_o)) {
375 if (ArgStrings[A->getIndex()] == A->getSpelling())
379 std::string ArgString = ArgStrings[A->getIndex()];
381 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
382 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
383 << A->getAsString(Args) << Nearest;
393 Arg **FinalPhaseArg)
const {
394 Arg *PhaseArg =
nullptr;
398 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
399 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
400 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
401 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
408 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
409 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
410 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
411 options::OPT_fmodule_header_EQ))) {
414 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
415 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
417 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
418 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
419 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
420 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
421 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
422 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
423 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
424 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
428 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
432 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
435 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
443 *FinalPhaseArg = PhaseArg;
449 StringRef
Value,
bool Claim =
true) {
450 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
451 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
452 Args.AddSynthesizedArg(A);
458DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
459 const llvm::opt::OptTable &Opts =
getOpts();
460 DerivedArgList *DAL =
new DerivedArgList(Args);
462 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
463 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
464 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
465 bool IgnoreUnused =
false;
466 for (Arg *A : Args) {
470 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
474 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
475 IgnoreUnused =
false;
485 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
486 A->getOption().matches(options::OPT_Xlinker)) &&
487 A->containsValue(
"--no-demangle")) {
489 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
492 for (StringRef Val : A->getValues())
493 if (Val !=
"--no-demangle")
494 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
502 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
503 A->getNumValues() > 0 &&
504 (A->getValue(0) == StringRef(
"-MD") ||
505 A->getValue(0) == StringRef(
"-MMD"))) {
507 if (A->getValue(0) == StringRef(
"-MD"))
508 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
510 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
511 if (A->getNumValues() == 2)
512 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
517 if (A->getOption().matches(options::OPT_l)) {
518 StringRef
Value = A->getValue();
521 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
523 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
528 if (
Value ==
"cc_kext") {
529 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
535 if (A->getOption().matches(options::OPT__DASH_DASH)) {
537 for (StringRef Val : A->getValues())
546 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
547 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
550 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
551 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
555#if defined(HOST_LINK_VERSION)
556 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
557 strlen(HOST_LINK_VERSION) > 0) {
558 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
560 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
572 StringRef TargetTriple,
574 StringRef DarwinArchName =
"") {
576 if (
const Arg *A = Args.getLastArg(options::OPT_target))
577 TargetTriple = A->getValue();
579 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
584 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
588 if (
Target.isOSBinFormatMachO()) {
590 if (!DarwinArchName.empty()) {
597 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
598 StringRef ArchName = A->getValue();
605 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
606 options::OPT_mbig_endian)) {
607 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
608 ?
Target.getLittleEndianArchVariant()
609 :
Target.getBigEndianArchVariant();
610 if (
T.getArch() != llvm::Triple::UnknownArch) {
612 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
617 if (
Target.getArch() == llvm::Triple::tce)
622 if (std::optional<std::string> ObjectModeValue =
623 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
624 StringRef ObjectMode = *ObjectModeValue;
625 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
627 if (ObjectMode ==
"64") {
628 AT =
Target.get64BitArchVariant().getArch();
629 }
else if (ObjectMode ==
"32") {
630 AT =
Target.get32BitArchVariant().getArch();
632 D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
635 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
641 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
642 D.Diag(diag::err_target_unknown_triple) <<
Target.str();
645 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
647 D.Diag(diag::err_drv_unsupported_opt_for_target)
648 << A->getAsString(Args) <<
Target.str();
651 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
652 options::OPT_m32, options::OPT_m16,
653 options::OPT_maix32, options::OPT_maix64);
655 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
657 if (A->getOption().matches(options::OPT_m64) ||
658 A->getOption().matches(options::OPT_maix64)) {
659 AT =
Target.get64BitArchVariant().getArch();
660 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
661 Target.getEnvironment() == llvm::Triple::GNUT64)
662 Target.setEnvironment(llvm::Triple::GNU);
663 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
664 Target.setEnvironment(llvm::Triple::Musl);
665 }
else if (A->getOption().matches(options::OPT_mx32) &&
666 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
667 AT = llvm::Triple::x86_64;
668 if (
Target.getEnvironment() == llvm::Triple::Musl)
669 Target.setEnvironment(llvm::Triple::MuslX32);
671 Target.setEnvironment(llvm::Triple::GNUX32);
672 }
else if (A->getOption().matches(options::OPT_m32) ||
673 A->getOption().matches(options::OPT_maix32)) {
674 AT =
Target.get32BitArchVariant().getArch();
675 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
676 Target.setEnvironment(llvm::Triple::GNU);
677 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
678 Target.setEnvironment(llvm::Triple::Musl);
679 }
else if (A->getOption().matches(options::OPT_m16) &&
680 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
681 AT = llvm::Triple::x86;
682 Target.setEnvironment(llvm::Triple::CODE16);
685 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
687 if (
Target.isWindowsGNUEnvironment())
693 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
694 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
695 D.Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
698 if (A && !A->getOption().matches(options::OPT_m32))
699 D.Diag(diag::err_drv_argument_not_allowed_with)
700 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
702 Target.setArch(llvm::Triple::x86);
703 Target.setArchName(
"i586");
704 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
705 Target.setEnvironmentName(
"");
706 Target.setOS(llvm::Triple::ELFIAMCU);
707 Target.setVendor(llvm::Triple::UnknownVendor);
708 Target.setVendorName(
"intel");
714 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
715 StringRef ABIName = A->getValue();
716 if (ABIName ==
"32") {
718 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
719 Target.getEnvironment() == llvm::Triple::GNUABIN32)
720 Target.setEnvironment(llvm::Triple::GNU);
721 }
else if (ABIName ==
"n32") {
723 if (
Target.getEnvironment() == llvm::Triple::GNU ||
724 Target.getEnvironment() == llvm::Triple::GNUT64 ||
725 Target.getEnvironment() == llvm::Triple::GNUABI64)
726 Target.setEnvironment(llvm::Triple::GNUABIN32);
727 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
728 Target.getEnvironment() == llvm::Triple::MuslABI64)
729 Target.setEnvironment(llvm::Triple::MuslABIN32);
730 }
else if (ABIName ==
"64") {
732 if (
Target.getEnvironment() == llvm::Triple::GNU ||
733 Target.getEnvironment() == llvm::Triple::GNUT64 ||
734 Target.getEnvironment() == llvm::Triple::GNUABIN32)
735 Target.setEnvironment(llvm::Triple::GNUABI64);
736 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
737 Target.getEnvironment() == llvm::Triple::MuslABIN32)
738 Target.setEnvironment(llvm::Triple::MuslABI64);
746 if (Args.hasArg(options::OPT_march_EQ) ||
747 Args.hasArg(options::OPT_mcpu_EQ)) {
749 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
751 if (!llvm::errorToBool(ISAInfo.takeError())) {
752 unsigned XLen = (*ISAInfo)->getXLen();
754 Target.setArch(llvm::Triple::riscv32);
756 Target.setArch(llvm::Triple::riscv64);
768 OptSpecifier OptEq, OptSpecifier OptNeg) {
769 if (!Args.hasFlag(OptEq, OptNeg,
false))
772 const Arg *A = Args.getLastArg(OptEq);
773 StringRef LTOName = A->getValue();
781 D.Diag(diag::err_drv_unsupported_option_argument)
782 << A->getSpelling() << A->getValue();
789void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
791 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
793 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
794 options::OPT_fno_offload_lto);
797 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
798 options::OPT_fno_openmp_target_jit,
false)) {
799 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
800 options::OPT_fno_offload_lto))
802 Diag(diag::err_drv_incompatible_options)
803 << A->getSpelling() <<
"-fopenmp-target-jit";
810 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
812 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
814 RuntimeName = A->getValue();
816 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
824 Diag(diag::err_drv_unsupported_option_argument)
825 << A->getSpelling() << A->getValue();
828 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
837 if (llvm::is_contained(SYCLAlias, TargetArch)) {
838 llvm::Triple TargetTriple;
839 TargetTriple.setArchName(TargetArch);
840 TargetTriple.setVendor(llvm::Triple::UnknownVendor);
841 TargetTriple.setOS(llvm::Triple::UnknownOS);
844 return llvm::Triple(TargetArch);
850 for (
const auto &SYCLTriple : SYCLTriples) {
851 if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
852 SYCLTriple.isSPIROrSPIRV())
857 C.getDefaultToolChain().getTriple().isArch32Bit() ?
"spirv32"
859 SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple);
872 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
877 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
880 C.getInputArgs().hasArg(options::OPT_hip_link) ||
881 C.getInputArgs().hasArg(options::OPT_hipstdpar);
882 bool UseLLVMOffload =
C.getInputArgs().hasArg(
883 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
884 if (IsCuda && IsHIP) {
885 Diag(clang::diag::err_drv_mix_cuda_hip);
888 if (IsCuda && !UseLLVMOffload) {
890 const llvm::Triple &HostTriple = HostTC->
getTriple();
898 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
900 CudaTC = std::make_unique<toolchains::CudaToolChain>(
901 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
906 if (CudaInstallation.
isValid())
909 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
910 }
else if (IsHIP && !UseLLVMOffload) {
911 if (
auto *OMPTargetArg =
912 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
913 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
914 << OMPTargetArg->getSpelling() <<
"HIP";
922 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
924 C.addOffloadDeviceToolChain(HIPTC, OFK);
935 bool IsOpenMPOffloading =
936 ((IsCuda || IsHIP) && UseLLVMOffload) ||
937 (
C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
938 options::OPT_fno_openmp,
false) &&
939 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
940 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ)));
941 if (IsOpenMPOffloading) {
947 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
951 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
952 llvm::StringMap<StringRef> FoundNormalizedTriples;
953 std::multiset<StringRef> OpenMPTriples;
958 if (Arg *OpenMPTargets =
959 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
960 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
961 Diag(clang::diag::warn_drv_empty_joined_argument)
962 << OpenMPTargets->getAsString(
C.getInputArgs());
965 for (StringRef
T : OpenMPTargets->getValues())
966 OpenMPTriples.insert(
T);
967 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
968 ((!IsHIP && !IsCuda) || UseLLVMOffload)) {
978 llvm::DenseSet<StringRef> Archs;
980 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
981 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
987 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
988 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
993 if (!AMDTriple && !NVPTXTriple) {
994 for (StringRef Arch :
999 for (StringRef Arch : Archs) {
1002 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
1003 }
else if (AMDTriple &&
1006 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
1008 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
1014 if (Archs.empty()) {
1015 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1020 for (
const auto &TripleAndArchs : DerivedArchs)
1021 OpenMPTriples.insert(TripleAndArchs.first());
1024 for (StringRef Val : OpenMPTriples) {
1026 std::string NormalizedName = TT.normalize();
1029 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
1030 if (Duplicate != FoundNormalizedTriples.end()) {
1031 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1032 << Val << Duplicate->second;
1038 FoundNormalizedTriples[NormalizedName] = Val;
1041 if (TT.getArch() == llvm::Triple::UnknownArch)
1042 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
1047 if (TT.isNVPTX() || TT.isAMDGCN() || TT.isSPIRV()) {
1050 assert(HostTC &&
"Host toolchain should be always defined.");
1052 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
1055 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
1056 *
this, TT, *HostTC,
C.getInputArgs());
1057 else if (TT.isAMDGCN())
1058 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
1059 *
this, TT, *HostTC,
C.getInputArgs());
1060 else if (TT.isSPIRV())
1061 DeviceTC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(
1062 *
this, TT, *HostTC,
C.getInputArgs());
1064 assert(DeviceTC &&
"Device toolchain not defined.");
1067 TC = DeviceTC.get();
1069 TC = &getToolChain(
C.getInputArgs(), TT);
1071 auto It = DerivedArchs.find(TT.getTriple());
1072 if (It != DerivedArchs.end())
1073 KnownArchs[TC] = It->second;
1076 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
1077 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1082 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1083 options::OPT_fno_sycl,
false);
1085 auto argSYCLIncompatible = [&](OptSpecifier OptId) {
1088 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(OptId))
1089 Diag(clang::diag::err_drv_argument_not_allowed_with)
1090 << IncompatArg->getSpelling() <<
"-fsycl";
1093 argSYCLIncompatible(options::OPT_static_libstdcxx);
1095 argSYCLIncompatible(options::OPT_ffreestanding);
1106 for (
const auto &TargetTriple : UniqueSYCLTriplesVec) {
1107 auto SYCLTC = &getOffloadingDeviceToolChain(
1118bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1123 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1127 if (!PathLIBEnv.empty()) {
1128 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1129 if (llvm::sys::fs::is_directory(PathLIBEnv))
1130 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1131 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1132 return readConfigFile(CustomizationFile, ExpCtx);
1133 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1138 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1139 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1140 return readConfigFile(CustomizationFile, ExpCtx);
1150 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1151 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1152 Copy->getValues() = Opt->getValues();
1153 if (Opt->isClaimed())
1155 Copy->setOwnsValues(Opt->getOwnsValues());
1156 Opt->setOwnsValues(
false);
1158 if (Opt->getAlias()) {
1159 const Arg *Alias = Opt->getAlias();
1160 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1161 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1162 Args.getArgString(Index), Index);
1163 AliasCopy->getValues() = Alias->getValues();
1164 AliasCopy->setOwnsValues(
false);
1165 if (Alias->isClaimed())
1167 Copy->setAlias(std::move(AliasCopy));
1171bool Driver::readConfigFile(StringRef
FileName,
1172 llvm::cl::ExpansionContext &ExpCtx) {
1176 Diag(diag::err_drv_cannot_open_config_file)
1177 <<
FileName << Status.getError().message();
1180 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1181 Diag(diag::err_drv_cannot_open_config_file)
1182 <<
FileName <<
"not a regular file";
1188 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1189 Diag(diag::err_drv_cannot_read_config_file)
1196 for (
const char *Opt : NewCfgFileArgs) {
1198 if (Opt[0] ==
'$' && Opt[1])
1199 NewCfgTailArgs.push_back(Opt + 1);
1201 NewCfgHeadArgs.push_back(Opt);
1206 llvm::sys::path::native(CfgFileName);
1207 bool ContainErrors =
false;
1208 auto NewHeadOptions = std::make_unique<InputArgList>(
1212 auto NewTailOptions = std::make_unique<InputArgList>(
1219 for (Arg *A : *NewHeadOptions)
1221 for (Arg *A : *NewTailOptions)
1224 if (!CfgOptionsHead)
1225 CfgOptionsHead = std::move(NewHeadOptions);
1228 for (
auto *Opt : *NewHeadOptions)
1232 if (!CfgOptionsTail)
1233 CfgOptionsTail = std::move(NewTailOptions);
1236 for (
auto *Opt : *NewTailOptions)
1240 ConfigFiles.push_back(std::string(CfgFileName));
1244bool Driver::loadConfigFiles() {
1245 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1246 llvm::cl::tokenizeConfigFile);
1247 ExpCtx.setVFS(&
getVFS());
1251 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1254 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1255 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1260 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1262 llvm::sys::fs::expand_tilde(
1263 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1264 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1273 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1276 if (loadDefaultConfigFiles(ExpCtx))
1282 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1285 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1286 CfgFilePath.assign(CfgFileName);
1287 if (llvm::sys::path::is_relative(CfgFilePath)) {
1288 if (
getVFS().makeAbsolute(CfgFilePath)) {
1289 Diag(diag::err_drv_cannot_open_config_file)
1290 << CfgFilePath <<
"cannot get absolute path";
1294 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1296 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1297 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1298 if (!SearchDir.empty())
1299 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1304 if (readConfigFile(CfgFilePath, ExpCtx))
1315 llvm::Triple Triple, std::string Suffix) {
1317 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1321 VersionTuple OSVersion = Triple.getOSVersion();
1322 if (!OSVersion.getMinor().has_value())
1325 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1329 if (OSVersion.getMajor() != 0) {
1330 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1331 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1337 Triple.setOSName(BaseOSName);
1338 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1341bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1344 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1348 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1351 std::string RealMode = getExecutableForDriverMode(Mode);
1352 llvm::Triple Triple;
1361 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1362 PrefixTriple.isOSUnknown())
1363 Triple = PrefixTriple;
1367 llvm::Triple RealTriple =
1369 if (Triple.str().empty()) {
1370 Triple = RealTriple;
1371 assert(!Triple.str().empty());
1376 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1392 "-" + RealMode +
".cfg"))
1393 return readConfigFile(CfgFilePath, ExpCtx);
1397 if (TryModeSuffix) {
1400 return readConfigFile(CfgFilePath, ExpCtx);
1405 std::string CfgFileName = RealMode +
".cfg";
1406 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1407 if (readConfigFile(CfgFilePath, ExpCtx))
1409 }
else if (TryModeSuffix) {
1411 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1412 readConfigFile(CfgFilePath, ExpCtx))
1418 return readConfigFile(CfgFilePath, ExpCtx);
1426 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1435 if (!DriverMode.empty())
1436 setDriverMode(DriverMode);
1442 CLOptions = std::make_unique<InputArgList>(
1447 ContainsError = loadConfigFiles();
1448 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1449 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1453 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1455 if (HasConfigFileHead)
1456 for (
auto *Opt : *CLOptions)
1457 if (!Opt->getOption().matches(options::OPT_config))
1461 if (
IsCLMode() && !ContainsError) {
1463 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1465 CLModePassThroughArgList.push_back(A->getValue());
1468 if (!CLModePassThroughArgList.empty()) {
1471 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1476 for (
auto *Opt : *CLModePassThroughOptions)
1482 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1483 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1484 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1488 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1489 if (!VFS->exists(IncludeDir))
1490 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1495 bool CCCPrintPhases;
1498 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1499 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1502 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1503 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1506 Args.ClaimAllArgs(options::OPT_pipe);
1514 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1516 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1517 CCCGenericGCCName = A->getValue();
1520 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1524 if (Args.hasArg(options::OPT_fproc_stat_report))
1531 llvm::Triple
T(TargetTriple);
1532 T.setOS(llvm::Triple::Win32);
1533 T.setVendor(llvm::Triple::PC);
1534 T.setEnvironment(llvm::Triple::MSVC);
1535 T.setObjectFormat(llvm::Triple::COFF);
1536 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1537 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1538 TargetTriple =
T.str();
1541 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1542 StringRef TargetProfile = A->getValue();
1545 TargetTriple = *Triple;
1547 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1551 if (Args.hasArg(options::OPT_spirv)) {
1552 llvm::Triple
T(TargetTriple);
1553 T.setArch(llvm::Triple::spirv);
1554 T.setOS(llvm::Triple::Vulkan);
1557 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1558 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1559 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1560 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1562 auto TargetInfo = ValidTargets.find(A->getValue());
1565 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1567 Diag(diag::err_drv_invalid_value)
1568 << A->getAsString(Args) << A->getValue();
1573 TargetTriple =
T.str();
1576 Diag(diag::err_drv_dxc_missing_target_profile);
1580 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1581 TargetTriple = A->getValue();
1582 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1583 Dir =
Dir = A->getValue();
1584 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1588 if (std::optional<std::string> CompilerPathValue =
1589 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1590 StringRef CompilerPath = *CompilerPathValue;
1591 while (!CompilerPath.empty()) {
1592 std::pair<StringRef, StringRef> Split =
1593 CompilerPath.split(llvm::sys::EnvPathSeparator);
1594 PrefixDirs.push_back(std::string(Split.first));
1595 CompilerPath = Split.second;
1598 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1600 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1603 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1606 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1607 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1608 .Case(
"cwd", SaveTempsCwd)
1609 .Case(
"obj", SaveTempsObj)
1610 .Default(SaveTempsCwd);
1613 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1614 options::OPT_offload_device_only,
1615 options::OPT_offload_host_device)) {
1616 if (A->getOption().matches(options::OPT_offload_host_only))
1617 Offload = OffloadHost;
1618 else if (A->getOption().matches(options::OPT_offload_device_only))
1619 Offload = OffloadDevice;
1621 Offload = OffloadHostDevice;
1627 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1628 StringRef
Name = A->getValue();
1629 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1630 .Case(
"off", EmbedNone)
1631 .Case(
"all", EmbedBitcode)
1632 .Case(
"bitcode", EmbedBitcode)
1633 .Case(
"marker", EmbedMarker)
1636 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1639 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1643 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1644 llvm::sys::fs::remove(A->getValue());
1650 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1652 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1653 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1654 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1655 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1656 Std->containsValue(
"c++latest"));
1659 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1660 options::OPT_fmodule_header)) {
1662 ModulesModeCXX20 =
true;
1663 if (A->getOption().matches(options::OPT_fmodule_header))
1666 StringRef ArgName = A->getValue();
1667 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1672 Diags.
Report(diag::err_drv_invalid_value)
1673 << A->getAsString(Args) << ArgName;
1679 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1680 std::make_unique<InputArgList>(std::move(Args));
1690 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1691 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1693 bool MLContainsError;
1694 auto MultilibMacroDefineList =
1696 MLMacroDefinesChar,
false, MLContainsError));
1697 if (!MLContainsError) {
1698 for (
auto *Opt : *MultilibMacroDefineList) {
1705 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1709 if (!Triple.isWasm()) {
1710 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1711 StringRef TripleObjectFormat =
1712 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1713 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1714 TripleVersionName != TripleObjectFormat) {
1715 Diags.
Report(diag::err_drv_triple_version_invalid)
1717 ContainsError =
true;
1722 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1723 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1724 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1732 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1733 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1735 case llvm::Triple::arm:
1736 case llvm::Triple::armeb:
1737 case llvm::Triple::thumb:
1738 case llvm::Triple::thumbeb:
1739 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1740 Diag(diag::warn_target_unrecognized_env)
1742 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1745 case llvm::Triple::aarch64:
1746 case llvm::Triple::aarch64_be:
1747 case llvm::Triple::aarch64_32:
1748 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1749 Diag(diag::warn_target_unrecognized_env)
1751 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1768 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1769 if (HasConfigFileTail && Inputs.size()) {
1772 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1773 for (Arg *A : *CfgOptionsTail)
1774 TranslatedLinkerIns.append(A);
1775 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1784 if (TC.
getTriple().isOSBinFormatMachO())
1789 if (CCCPrintPhases) {
1800 llvm::opt::ArgStringList ASL;
1801 for (
const auto *A : Args) {
1805 while (A->getAlias())
1807 A->render(Args, ASL);
1810 for (
auto I = ASL.begin(),
E = ASL.end(); I !=
E; ++I) {
1811 if (I != ASL.begin())
1813 llvm::sys::printArg(OS, *I,
true);
1818bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1820 using namespace llvm::sys;
1821 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1822 "Only knows about .crash files on Darwin");
1827 path::home_directory(CrashDiagDir);
1828 if (CrashDiagDir.starts_with(
"/var/root"))
1830 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1838 fs::file_status FileStatus;
1839 TimePoint<> LastAccessTime;
1843 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1844 File != FileEnd && !EC;
File.increment(EC)) {
1848 if (fs::status(
File->path(), FileStatus))
1850 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1851 llvm::MemoryBuffer::getFile(
File->path());
1856 StringRef
Data = CrashFile.get()->getBuffer();
1857 if (!
Data.starts_with(
"Process:"))
1860 size_t ParentProcPos =
Data.find(
"Parent Process:");
1861 if (ParentProcPos == StringRef::npos)
1863 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1864 if (LineEnd == StringRef::npos)
1866 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1867 int OpenBracket = -1, CloseBracket = -1;
1868 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1869 if (ParentProcess[i] ==
'[')
1871 if (ParentProcess[i] ==
']')
1877 if (OpenBracket < 0 || CloseBracket < 0 ||
1878 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1879 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1889 const auto FileAccessTime = FileStatus.getLastModificationTime();
1890 if (FileAccessTime > LastAccessTime) {
1891 CrashFilePath.assign(
File->path());
1892 LastAccessTime = FileAccessTime;
1897 if (!CrashFilePath.empty()) {
1898 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1908 "\n********************\n\n"
1909 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1910 "Preprocessed source(s) and associated run script(s) are located at:";
1918 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1922 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1923 Level = llvm::StringSwitch<unsigned>(A->getValue())
1925 .Case(
"compiler", 1)
1937 ArgStringList SavedTemps;
1939 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1940 if (!IsLLD || Level < 2)
1947 SavedTemps = std::move(
C.getTempFiles());
1948 assert(!
C.getTempFiles().size());
1965 C.initCompilationForDiagnostics();
1971 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1972 StringRef ReproduceOption =
1973 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1976 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1980 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1982 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1983 Diag(clang::diag::note_drv_command_failed_diag_msg)
1984 <<
"\n\n********************";
1986 Report->TemporaryFiles.push_back(TmpName);
1994 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1995 bool IgnoreInput =
false;
2001 }
else if (!strcmp(it->second->getValue(),
"-")) {
2002 Diag(clang::diag::note_drv_command_failed_diag_msg)
2003 <<
"Error generating preprocessed source(s) - "
2004 "ignoring input from stdin.";
2009 it = Inputs.erase(it);
2016 if (Inputs.empty()) {
2017 Diag(clang::diag::note_drv_command_failed_diag_msg)
2018 <<
"Error generating preprocessed source(s) - "
2019 "no preprocessable inputs.";
2025 llvm::StringSet<> ArchNames;
2026 for (
const Arg *A :
C.getArgs()) {
2027 if (A->getOption().matches(options::OPT_arch)) {
2028 StringRef ArchName = A->getValue();
2029 ArchNames.insert(ArchName);
2032 if (ArchNames.size() > 1) {
2033 Diag(clang::diag::note_drv_command_failed_diag_msg)
2034 <<
"Error generating preprocessed source(s) - cannot generate "
2035 "preprocessed source with multiple -arch options.";
2041 const ToolChain &TC =
C.getDefaultToolChain();
2042 if (TC.
getTriple().isOSBinFormatMachO())
2051 Diag(clang::diag::note_drv_command_failed_diag_msg)
2052 <<
"Error generating preprocessed source(s).";
2058 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2061 if (!FailingCommands.empty()) {
2062 Diag(clang::diag::note_drv_command_failed_diag_msg)
2063 <<
"Error generating preprocessed source(s).";
2067 const ArgStringList &TempFiles =
C.getTempFiles();
2068 if (TempFiles.empty()) {
2069 Diag(clang::diag::note_drv_command_failed_diag_msg)
2070 <<
"Error generating preprocessed source(s).";
2078 for (
const char *TempFile : TempFiles) {
2079 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2081 Report->TemporaryFiles.push_back(TempFile);
2082 if (ReproCrashFilename.empty()) {
2083 ReproCrashFilename = TempFile;
2084 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2086 if (StringRef(TempFile).ends_with(
".cache")) {
2089 VFS = llvm::sys::path::filename(TempFile);
2090 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2094 for (
const char *TempFile : SavedTemps)
2095 C.addTempFile(TempFile);
2101 llvm::sys::path::replace_extension(Script,
"sh");
2103 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2104 llvm::sys::fs::FA_Write,
2105 llvm::sys::fs::OF_Text);
2107 Diag(clang::diag::note_drv_command_failed_diag_msg)
2108 <<
"Error generating run script: " << Script <<
" " << EC.message();
2111 <<
"# Driver args: ";
2113 ScriptOS <<
"# Original command: ";
2114 Cmd.Print(ScriptOS,
"\n",
true);
2115 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
2116 if (!AdditionalInformation.empty())
2117 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2120 Report->TemporaryFiles.push_back(std::string(Script));
2121 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2125 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2127 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2128 Diag(clang::diag::note_drv_command_failed_diag_msg)
2129 << ReproCrashFilename.str();
2131 llvm::sys::path::append(CrashDiagDir,
Name);
2132 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2133 Diag(clang::diag::note_drv_command_failed_diag_msg)
2134 <<
"Crash backtrace is located in";
2135 Diag(clang::diag::note_drv_command_failed_diag_msg)
2136 << CrashDiagDir.str();
2137 Diag(clang::diag::note_drv_command_failed_diag_msg)
2138 <<
"(choose the .crash file that corresponds to your crash)";
2142 Diag(clang::diag::note_drv_command_failed_diag_msg)
2143 <<
"\n\n********************";
2151 if (
Cmd.getResponseFileSupport().ResponseKind ==
2153 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
2154 Cmd.getArguments()))
2158 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
2164 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2165 if (
C.getArgs().hasArg(options::OPT_v))
2166 C.getJobs().Print(llvm::errs(),
"\n",
true);
2168 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2178 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2179 C.getJobs().Print(llvm::errs(),
"\n",
true);
2188 for (
auto &Job :
C.getJobs())
2189 setUpResponseFiles(
C, Job);
2191 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2194 if (FailingCommands.empty())
2200 for (
const auto &CmdPair : FailingCommands) {
2201 int CommandRes = CmdPair.first;
2202 const Command *FailingCommand = CmdPair.second;
2207 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2211 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2216 if (CommandRes == EX_IOERR) {
2233 Diag(clang::diag::err_drv_command_signalled)
2236 Diag(clang::diag::err_drv_command_failed)
2244 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2246 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2260 const ToolChain &TC =
C.getDefaultToolChain();
2264 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2267 OS <<
"Thread model: " << A->getValue();
2273 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2278 if (!llvm::cl::getCompilerBuildConfig().empty())
2279 llvm::cl::printBuildConfig(OS);
2282 for (
auto ConfigFile : ConfigFiles)
2283 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2296 if (PassedFlags ==
"")
2300 std::vector<std::string> SuggestedCompletions;
2301 std::vector<std::string> Flags;
2313 const bool HasSpace = PassedFlags.ends_with(
",");
2317 StringRef TargetFlags = PassedFlags;
2318 while (TargetFlags !=
"") {
2320 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2321 Flags.push_back(std::string(CurFlag));
2326 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2329 const llvm::opt::OptTable &Opts =
getOpts();
2331 Cur = Flags.at(Flags.size() - 1);
2333 if (Flags.size() >= 2) {
2334 Prev = Flags.at(Flags.size() - 2);
2335 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2338 if (SuggestedCompletions.empty())
2339 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2346 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2347 llvm::outs() <<
'\n';
2353 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2357 SuggestedCompletions = Opts.findByPrefix(
2358 Cur, VisibilityMask,
2365 if (S.starts_with(Cur))
2366 SuggestedCompletions.push_back(std::string(S));
2373 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2374 if (
int X = A.compare_insensitive(B))
2376 return A.compare(B) > 0;
2379 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2386 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2387 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2391 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2394 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2398 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2403 if (
C.getArgs().hasArg(options::OPT_help) ||
2404 C.getArgs().hasArg(options::OPT__help_hidden)) {
2405 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2409 if (
C.getArgs().hasArg(options::OPT__version)) {
2415 if (
C.getArgs().hasArg(options::OPT_v) ||
2416 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2417 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2418 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2419 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2421 SuppressMissingInputWarning =
true;
2424 if (
C.getArgs().hasArg(options::OPT_v)) {
2426 llvm::errs() <<
"System configuration file directory: "
2429 llvm::errs() <<
"User configuration file directory: "
2433 const ToolChain &TC =
C.getDefaultToolChain();
2435 if (
C.getArgs().hasArg(options::OPT_v))
2438 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2443 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2444 llvm::outs() <<
"programs: =";
2445 bool separator =
false;
2449 llvm::outs() << llvm::sys::EnvPathSeparator;
2450 llvm::outs() <<
Path;
2455 llvm::outs() << llvm::sys::EnvPathSeparator;
2456 llvm::outs() <<
Path;
2459 llvm::outs() <<
"\n";
2462 StringRef sysroot =
C.getSysRoot();
2466 llvm::outs() << llvm::sys::EnvPathSeparator;
2469 llvm::outs() << sysroot <<
Path.substr(1);
2471 llvm::outs() <<
Path;
2473 llvm::outs() <<
"\n";
2477 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2483 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2484 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2485 llvm::outs() << *RuntimePath <<
'\n';
2491 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2493 for (std::size_t I = 0; I != Flags.size(); I += 2)
2494 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2500 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2501 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2505 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2506 StringRef ProgName = A->getValue();
2509 if (! ProgName.empty())
2512 llvm::outs() <<
"\n";
2516 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2517 StringRef PassedFlags = A->getValue();
2522 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2536 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2539 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2545 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2552 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2555 std::set<llvm::StringRef> SortedFlags;
2556 for (
const auto &FlagEntry : ExpandedFlags)
2557 SortedFlags.insert(FlagEntry.getKey());
2558 for (
auto Flag : SortedFlags)
2559 llvm::outs() << Flag <<
'\n';
2563 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2566 llvm::outs() <<
".\n";
2569 assert(Suffix.front() ==
'/');
2570 llvm::outs() << Suffix.substr(1) <<
"\n";
2576 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2581 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2583 llvm::outs() << Triple.getTriple() <<
"\n";
2587 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2588 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2605 std::map<Action *, unsigned> &Ids,
2607 if (
auto It = Ids.find(A); It != Ids.end())
2611 llvm::raw_string_ostream os(str);
2613 auto getSibIndent = [](
int K) -> Twine {
2617 Twine SibIndent = Indent + getSibIndent(Kind);
2621 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2623 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2624 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2625 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2626 bool IsFirst =
true;
2627 OA->doOnEachDependence(
2629 assert(TC &&
"Unknown host toolchain");
2641 os <<
":" << BoundArch;
2644 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2652 const char *Prefix =
"{";
2653 for (
Action *PreRequisite : *AL) {
2654 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2665 std::string offload_str;
2666 llvm::raw_string_ostream offload_os(offload_str);
2667 if (!isa<OffloadAction>(A)) {
2670 offload_os <<
", (" << S;
2677 auto getSelfIndent = [](
int K) -> Twine {
2681 unsigned Id = Ids.size();
2683 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2692 std::map<Action *, unsigned> Ids;
2693 for (
Action *A :
C.getActions())
2700 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2701 isa<AssembleJobAction>(A))
2709 DerivedArgList &Args =
C.getArgs();
2711 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2714 llvm::StringSet<> ArchNames;
2716 for (Arg *A : Args) {
2717 if (A->getOption().matches(options::OPT_arch)) {
2720 llvm::Triple::ArchType Arch =
2722 if (Arch == llvm::Triple::UnknownArch) {
2723 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2728 if (ArchNames.insert(A->getValue()).second)
2729 Archs.push_back(A->getValue());
2743 for (
Action* Act : SingleActions) {
2751 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2755 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2760 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2761 Actions.append(Inputs.begin(), Inputs.end());
2763 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2766 Arg *A = Args.getLastArg(options::OPT_g_Group);
2767 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2768 !A->getOption().matches(options::OPT_gstabs);
2776 if (Act->getType() == types::TY_Image) {
2778 Inputs.push_back(Actions.back());
2785 if (Args.hasArg(options::OPT_verify_debug_info)) {
2786 Action* LastAction = Actions.back();
2789 LastAction, types::TY_Nothing));
2808 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2809 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2821 std::string Nearest;
2822 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2823 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2824 <<
Value << Nearest;
2863 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2866 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2874 return types::TY_CXXUHeader;
2876 return types::TY_CXXSHeader;
2880 llvm_unreachable(
"should not be called in this case");
2882 return types::TY_CXXHUHeader;
2888 const llvm::opt::OptTable &Opts =
getOpts();
2892 types::ID InputType = types::TY_Nothing;
2893 Arg *InputTypeArg =
nullptr;
2896 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2897 options::OPT__SLASH_TP)) {
2898 InputTypeArg = TCTP;
2899 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2904 bool ShowNote =
false;
2906 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2908 Diag(clang::diag::warn_drv_overriding_option)
2909 <<
Previous->getSpelling() << A->getSpelling();
2915 Diag(clang::diag::note_drv_t_option_is_global);
2920 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2921 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2922 if (LastXArg && LastInputArg &&
2923 LastInputArg->getIndex() < LastXArg->getIndex())
2924 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2927 for (Arg *A : Args) {
2928 if (A->getOption().
getKind() == Option::InputClass) {
2929 const char *
Value = A->getValue();
2933 if (InputType == types::TY_Nothing) {
2936 InputTypeArg->claim();
2939 if (memcmp(
Value,
"-", 2) == 0) {
2941 Ty = types::TY_Fortran;
2943 Ty = types::TY_HLSL;
2952 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2953 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2954 : clang::diag::err_drv_unknown_stdin_type);
2963 if (
const char *Ext = strrchr(
Value,
'.'))
2972 Ty = types::TY_Object;
2983 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2984 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2985 << getTypeName(OldTy) << getTypeName(Ty);
2990 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2991 Ty == types::TY_Object)
2992 Ty = types::TY_LLVM_BC;
3000 if (Ty != types::TY_Object) {
3001 if (Args.hasArg(options::OPT_ObjC))
3002 Ty = types::TY_ObjC;
3003 else if (Args.hasArg(options::OPT_ObjCXX))
3004 Ty = types::TY_ObjCXX;
3011 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3015 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3016 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3019 const char *Ext = strrchr(
Value,
'.');
3021 Ty = types::TY_Object;
3025 InputTypeArg->claim();
3029 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3030 Args.hasArgNoClaim(options::OPT_hipstdpar))
3034 Inputs.push_back(std::make_pair(Ty, A));
3036 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3037 StringRef
Value = A->getValue();
3040 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3041 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3044 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3045 StringRef
Value = A->getValue();
3048 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3049 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3055 Inputs.push_back(std::make_pair(types::TY_Object, A));
3057 }
else if (A->getOption().matches(options::OPT_x)) {
3066 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3067 InputType = types::TY_Object;
3074 }
else if (A->getOption().getID() == options::OPT_U) {
3075 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3076 StringRef Val = A->getValue(0);
3077 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3079 Diag(diag::warn_slash_u_filename) << Val;
3080 Diag(diag::note_use_dashdash);
3084 if (
CCCIsCPP() && Inputs.empty()) {
3088 Inputs.push_back(std::make_pair(types::TY_C, A));
3095class OffloadingActionBuilder final {
3097 bool IsValid =
false;
3103 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3106 std::map<Action *, const Arg *> HostActionToInputArgMap;
3109 class DeviceActionBuilder {
3113 enum ActionBuilderReturnCode {
3132 DerivedArgList &Args;
3141 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3144 :
C(
C), Args(Args), Inputs(Inputs),
3145 AssociatedOffloadKind(AssociatedOffloadKind) {}
3146 virtual ~DeviceActionBuilder() {}
3151 virtual ActionBuilderReturnCode
3155 return ABRT_Inactive;
3160 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
3161 return ABRT_Inactive;
3165 virtual void appendTopLevelActions(
ActionList &AL) {}
3168 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3181 virtual bool canUseBundlerUnbundler()
const {
return false; }
3185 bool isValid() {
return !ToolChains.empty(); }
3189 return AssociatedOffloadKind;
3195 class CudaActionBuilderBase :
public DeviceActionBuilder {
3199 bool CompileHostOnly =
false;
3200 bool CompileDeviceOnly =
false;
3202 bool EmitAsm =
false;
3212 TargetID(
const char *
ID) :
ID(
ID) {}
3213 operator const char *() {
return ID; }
3214 operator StringRef() {
return StringRef(
ID); }
3223 Action *CudaFatBinary =
nullptr;
3226 bool IsActive =
false;
3229 bool Relocatable =
false;
3232 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3238 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
3241 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3242 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3244 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3245 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3246 options::OPT_fno_gpu_rdc,
false);
3249 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3256 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3257 assert(!GpuArchList.empty() &&
3258 "We should have at least one GPU architecture.");
3262 if (!(IA->getType() == types::TY_CUDA ||
3263 IA->getType() == types::TY_HIP ||
3264 IA->getType() == types::TY_PP_HIP)) {
3267 return ABRT_Inactive;
3274 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3276 if (CompileHostOnly)
3277 return ABRT_Success;
3280 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3281 : types::TY_CUDA_DEVICE;
3282 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3283 CudaDeviceActions.push_back(
3284 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3287 return ABRT_Success;
3291 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3295 if (UA->getType() == types::TY_Object && !Relocatable)
3296 return ABRT_Inactive;
3298 CudaDeviceActions.clear();
3299 auto *IA = cast<InputAction>(UA->getInputs().back());
3300 std::string
FileName = IA->getInputArg().getAsString(Args);
3306 const StringRef LibFileExt =
".lib";
3307 if (IA->getType() == types::TY_Object &&
3308 (!llvm::sys::path::has_extension(
FileName) ||
3310 llvm::sys::path::extension(
FileName).drop_front()) !=
3312 llvm::sys::path::extension(
FileName) == LibFileExt))
3313 return ABRT_Inactive;
3315 for (
auto Arch : GpuArchList) {
3316 CudaDeviceActions.push_back(UA);
3317 UA->registerDependentActionInfo(ToolChains[0], Arch,
3318 AssociatedOffloadKind);
3321 return ABRT_Success;
3324 return IsActive ? ABRT_Success : ABRT_Inactive;
3327 void appendTopLevelActions(
ActionList &AL)
override {
3329 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3331 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3336 if (CudaFatBinary) {
3337 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3338 CudaDeviceActions.clear();
3339 CudaFatBinary =
nullptr;
3343 if (CudaDeviceActions.empty())
3349 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3350 "Expecting one action per GPU architecture.");
3351 assert(ToolChains.size() == 1 &&
3352 "Expecting to have a single CUDA toolchain.");
3353 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I)
3354 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3356 CudaDeviceActions.clear();
3361 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3363 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3381 assert(HostTC &&
"No toolchain for host compilation.");
3383 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3387 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3392 ToolChains.push_back(
3397 CompileHostOnly =
C.getDriver().offloadHostOnly();
3398 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3399 EmitAsm = Args.getLastArg(options::OPT_S);
3402 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3403 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3404 options::OPT_no_offload_arch_EQ)) {
3405 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3410 std::set<StringRef> GpuArchs;
3412 for (Arg *A : Args) {
3413 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3414 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3418 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3419 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3422 }
else if (ArchStr ==
"native") {
3423 const ToolChain &TC = *ToolChains.front();
3424 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3427 << llvm::Triple::getArchTypeName(TC.
getArch())
3428 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3432 for (
auto GPU : *GPUsOrErr) {
3433 GpuArchs.insert(Args.MakeArgString(GPU));
3436 ArchStr = getCanonicalOffloadArch(ArchStr);
3437 if (ArchStr.empty()) {
3439 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3440 GpuArchs.insert(ArchStr);
3441 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3442 GpuArchs.erase(ArchStr);
3444 llvm_unreachable(
"Unexpected option.");
3450 if (ConflictingArchs) {
3451 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3452 << ConflictingArchs->first << ConflictingArchs->second;
3453 C.setContainsError();
3458 for (
auto Arch : GpuArchs)
3459 GpuArchList.push_back(Arch.data());
3464 if (GpuArchList.empty()) {
3465 if (ToolChains.front()->getTriple().isSPIRV()) {
3466 if (ToolChains.front()->getTriple().getVendor() == llvm::Triple::AMD)
3467 GpuArchList.push_back(OffloadArch::AMDGCNSPIRV);
3469 GpuArchList.push_back(OffloadArch::Generic);
3471 GpuArchList.push_back(DefaultOffloadArch);
3481 class CudaActionBuilder final :
public CudaActionBuilderBase {
3483 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3485 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3486 DefaultOffloadArch = OffloadArch::CudaDefault;
3489 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3492 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3498 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3500 const std::set<StringRef> &GpuArchs)
override {
3501 return std::nullopt;
3504 ActionBuilderReturnCode
3507 PhasesTy &Phases)
override {
3509 return ABRT_Inactive;
3513 if (CudaDeviceActions.empty())
3514 return ABRT_Success;
3516 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3517 "Expecting one action per GPU architecture.");
3518 assert(!CompileHostOnly &&
3519 "Not expecting CUDA actions in host-only compilation.");
3529 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3532 for (
auto Ph : Phases) {
3537 if (Ph > FinalPhase)
3540 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3550 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3554 Action *AssembleAction = CudaDeviceActions[I];
3555 assert(AssembleAction->
getType() == types::TY_Object);
3556 assert(AssembleAction->
getInputs().size() == 1);
3564 DeviceActions.push_back(
3570 if (!DeviceActions.empty()) {
3572 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3574 if (!CompileDeviceOnly) {
3575 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3579 CudaFatBinary =
nullptr;
3584 CudaDeviceActions.clear();
3588 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3593 return ABRT_Success;
3597 "instructions should only occur "
3598 "before the backend phase!");
3601 for (
Action *&A : CudaDeviceActions)
3602 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3604 return ABRT_Success;
3609 class HIPActionBuilder final :
public CudaActionBuilderBase {
3617 std::optional<bool> BundleOutput;
3618 std::optional<bool> EmitReloc;
3623 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3625 DefaultOffloadArch = OffloadArch::HIPDefault;
3627 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3628 options::OPT_fno_hip_emit_relocatable)) {
3629 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3630 options::OPT_fno_hip_emit_relocatable,
false);
3634 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3635 <<
"-fhip-emit-relocatable"
3639 if (!CompileDeviceOnly) {
3640 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3641 <<
"-fhip-emit-relocatable"
3642 <<
"--cuda-device-only";
3647 if (Args.hasArg(options::OPT_gpu_bundle_output,
3648 options::OPT_no_gpu_bundle_output))
3649 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3650 options::OPT_no_gpu_bundle_output,
true) &&
3651 (!EmitReloc || !*EmitReloc);
3654 bool canUseBundlerUnbundler()
const override {
return true; }
3656 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3657 llvm::StringMap<bool> Features;
3661 (IdStr ==
"amdgcnspirv")
3662 ? llvm::Triple(
"spirv64-amd-amdhsa")
3666 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3667 C.setContainsError();
3671 return Args.MakeArgStringRef(CanId);
3674 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3676 const std::set<StringRef> &GpuArchs)
override {
3680 ActionBuilderReturnCode
3683 PhasesTy &Phases)
override {
3685 return ABRT_Inactive;
3691 if (CudaDeviceActions.empty())
3692 return ABRT_Success;
3695 CudaDeviceActions.size() == GpuArchList.size()) &&
3696 "Expecting one action per GPU architecture.");
3697 assert(!CompileHostOnly &&
3698 "Not expecting HIP actions in host-only compilation.");
3700 bool ShouldLink = !EmitReloc || !*EmitReloc;
3703 !EmitAsm && ShouldLink) {
3709 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3710 if (
C.getDriver().isUsingOffloadLTO()) {
3714 AL.push_back(CudaDeviceActions[I]);
3717 CudaDeviceActions[I] =
3724 if (ToolChains.front()->getTriple().isSPIRV()) {
3727 types::ID Output = Args.hasArg(options::OPT_S)
3729 : types::TY_LLVM_BC;
3735 AssociatedOffloadKind);
3736 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3738 AssociatedOffloadKind);
3739 AL.push_back(AssembleAction);
3742 CudaDeviceActions[I] =
3753 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3754 AssociatedOffloadKind);
3756 DDep, CudaDeviceActions[I]->getType());
3759 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3762 types::TY_HIP_FATBIN);
3764 if (!CompileDeviceOnly) {
3765 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3766 AssociatedOffloadKind);
3769 CudaFatBinary =
nullptr;
3774 CudaDeviceActions.clear();
3777 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3780 return ABRT_Success;
3786 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3787 auto LI = DeviceLinkerInputs.begin();
3788 for (
auto *A : CudaDeviceActions) {
3795 CudaDeviceActions.clear();
3796 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3800 for (
Action *&A : CudaDeviceActions)
3801 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3802 AssociatedOffloadKind);
3804 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3806 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3808 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3809 AssociatedOffloadKind);
3811 DDep, CudaDeviceActions[I]->getType());
3815 CudaDeviceActions.clear();
3818 return (CompileDeviceOnly &&
3819 (CurPhase == FinalPhase ||
3825 void appendLinkDeviceActions(
ActionList &AL)
override {
3826 if (DeviceLinkerInputs.size() == 0)
3829 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3830 "Linker inputs and GPU arch list sizes do not match.");
3836 for (
auto &LI : DeviceLinkerInputs) {
3838 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3842 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3846 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3847 GpuArchList[I], AssociatedOffloadKind);
3849 DeviceLinkDeps, DeviceLinkAction->getType()));
3852 DeviceLinkerInputs.clear();
3855 if (Args.hasArg(options::OPT_emit_llvm)) {
3864 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3867 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3868 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3869 AssociatedOffloadKind);
3872 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3878 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3894 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3902 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3905 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3913 unsigned ValidBuilders = 0u;
3914 unsigned ValidBuildersSupportingBundling = 0u;
3915 for (
auto *SB : SpecializedBuilders) {
3916 IsValid = IsValid && !SB->initialize();
3919 if (SB->isValid()) {
3921 if (SB->canUseBundlerUnbundler())
3922 ++ValidBuildersSupportingBundling;
3926 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3929 ~OffloadingActionBuilder() {
3930 for (
auto *SB : SpecializedBuilders)
3935 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3936 assert(HostAction &&
"Invalid host action");
3937 assert(InputArg &&
"Invalid input argument");
3938 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3939 assert(
Loc->second == InputArg &&
3940 "host action mapped to multiple input arguments");
3949 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3951 DeviceActionBuilder::PhasesTy &Phases) {
3955 if (SpecializedBuilders.empty())
3958 assert(HostAction &&
"Invalid host action!");
3959 recordHostAction(HostAction, InputArg);
3964 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3965 unsigned InactiveBuilders = 0u;
3966 unsigned IgnoringBuilders = 0u;
3967 for (
auto *SB : SpecializedBuilders) {
3968 if (!SB->isValid()) {
3973 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3978 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3983 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3984 OffloadKind |= SB->getAssociatedOffloadKind();
3989 if (IgnoringBuilders &&
3990 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4007 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4008 const Arg *InputArg) {
4012 recordHostAction(HostAction, InputArg);
4020 if (CanUseBundler && isa<InputAction>(HostAction) &&
4021 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4023 HostAction->
getType() == types::TY_PP_HIP)) {
4024 auto UnbundlingHostAction =
4029 HostAction = UnbundlingHostAction;
4030 recordHostAction(HostAction, InputArg);
4033 assert(HostAction &&
"Invalid host action!");
4036 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4037 for (
auto *SB : SpecializedBuilders) {
4041 auto RetCode = SB->addDeviceDependences(HostAction);
4045 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4046 "Host dependence not expected to be ignored.!");
4050 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4051 OffloadKind |= SB->getAssociatedOffloadKind();
4056 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4066 const Arg *InputArg) {
4068 recordHostAction(HostAction, InputArg);
4072 for (
auto *SB : SpecializedBuilders) {
4075 SB->appendTopLevelActions(OffloadAL);
4082 if (CanUseBundler && HostAction &&
4083 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4085 OffloadAL.push_back(HostAction);
4089 assert(HostAction == AL.back() &&
"Host action not in the list??");
4091 recordHostAction(HostAction, InputArg);
4092 AL.back() = HostAction;
4094 AL.append(OffloadAL.begin(), OffloadAL.end());
4104 void appendDeviceLinkActions(
ActionList &AL) {
4105 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4108 SB->appendLinkDeviceActions(AL);
4112 Action *makeHostLinkAction() {
4115 appendDeviceLinkActions(DeviceAL);
4116 if (DeviceAL.empty())
4121 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4124 HA = SB->appendLinkHostActions(DeviceAL);
4141 for (
auto *SB : SpecializedBuilders) {
4145 SB->appendLinkDependences(DDeps);
4149 unsigned ActiveOffloadKinds = 0u;
4150 for (
auto &I : InputArgToOffloadKindMap)
4151 ActiveOffloadKinds |= I.second;
4163 for (
auto *A : HostAction->
inputs()) {
4164 auto ArgLoc = HostActionToInputArgMap.find(A);
4165 if (ArgLoc == HostActionToInputArgMap.end())
4167 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4168 if (OFKLoc == InputArgToOffloadKindMap.end())
4180 nullptr, ActiveOffloadKinds);
4186void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4187 const InputList &Inputs,
4191 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4192 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4193 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4194 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4195 Args.eraseArg(options::OPT__SLASH_Yc);
4196 Args.eraseArg(options::OPT__SLASH_Yu);
4197 YcArg = YuArg =
nullptr;
4199 if (YcArg && Inputs.size() > 1) {
4200 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4201 Args.eraseArg(options::OPT__SLASH_Yc);
4209 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4210 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4211 Args.AddFlagArg(
nullptr,
4212 getOpts().getOption(options::OPT_frtlib_add_rpath));
4215 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4216 Diag(clang::diag::err_drv_emit_llvm_link);
4217 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4219 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4220 .starts_with_insensitive(
"lld"))
4221 Diag(clang::diag::err_drv_lto_without_lld);
4227 if (!Args.hasArg(options::OPT_dumpdir)) {
4228 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4229 Arg *Arg = Args.MakeSeparateArg(
4230 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4232 (FinalOutput ? FinalOutput->getValue()
4244 Args.eraseArg(options::OPT__SLASH_Fp);
4245 Args.eraseArg(options::OPT__SLASH_Yc);
4246 Args.eraseArg(options::OPT__SLASH_Yu);
4247 YcArg = YuArg =
nullptr;
4250 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4251 for (
auto &I : Inputs) {
4253 const Arg *InputArg = I.second;
4258 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4262 if (InitialPhase > FinalPhase) {
4263 if (InputArg->isClaimed())
4270 if (Args.hasArg(options::OPT_Qunused_arguments))
4276 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4277 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4281 (Args.getLastArg(options::OPT__SLASH_EP,
4282 options::OPT__SLASH_P) ||
4283 Args.getLastArg(options::OPT_E) ||
4284 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4286 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4287 << InputArg->getAsString(Args) << !!FinalPhaseArg
4288 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4290 Diag(clang::diag::warn_drv_input_file_unused)
4291 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4293 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4306 Actions.push_back(ClangClPch);
4318 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4319 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4325 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4327 if (!SuppressMissingInputWarning && Inputs.empty()) {
4328 Diag(clang::diag::err_drv_no_input_files);
4333 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4334 StringRef
V = A->getValue();
4335 if (Inputs.size() > 1 && !
V.empty() &&
4336 !llvm::sys::path::is_separator(
V.back())) {
4338 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4339 << A->getSpelling() <<
V;
4340 Args.eraseArg(options::OPT__SLASH_Fo);
4345 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4346 StringRef
V = A->getValue();
4347 if (Inputs.size() > 1 && !
V.empty() &&
4348 !llvm::sys::path::is_separator(
V.back())) {
4350 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4351 << A->getSpelling() <<
V;
4352 Args.eraseArg(options::OPT__SLASH_Fa);
4357 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4358 if (A->getValue()[0] ==
'\0') {
4360 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4361 Args.eraseArg(options::OPT__SLASH_o);
4365 handleArguments(
C, Args, Inputs, Actions);
4367 bool UseNewOffloadingDriver =
4370 Args.hasFlag(options::OPT_foffload_via_llvm,
4371 options::OPT_fno_offload_via_llvm,
false) ||
4372 Args.hasFlag(options::OPT_offload_new_driver,
4373 options::OPT_no_offload_new_driver,
4377 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4378 !UseNewOffloadingDriver
4379 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4387 for (
auto &I : Inputs) {
4389 const Arg *InputArg = I.second;
4402 CUID = CUIDOpts.
getCUID(InputArg->getValue(), Args);
4403 cast<InputAction>(Current)->setId(CUID);
4408 if (!UseNewOffloadingDriver)
4409 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4415 if (!UseNewOffloadingDriver)
4416 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4417 Current, InputArg, Phase, PL.back(), FullPL);
4423 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4426 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4427 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4429 LinkerInputs.push_back(Current);
4439 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4440 MergerInputs.push_back(Current);
4458 if (NewCurrent == Current)
4461 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4464 Current = NewCurrent;
4468 if (UseNewOffloadingDriver)
4472 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4476 if (Current->getType() == types::TY_Nothing)
4482 Actions.push_back(Current);
4485 if (!UseNewOffloadingDriver)
4486 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4488 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4494 if (LinkerInputs.empty()) {
4497 if (!UseNewOffloadingDriver)
4498 OffloadBuilder->appendDeviceLinkActions(Actions);
4501 if (!LinkerInputs.empty()) {
4502 if (!UseNewOffloadingDriver)
4503 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4504 LinkerInputs.push_back(Wrapper);
4509 }
else if (UseNewOffloadingDriver ||
4510 Args.hasArg(options::OPT_offload_link)) {
4517 if (!UseNewOffloadingDriver)
4518 LA = OffloadBuilder->processHostLinkAction(LA);
4519 Actions.push_back(LA);
4523 if (!MergerInputs.empty())
4527 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4534 for (
auto &I : Inputs) {
4536 const Arg *InputArg = I.second;
4541 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4542 InputType == types::TY_Asm)
4547 for (
auto Phase : PhaseList) {
4551 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4556 if (InputType == types::TY_Object)
4563 assert(Phase == PhaseList.back() &&
4564 "merging must be final compilation step.");
4565 MergerInputs.push_back(Current);
4574 Actions.push_back(Current);
4578 if (!MergerInputs.empty())
4583 for (
auto Opt : {options::OPT_print_supported_cpus,
4584 options::OPT_print_supported_extensions,
4585 options::OPT_print_enabled_extensions}) {
4592 if (Arg *A = Args.getLastArg(Opt)) {
4593 if (Opt == options::OPT_print_supported_extensions &&
4594 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4595 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4596 !
C.getDefaultToolChain().getTriple().isARM()) {
4597 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4598 <<
"--print-supported-extensions";
4601 if (Opt == options::OPT_print_enabled_extensions &&
4602 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4603 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4604 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4605 <<
"--print-enabled-extensions";
4612 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4615 for (
auto &I : Inputs)
4621 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4625 if (TC.requiresValidation(Args)) {
4626 Action *LastAction = Actions.back();
4628 LastAction, types::TY_DX_CONTAINER));
4633 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4639 const llvm::opt::DerivedArgList &Args,
4641 const llvm::Triple &Triple,
4642 bool SuppressError =
false) {
4647 if (!SuppressError && Triple.isNVPTX() &&
4649 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4650 <<
"CUDA" << ArchStr;
4652 }
else if (!SuppressError && Triple.isAMDGPU() &&
4654 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4655 <<
"HIP" << ArchStr;
4663 llvm::StringMap<bool> Features;
4669 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4670 C.setContainsError();
4682static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4684 llvm::Triple Triple) {
4685 if (!Triple.isAMDGPU())
4686 return std::nullopt;
4688 std::set<StringRef> ArchSet;
4689 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4693llvm::DenseSet<StringRef>
4696 bool SuppressError)
const {
4698 TC = &
C.getDefaultToolChain();
4701 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4702 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4703 options::OPT_no_offload_arch_EQ)) {
4704 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4706 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4708 :
"--no-offload-arch");
4711 if (KnownArchs.contains(TC))
4712 return KnownArchs.lookup(TC);
4714 llvm::DenseSet<StringRef> Archs;
4715 for (
auto *Arg :
C.getArgsForToolChain(TC,
"", Kind)) {
4718 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4719 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4720 if (Arch ==
"native" || Arch.empty()) {
4724 llvm::consumeError(GPUsOrErr.takeError());
4727 << llvm::Triple::getArchTypeName(TC->
getArch())
4728 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4732 for (
auto ArchStr : *GPUsOrErr) {
4739 C, Args, Arch, TC->
getTriple(), SuppressError);
4740 if (ArchStr.empty())
4742 Archs.insert(ArchStr);
4745 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4746 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4747 if (Arch ==
"all") {
4751 C, Args, Arch, TC->
getTriple(), SuppressError);
4752 if (ArchStr.empty())
4754 Archs.erase(ArchStr);
4760 if (
auto ConflictingArchs =
4762 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4763 << ConflictingArchs->first << ConflictingArchs->second;
4764 C.setContainsError();
4771 if (Archs.empty()) {
4777 Archs.insert(StringRef());
4780 if (
auto *Arg =
C.getArgsForToolChain(TC,
"", Kind)
4781 .getLastArg(options::OPT_march_EQ)) {
4782 Archs.insert(Arg->getValue());
4787 << llvm::Triple::getArchTypeName(TC->
getArch())
4788 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4789 }
else if (!ArchsOrErr->empty()) {
4790 for (
auto Arch : *ArchsOrErr)
4791 Archs.insert(Args.MakeArgStringRef(Arch));
4793 Archs.insert(StringRef());
4798 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4799 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4806 llvm::opt::DerivedArgList &Args,
4807 const InputTy &Input, StringRef CUID,
4808 Action *HostAction)
const {
4813 !(isa<CompileJobAction>(HostAction) ||
4827 auto TCRange =
C.getOffloadToolChains(Kind);
4828 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4829 ToolChains.push_back(TI->second);
4831 if (ToolChains.empty())
4835 const Arg *InputArg = Input.second;
4844 for (
const ToolChain *TC : ToolChains) {
4848 for (StringRef Arch : Sorted) {
4849 TCAndArchs.push_back(std::make_pair(TC, Arch));
4850 DeviceActions.push_back(
4851 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4855 if (DeviceActions.empty())
4861 HostAction->
getType() != types::TY_Nothing &&
4871 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4880 auto TCAndArch = TCAndArchs.begin();
4881 for (
Action *&A : DeviceActions) {
4882 if (A->
getType() == types::TY_Nothing)
4890 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4892 HostAction->
getType() != types::TY_Nothing) {
4899 TCAndArch->second.data(), Kind);
4901 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4910 for (
Action *&A : DeviceActions) {
4911 if ((A->
getType() != types::TY_Object &&
4912 A->
getType() != types::TY_LTO_BC) ||
4914 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4920 auto TCAndArch = TCAndArchs.begin();
4921 for (
Action *A : DeviceActions) {
4922 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4924 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4929 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4931 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4939 bool ShouldBundleHIP =
4941 Args.hasFlag(options::OPT_gpu_bundle_output,
4942 options::OPT_no_gpu_bundle_output,
true) &&
4943 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4944 !llvm::any_of(OffloadActions,
4951 if (OffloadActions.empty())
4956 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4960 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4964 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4969 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4978 nullptr,
C.getActiveOffloadKinds());
4987 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4988 return A->
getType() == types::TY_Nothing;
4989 }) && isa<CompileJobAction>(HostAction);
4992 nullptr, SingleDeviceOutput ? DDep : DDeps);
4993 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4999 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5009 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5015 llvm_unreachable(
"link action invalid here.");
5017 llvm_unreachable(
"ifsmerge action invalid here.");
5022 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5023 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5024 OutputTy = types::TY_Dependencies;
5029 if (!Args.hasFlag(options::OPT_frewrite_includes,
5030 options::OPT_fno_rewrite_includes,
false) &&
5031 !Args.hasFlag(options::OPT_frewrite_imports,
5032 options::OPT_fno_rewrite_imports,
false) &&
5033 !Args.hasFlag(options::OPT_fdirectives_only,
5034 options::OPT_fno_directives_only,
false) &&
5038 "Cannot preprocess this input type!");
5044 if (Args.hasArg(options::OPT_extract_api))
5051 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
5052 !Args.getLastArg(options::OPT__precompile))
5057 "Cannot precompile this input type!");
5061 const char *ModName =
nullptr;
5062 if (OutputTy == types::TY_PCH) {
5063 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5064 ModName = A->getValue();
5066 OutputTy = types::TY_ModuleFile;
5069 if (Args.hasArg(options::OPT_fsyntax_only)) {
5071 OutputTy = types::TY_Nothing;
5077 if (Args.hasArg(options::OPT_fsyntax_only))
5079 if (Args.hasArg(options::OPT_rewrite_objc))
5081 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5083 types::TY_RewrittenLegacyObjC);
5084 if (Args.hasArg(options::OPT__analyze))
5086 if (Args.hasArg(options::OPT_emit_ast))
5088 if (Args.hasArg(options::OPT_emit_cir))
5090 if (Args.hasArg(options::OPT_module_file_info))
5092 if (Args.hasArg(options::OPT_verify_pch))
5094 if (Args.hasArg(options::OPT_extract_api))
5101 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5102 !Args.hasArg(options::OPT_emit_llvm))
5103 Output = types::TY_PP_Asm;
5104 else if (Args.hasArg(options::OPT_S))
5105 Output = types::TY_LTO_IR;
5107 Output = types::TY_LTO_BC;
5112 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5115 if (Args.hasArg(options::OPT_emit_llvm) ||
5120 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5124 Args.hasArg(options::OPT_S) &&
5128 !Args.hasFlag(options::OPT_offload_new_driver,
5129 options::OPT_no_offload_new_driver,
5132 : types::TY_LLVM_BC;
5141 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5145 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5147 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5167 unsigned NumOutputs = 0;
5168 unsigned NumIfsOutputs = 0;
5169 for (
const Action *A :
C.getActions()) {
5170 if (A->
getType() != types::TY_Nothing &&
5171 A->
getType() != types::TY_DX_CONTAINER &&
5173 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5175 0 == NumIfsOutputs++) ||
5180 A->
getType() == types::TY_Nothing &&
5181 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5182 NumOutputs += A->
size();
5185 if (NumOutputs > 1) {
5186 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5187 FinalOutput =
nullptr;
5191 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5194 llvm::StringSet<> ArchNames;
5195 if (RawTriple.isOSBinFormatMachO())
5196 for (
const Arg *A :
C.getArgs())
5197 if (A->getOption().matches(options::OPT_arch))
5198 ArchNames.insert(A->getValue());
5201 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5202 for (
Action *A :
C.getActions()) {
5209 const char *LinkingOutput =
nullptr;
5210 if (isa<LipoJobAction>(A)) {
5212 LinkingOutput = FinalOutput->getValue();
5220 ArchNames.size() > 1,
5221 LinkingOutput, CachedResults,
5228 for (
auto &J :
C.getJobs())
5229 J.InProcess =
false;
5232 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
5233 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5234 Cmd.getProcessStatistics();
5238 const char *LinkingOutput =
nullptr;
5240 LinkingOutput = FinalOutput->getValue();
5241 else if (!
Cmd.getOutputFilenames().empty())
5242 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
5247 using namespace llvm;
5249 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
5250 <<
"output=" << LinkingOutput;
5251 outs() <<
", total="
5252 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5254 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5255 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5259 llvm::raw_string_ostream Out(Buffer);
5260 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
5263 llvm::sys::printArg(Out, LinkingOutput, true);
5264 Out <<
',' << ProcStat->TotalTime.count() <<
','
5265 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5269 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5270 llvm::sys::fs::OF_Append |
5271 llvm::sys::fs::OF_Text);
5276 llvm::errs() <<
"ERROR: Cannot lock file "
5277 << CCPrintStatReportFilename <<
": "
5278 << toString(L.takeError()) <<
"\n";
5289 if (Diags.hasErrorOccurred() ||
5290 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5294 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5296 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5299 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5300 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5302 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5306 return strstr(J.getCreator().getShortName(),
"assembler");
5308 for (Arg *A :
C.getArgs()) {
5312 if (!A->isClaimed()) {
5318 const Option &Opt = A->getOption();
5319 if (Opt.getKind() == Option::FlagClass) {
5320 bool DuplicateClaimed =
false;
5322 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5323 if (AA->isClaimed()) {
5324 DuplicateClaimed =
true;
5329 if (DuplicateClaimed)
5335 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5337 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5342 !
C.getActions().empty()) {
5343 Diag(diag::err_drv_unsupported_opt_for_target)
5344 << A->getSpelling() << getTargetTriple();
5346 Diag(clang::diag::warn_drv_unused_argument)
5347 << A->getAsString(
C.getArgs());
5357class ToolSelector final {
5368 bool IsHostSelector;
5379 bool CanBeCollapsed =
true) {
5381 if (Inputs.size() != 1)
5384 Action *CurAction = *Inputs.begin();
5385 if (CanBeCollapsed &&
5391 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5395 if (!IsHostSelector) {
5396 if (OA->hasSingleDeviceDependence(
true)) {
5398 OA->getSingleDeviceDependence(
true);
5399 if (CanBeCollapsed &&
5402 SavedOffloadAction.push_back(OA);
5403 return dyn_cast<JobAction>(CurAction);
5405 }
else if (OA->hasHostDependence()) {
5406 CurAction = OA->getHostDependence();
5407 if (CanBeCollapsed &&
5410 SavedOffloadAction.push_back(OA);
5411 return dyn_cast<JobAction>(CurAction);
5416 return dyn_cast<JobAction>(CurAction);
5420 bool canCollapseAssembleAction()
const {
5421 return TC.useIntegratedAs() && !SaveTemps &&
5422 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5423 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5424 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5425 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5429 bool canCollapsePreprocessorAction()
const {
5430 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5431 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5432 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5437 struct JobActionInfo final {
5447 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5449 unsigned ElementNum) {
5450 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5451 for (
unsigned I = 0; I < ElementNum; ++I)
5452 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5453 ActionInfo[I].SavedOffloadAction.end());
5469 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5471 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5472 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5473 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5474 if (!AJ || !BJ || !CJ)
5478 const Tool *
T = TC.SelectTool(*CJ);
5485 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5491 const Tool *BT = TC.SelectTool(*BJ);
5496 if (!
T->hasIntegratedAssembler())
5499 Inputs = CJ->getInputs();
5500 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5507 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5509 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5510 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5515 const Tool *
T = TC.SelectTool(*BJ);
5519 if (!
T->hasIntegratedAssembler())
5522 Inputs = BJ->getInputs();
5523 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5530 if (ActionInfo.size() < 2)
5532 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5533 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5542 bool InputIsBitcode =
true;
5543 for (
size_t i = 1; i < ActionInfo.size(); i++)
5544 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5545 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5546 InputIsBitcode =
false;
5549 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5553 const Tool *
T = TC.SelectTool(*CJ);
5560 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5563 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5566 Inputs = CJ->getInputs();
5567 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5578 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5584 for (
Action *A : Inputs) {
5585 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5586 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5587 NewInputs.push_back(A);
5593 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5594 PreprocessJobOffloadActions.end());
5595 NewInputs.append(PJ->input_begin(), PJ->input_end());
5603 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5605 assert(BaseAction &&
"Invalid base action.");
5622 ActionChain.back().JA = BaseAction;
5623 while (ActionChain.back().JA) {
5624 const Action *CurAction = ActionChain.back().JA;
5627 ActionChain.resize(ActionChain.size() + 1);
5628 JobActionInfo &AI = ActionChain.back();
5632 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5636 ActionChain.pop_back();
5644 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5645 CollapsedOffloadAction);
5647 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5649 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5655 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5667 StringRef BoundArch,
5669 std::string TriplePlusArch = TC->
getTriple().normalize();
5670 if (!BoundArch.empty()) {
5671 TriplePlusArch +=
"-";
5672 TriplePlusArch += BoundArch;
5674 TriplePlusArch +=
"-";
5676 return TriplePlusArch;
5681 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5682 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5685 std::pair<const Action *, std::string> ActionTC = {
5687 auto CachedResult = CachedResults.find(ActionTC);
5688 if (CachedResult != CachedResults.end()) {
5689 return CachedResult->second;
5692 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5693 CachedResults, TargetDeviceOffloadKind);
5694 CachedResults[ActionTC] =
Result;
5699 const JobAction *JA,
const char *BaseInput,
5702 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5706 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5707 Path = A->getValue();
5708 if (llvm::sys::fs::is_directory(
Path)) {
5710 llvm::sys::path::replace_extension(Tmp,
"json");
5711 llvm::sys::path::append(
Path, llvm::sys::path::filename(Tmp));
5714 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5717 Path = DumpDir->getValue();
5718 Path += llvm::sys::path::filename(BaseInput);
5722 llvm::sys::path::replace_extension(
Path,
"json");
5724 const char *ResultFile =
C.getArgs().MakeArgString(
Path);
5725 C.addTimeTraceFile(ResultFile, JA);
5726 C.addResultFile(ResultFile, JA);
5731 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5732 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5735 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5738 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5771 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5773 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5774 const char *DepBoundArch) {
5777 LinkingOutput, CachedResults,
5787 OA->doOnEachDependence(
5788 BuildingForOffloadDevice,
5791 C, DepA, DepTC, DepBoundArch,
false,
5792 !!DepBoundArch, LinkingOutput, CachedResults,
5796 A = BuildingForOffloadDevice
5797 ? OA->getSingleDeviceDependence(
true)
5798 : OA->getHostDependence();
5802 std::pair<const Action *, std::string> ActionTC = {
5803 OA->getHostDependence(),
5805 auto It = CachedResults.find(ActionTC);
5806 if (It != CachedResults.end()) {
5808 Inputs.append(OffloadDependencesInputInfo);
5813 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5816 const Arg &Input = IA->getInputArg();
5818 if (Input.getOption().matches(options::OPT_INPUT)) {
5819 const char *
Name = Input.getValue();
5829 if (!ArchName.empty())
5830 TC = &getToolChain(
C.getArgs(),
5832 C.getArgs(), ArchName));
5834 TC = &
C.getDefaultToolChain();
5837 MultipleArchs, LinkingOutput, CachedResults,
5838 TargetDeviceOffloadKind);
5844 const JobAction *JA = cast<JobAction>(A);
5849 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5856 for (
const auto *OA : CollapsedOffloadActions)
5857 cast<OffloadAction>(OA)->doOnEachDependence(
5858 BuildingForOffloadDevice,
5861 C, DepA, DepTC, DepBoundArch,
false,
5862 !!DepBoundArch, LinkingOutput, CachedResults,
5868 for (
const Action *Input : Inputs) {
5872 bool SubJobAtTopLevel =
5873 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5875 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5880 const char *BaseInput = InputInfos[0].getBaseInput();
5881 for (
auto &Info : InputInfos) {
5882 if (Info.isFilename()) {
5883 BaseInput = Info.getBaseInput();
5890 if (JA->
getType() == types::TY_dSYM)
5891 BaseInput = InputInfos[0].getFilename();
5894 if (!OffloadDependencesInputInfo.empty())
5895 InputInfos.append(OffloadDependencesInputInfo.begin(),
5896 OffloadDependencesInputInfo.end());
5899 llvm::Triple EffectiveTriple;
5901 const ArgList &Args =
5903 if (InputInfos.size() != 1) {
5907 EffectiveTriple = llvm::Triple(
5915 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5919 for (
auto &UI : UA->getDependentActionsInfo()) {
5921 "Unbundling with no offloading??");
5928 UI.DependentOffloadKind,
5929 UI.DependentToolChain->getTriple().normalize(),
5940 UnbundlingResults.push_back(CurI);
5949 Arch = UI.DependentBoundArch;
5954 UI.DependentOffloadKind)}] = {
5960 std::pair<const Action *, std::string> ActionTC = {
5962 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5963 "Result does not exist??");
5964 Result = CachedResults[ActionTC].front();
5965 }
else if (JA->
getType() == types::TY_Nothing)
5972 isa<OffloadPackagerJobAction>(A) ||
5976 AtTopLevel, MultipleArchs,
5979 if (
T->canEmitIR() && OffloadingPrefix.empty())
5984 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5985 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5986 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5987 llvm::errs() << InputInfos[i].getAsString();
5989 llvm::errs() <<
", ";
5991 if (UnbundlingResults.empty())
5992 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5994 llvm::errs() <<
"], outputs: [";
5995 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5996 llvm::errs() << UnbundlingResults[i].getAsString();
5998 llvm::errs() <<
", ";
6000 llvm::errs() <<
"] \n";
6003 if (UnbundlingResults.empty())
6004 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6006 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6007 Args, LinkingOutput);
6013 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6014 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6026 if (ArgValue.empty()) {
6029 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
6031 llvm::sys::path::append(
Filename, BaseName);
6034 if (!llvm::sys::path::has_extension(ArgValue)) {
6039 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6044 llvm::sys::path::replace_extension(
Filename, Extension);
6047 return Args.MakeArgString(
Filename.c_str());
6051 if (isa<PreprocessJobAction>(JA))
6053 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
6055 if (isa<OffloadBundlingJobAction>(JA) &&
6062 StringRef Suffix,
bool MultipleArchs,
6063 StringRef BoundArch,
6064 bool NeedUniqueDirectory)
const {
6066 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6067 std::optional<std::string> CrashDirectory =
6069 ? std::string(A->getValue())
6070 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6071 if (CrashDirectory) {
6072 if (!
getVFS().exists(*CrashDirectory))
6073 llvm::sys::fs::create_directories(*CrashDirectory);
6075 llvm::sys::path::append(
Path, Prefix);
6076 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6077 if (std::error_code EC =
6078 llvm::sys::fs::createUniqueFile(
Path + Middle + Suffix, TmpName)) {
6079 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6083 if (MultipleArchs && !BoundArch.empty()) {
6084 if (NeedUniqueDirectory) {
6086 llvm::sys::path::append(TmpName,
6087 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6097 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6112 const char *BaseInput) {
6113 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
6114 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6115 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6120 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6124 const char *BaseInput,
6125 StringRef OrigBoundArch,
bool AtTopLevel,
6127 StringRef OffloadingPrefix)
const {
6128 std::string BoundArch = OrigBoundArch.str();
6129 if (is_style_windows(llvm::sys::path::Style::native)) {
6132 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
6135 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6137 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
6138 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6139 return C.addResultFile(FinalOutput->getValue(), &JA);
6143 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6144 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
6145 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6147 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6148 NameArg = A->getValue();
6149 return C.addResultFile(
6159 if (JA.
getType() == types::TY_ModuleFile &&
6160 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6164 if (JA.
getType() == types::TY_PP_Asm &&
6165 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6166 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6169 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6172 if (JA.
getType() == types::TY_Object &&
6173 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
6174 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6177 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6181 if (JA.
getType() == types::TY_PP_Asm &&
6182 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6183 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6185 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6186 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6187 return C.addResultFile(
6192 if (JA.
getType() == types::TY_API_INFO &&
6193 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6194 C.getArgs().hasArg(options::OPT_o))
6195 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6196 <<
C.getArgs().getLastArgValue(options::OPT_o);
6203 bool SpecifiedModuleOutput =
6204 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6205 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6206 if (MultipleArchs && SpecifiedModuleOutput)
6207 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6211 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
6212 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6213 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
6219 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6221 StringRef
Name = llvm::sys::path::filename(BaseInput);
6222 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6223 const char *Suffix =
6228 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6229 bool NeedUniqueDirectory =
6232 Triple.isOSDarwin();
6233 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6234 NeedUniqueDirectory);
6242 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
6243 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6248 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6249 llvm::sys::path::filename(BasePath));
6250 BaseName = ExternalPath;
6251 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
6252 BaseName = BasePath;
6254 BaseName = llvm::sys::path::filename(BasePath);
6257 const char *NamedOutput;
6259 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6260 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6264 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6268 }
else if (JA.
getType() == types::TY_Image &&
6269 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6270 options::OPT__SLASH_o)) {
6274 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6278 }
else if (JA.
getType() == types::TY_Image) {
6288 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6289 options::OPT_fno_gpu_rdc,
false);
6290 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6291 if (UseOutExtension) {
6293 llvm::sys::path::replace_extension(Output,
"");
6295 Output += OffloadingPrefix;
6296 if (MultipleArchs && !BoundArch.empty()) {
6298 Output.append(BoundArch);
6300 if (UseOutExtension)
6302 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6305 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6306 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6307 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6310 .getLastArg(options::OPT__SLASH_o)
6315 const char *Suffix =
6317 assert(Suffix &&
"All types used for output should have a suffix.");
6319 std::string::size_type End = std::string::npos;
6321 End = BaseName.rfind(
'.');
6323 Suffixed += OffloadingPrefix;
6324 if (MultipleArchs && !BoundArch.empty()) {
6326 Suffixed.append(BoundArch);
6331 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6332 const llvm::opt::DerivedArgList &Args) {
6337 return isa<CompileJobAction>(JA) &&
6339 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6344 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6345 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6346 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6350 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6354 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6355 JA.
getType() != types::TY_PCH) {
6356 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6358 llvm::sys::path::remove_filename(TempPath);
6359 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6360 llvm::sys::path::append(TempPath, OutputFileName);
6361 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6367 bool SameFile =
false;
6369 llvm::sys::fs::current_path(
Result);
6370 llvm::sys::path::append(
Result, BaseName);
6371 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6374 StringRef
Name = llvm::sys::path::filename(BaseInput);
6375 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6379 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6385 llvm::sys::path::remove_filename(BasePath);
6386 if (BasePath.empty())
6387 BasePath = NamedOutput;
6389 llvm::sys::path::append(BasePath, NamedOutput);
6390 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6393 return C.addResultFile(NamedOutput, &JA);
6399 -> std::optional<std::string> {
6402 for (
const auto &
Dir :
P) {
6406 llvm::sys::path::append(
P,
Name);
6407 if (llvm::sys::fs::exists(Twine(
P)))
6408 return std::string(
P);
6410 return std::nullopt;
6417 llvm::sys::path::append(R,
Name);
6418 if (llvm::sys::fs::exists(Twine(R)))
6419 return std::string(R);
6422 llvm::sys::path::append(
P,
Name);
6423 if (llvm::sys::fs::exists(Twine(
P)))
6424 return std::string(
P);
6427 llvm::sys::path::append(
D,
"..",
Name);
6428 if (llvm::sys::fs::exists(Twine(
D)))
6429 return std::string(
D);
6438 llvm::sys::path::append(R2,
"..",
"..",
Name);
6439 if (llvm::sys::fs::exists(Twine(R2)))
6440 return std::string(R2);
6442 return std::string(
Name);
6445void Driver::generatePrefixedToolNames(
6449 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6450 Names.emplace_back(
Tool);
6454 llvm::sys::path::append(Dir, Name);
6455 if (llvm::sys::fs::can_execute(Twine(Dir)))
6457 llvm::sys::path::remove_filename(Dir);
6463 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6468 if (llvm::sys::fs::is_directory(PrefixDir)) {
6471 return std::string(
P);
6474 if (llvm::sys::fs::can_execute(Twine(
P)))
6475 return std::string(
P);
6480 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6488 for (
const auto &
Path : List) {
6491 return std::string(
P);
6495 if (llvm::ErrorOr<std::string>
P =
6496 llvm::sys::findProgramByName(TargetSpecificExecutable))
6500 return std::string(
Name);
6505 std::string error =
"<NOT PRESENT>";
6509 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6526 llvm::sys::path::remove_filename(path);
6527 llvm::sys::path::append(path,
"libc++.modules.json");
6528 if (TC.
getVFS().exists(path))
6529 return static_cast<std::string
>(path);
6534 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6537 return evaluate(
"libc++.a").value_or(error);
6541 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6545 llvm::sys::path::remove_filename(path);
6546 llvm::sys::path::append(path,
"libstdc++.modules.json");
6547 if (TC.
getVFS().exists(path))
6548 return static_cast<std::string
>(path);
6553 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6556 return evaluate(
"libstdc++.a").value_or(error);
6565 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix,
Path);
6567 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6571 return std::string(
Path);
6576 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix,
Path);
6578 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6582 return std::string(
Path);
6587 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6591 Output = FpArg->getValue();
6595 if (!llvm::sys::path::has_extension(Output))
6598 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6599 Output = YcArg->getValue();
6602 llvm::sys::path::replace_extension(Output,
".pch");
6604 return std::string(Output);
6607const ToolChain &Driver::getToolChain(
const ArgList &Args,
6608 const llvm::Triple &
Target)
const {
6610 auto &TC = ToolChains[
Target.str()];
6612 switch (
Target.getOS()) {
6613 case llvm::Triple::AIX:
6614 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6616 case llvm::Triple::Haiku:
6617 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6619 case llvm::Triple::Darwin:
6620 case llvm::Triple::MacOSX:
6621 case llvm::Triple::IOS:
6622 case llvm::Triple::TvOS:
6623 case llvm::Triple::WatchOS:
6624 case llvm::Triple::XROS:
6625 case llvm::Triple::DriverKit:
6626 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6628 case llvm::Triple::DragonFly:
6629 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6631 case llvm::Triple::OpenBSD:
6632 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6634 case llvm::Triple::NetBSD:
6635 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6637 case llvm::Triple::FreeBSD:
6639 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6642 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6644 case llvm::Triple::Linux:
6645 case llvm::Triple::ELFIAMCU:
6646 if (
Target.getArch() == llvm::Triple::hexagon)
6647 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6649 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6650 !
Target.hasEnvironment())
6651 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6654 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6656 else if (
Target.getArch() == llvm::Triple::ve)
6657 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6658 else if (
Target.isOHOSFamily())
6659 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6661 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6663 case llvm::Triple::NaCl:
6664 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6666 case llvm::Triple::Fuchsia:
6667 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6669 case llvm::Triple::Solaris:
6670 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6672 case llvm::Triple::CUDA:
6673 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6675 case llvm::Triple::AMDHSA:
6676 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6678 case llvm::Triple::AMDPAL:
6679 case llvm::Triple::Mesa3D:
6680 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6682 case llvm::Triple::UEFI:
6683 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6685 case llvm::Triple::Win32:
6686 switch (
Target.getEnvironment()) {
6688 if (
Target.isOSBinFormatELF())
6689 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6690 else if (
Target.isOSBinFormatMachO())
6691 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6693 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6695 case llvm::Triple::GNU:
6696 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6698 case llvm::Triple::Itanium:
6699 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6702 case llvm::Triple::MSVC:
6703 case llvm::Triple::UnknownEnvironment:
6704 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6705 .starts_with_insensitive(
"bfd"))
6706 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6710 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6714 case llvm::Triple::PS4:
6715 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6717 case llvm::Triple::PS5:
6718 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6720 case llvm::Triple::Hurd:
6721 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6723 case llvm::Triple::LiteOS:
6724 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6726 case llvm::Triple::ZOS:
6727 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6729 case llvm::Triple::Vulkan:
6730 case llvm::Triple::ShaderModel:
6731 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6736 switch (
Target.getArch()) {
6737 case llvm::Triple::tce:
6738 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6740 case llvm::Triple::tcele:
6741 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6743 case llvm::Triple::hexagon:
6744 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6747 case llvm::Triple::lanai:
6748 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6750 case llvm::Triple::xcore:
6751 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6753 case llvm::Triple::wasm32:
6754 case llvm::Triple::wasm64:
6755 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6757 case llvm::Triple::avr:
6758 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6760 case llvm::Triple::msp430:
6762 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6764 case llvm::Triple::riscv32:
6765 case llvm::Triple::riscv64:
6768 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6770 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6772 case llvm::Triple::ve:
6773 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6775 case llvm::Triple::spirv32:
6776 case llvm::Triple::spirv64:
6777 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6779 case llvm::Triple::csky:
6780 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6784 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6785 else if (
Target.isOSBinFormatELF())
6786 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6787 else if (
Target.isAppleMachO())
6788 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6789 else if (
Target.isOSBinFormatMachO())
6790 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6792 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6800const ToolChain &Driver::getOffloadingDeviceToolChain(
6801 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6810 switch (TargetDeviceOffloadKind) {
6812 if (((
Target.getArch() == llvm::Triple::amdgcn ||
6813 Target.getArch() == llvm::Triple::spirv64) &&
6814 Target.getVendor() == llvm::Triple::AMD &&
6815 Target.getOS() == llvm::Triple::AMDHSA) ||
6816 !Args.hasArgNoClaim(options::OPT_offload_EQ))
6817 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6819 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6820 Target.getVendor() == llvm::Triple::UnknownVendor &&
6821 Target.getOS() == llvm::Triple::UnknownOS)
6822 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6827 if (
Target.isSPIROrSPIRV())
6828 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, HostTC,
6835 assert(TC &&
"Could not create offloading device tool chain.");
6841 if (JA.
size() != 1 ||
6846 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6847 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6848 !isa<ExtractAPIJobAction>(JA))
6856 if (JA.
size() != 1 ||
6861 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6862 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
6870 if (Args.hasArg(options::OPT_emit_static_lib))
6881 unsigned &Micro,
bool &HadExtra) {
6884 Major = Minor = Micro = 0;
6888 if (Str.consumeInteger(10, Major))
6892 if (!Str.consume_front(
"."))
6895 if (Str.consumeInteger(10, Minor))
6899 if (!Str.consume_front(
"."))
6902 if (Str.consumeInteger(10, Micro))
6920 unsigned CurDigit = 0;
6921 while (CurDigit < Digits.size()) {
6923 if (Str.consumeInteger(10, Digit))
6925 Digits[CurDigit] = Digit;
6928 if (!Str.consume_front(
"."))
6937llvm::opt::Visibility
6938Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6951const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6967 llvm_unreachable(
"Unhandled Mode");
6971 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6976 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6977 options::OPT_fno_save_optimization_record,
false))
6981 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6982 options::OPT_fno_save_optimization_record,
false))
6986 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6987 options::OPT_fno_save_optimization_record,
false))
6991 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6992 options::OPT_fno_save_optimization_record,
false))
6999 static StringRef OptName =
7001 llvm::StringRef Opt;
7002 for (StringRef Arg : Args) {
7003 if (!Arg.starts_with(OptName))
7009 return Opt.consume_front(OptName) ? Opt :
"";
7016 llvm::BumpPtrAllocator &Alloc,
7017 llvm::vfs::FileSystem *FS) {
7026 for (
const char *F : Args) {
7027 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7029 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7030 RSPQuoting = Windows;
7038 llvm::cl::TokenizerCallback Tokenizer;
7040 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7042 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7044 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7047 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7048 ECtx.setMarkEOLs(MarkEOLs);
7052 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7056 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7057 [](
const char *A) {
return A !=
nullptr; });
7058 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7061 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7062 Args.resize(newEnd - Args.begin());
7066 return llvm::Error::success();
7070 return SavedStrings.insert(S).first->getKeyData();
7103 llvm::StringSet<> &SavedStrings) {
7106 if (Edit[0] ==
'^') {
7107 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7108 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7109 Args.insert(Args.begin() + 1, Str);
7110 }
else if (Edit[0] ==
'+') {
7111 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7112 OS <<
"### Adding argument " << Str <<
" at end\n";
7113 Args.push_back(Str);
7114 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7115 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7116 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7117 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7118 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7120 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7122 if (Args[i] ==
nullptr)
7124 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7126 if (Repl != Args[i]) {
7127 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7131 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7132 auto Option = Edit.substr(1);
7133 for (
unsigned i = 1; i < Args.size();) {
7134 if (Option == Args[i]) {
7135 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7136 Args.erase(Args.begin() + i);
7137 if (Edit[0] ==
'X') {
7138 if (i < Args.size()) {
7139 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7140 Args.erase(Args.begin() + i);
7142 OS <<
"### Invalid X edit, end of command line!\n";
7147 }
else if (Edit[0] ==
'O') {
7148 for (
unsigned i = 1; i < Args.size();) {
7149 const char *A = Args[i];
7153 if (A[0] ==
'-' && A[1] ==
'O' &&
7154 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7155 (
'0' <= A[2] && A[2] <=
'9'))))) {
7156 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7157 Args.erase(Args.begin() + i);
7161 OS <<
"### Adding argument " << Edit <<
" at end\n";
7162 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7164 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7169 const char *OverrideStr,
7170 llvm::StringSet<> &SavedStrings,
7173 OS = &llvm::nulls();
7175 if (OverrideStr[0] ==
'#') {
7177 OS = &llvm::nulls();
7180 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
7184 const char *S = OverrideStr;
7186 const char *End = ::strchr(S,
' ');
7188 End = S + strlen(S);
static std::optional< llvm::Triple > getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args)
static bool addSYCLDefaultTriple(Compilation &C, SmallVectorImpl< llvm::Triple > &SYCLTriples)
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 llvm::Triple getSYCLDeviceTriple(StringRef TargetArch)
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 const char BugReporMsg[]
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static std::optional< llvm::Triple > getOffloadTargetTriple(const Driver &D, const ArgList &Args)
static void appendOneArg(InputArgList &Args, const Arg *Opt)
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.
Exposes information about the current target.
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
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) 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,...
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.
static std::string GetResourcesPath(StringRef BinaryPath)
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
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.
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, StringRef CUID, Action *HostAction) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
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.
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)
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.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError) const
ParseArgStrings - Parse the given list of strings into an ArgList.
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.
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.