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)) ||
416 (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
417 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
418 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
419 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
420 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
421 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
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 : Args) {
4717 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4718 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4721 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4722 unsigned Prev = Index;
4723 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4724 if (!ExtractedArg || Index > Prev + 1) {
4725 TC->
getDriver().
Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
4726 << Arg->getAsString(Args);
4729 Arg = ExtractedArg.get();
4734 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4735 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4736 if (Arch ==
"native" || Arch.empty()) {
4740 llvm::consumeError(GPUsOrErr.takeError());
4743 << llvm::Triple::getArchTypeName(TC->
getArch())
4744 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4748 for (
auto ArchStr : *GPUsOrErr) {
4755 C, Args, Arch, TC->
getTriple(), SuppressError);
4756 if (ArchStr.empty())
4758 Archs.insert(ArchStr);
4761 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4762 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4763 if (Arch ==
"all") {
4767 C, Args, Arch, TC->
getTriple(), SuppressError);
4768 if (ArchStr.empty())
4770 Archs.erase(ArchStr);
4776 if (
auto ConflictingArchs =
4778 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4779 << ConflictingArchs->first << ConflictingArchs->second;
4780 C.setContainsError();
4787 if (Archs.empty()) {
4793 Archs.insert(StringRef());
4795 Archs.insert(StringRef());
4797 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4798 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4805 llvm::opt::DerivedArgList &Args,
4806 const InputTy &Input, StringRef CUID,
4807 Action *HostAction)
const {
4812 !(isa<CompileJobAction>(HostAction) ||
4826 auto TCRange =
C.getOffloadToolChains(Kind);
4827 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4828 ToolChains.push_back(TI->second);
4830 if (ToolChains.empty())
4834 const Arg *InputArg = Input.second;
4843 for (
const ToolChain *TC : ToolChains) {
4847 for (StringRef Arch : Sorted) {
4848 TCAndArchs.push_back(std::make_pair(TC, Arch));
4849 DeviceActions.push_back(
4850 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4854 if (DeviceActions.empty())
4860 HostAction->
getType() != types::TY_Nothing &&
4870 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4879 auto TCAndArch = TCAndArchs.begin();
4880 for (
Action *&A : DeviceActions) {
4881 if (A->
getType() == types::TY_Nothing)
4889 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4891 HostAction->
getType() != types::TY_Nothing) {
4898 TCAndArch->second.data(), Kind);
4900 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4909 for (
Action *&A : DeviceActions) {
4910 if ((A->
getType() != types::TY_Object &&
4911 A->
getType() != types::TY_LTO_BC) ||
4913 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4919 auto TCAndArch = TCAndArchs.begin();
4920 for (
Action *A : DeviceActions) {
4921 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4923 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4928 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4930 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4938 bool ShouldBundleHIP =
4940 Args.hasFlag(options::OPT_gpu_bundle_output,
4941 options::OPT_no_gpu_bundle_output,
true) &&
4942 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4943 !llvm::any_of(OffloadActions,
4950 if (OffloadActions.empty())
4955 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4959 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4963 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4968 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4977 nullptr,
C.getActiveOffloadKinds());
4986 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4987 return A->
getType() == types::TY_Nothing;
4988 }) && isa<CompileJobAction>(HostAction);
4991 nullptr, SingleDeviceOutput ? DDep : DDeps);
4992 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4998 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5008 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5014 llvm_unreachable(
"link action invalid here.");
5016 llvm_unreachable(
"ifsmerge action invalid here.");
5021 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5022 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5023 OutputTy = types::TY_Dependencies;
5028 if (!Args.hasFlag(options::OPT_frewrite_includes,
5029 options::OPT_fno_rewrite_includes,
false) &&
5030 !Args.hasFlag(options::OPT_frewrite_imports,
5031 options::OPT_fno_rewrite_imports,
false) &&
5032 !Args.hasFlag(options::OPT_fdirectives_only,
5033 options::OPT_fno_directives_only,
false) &&
5037 "Cannot preprocess this input type!");
5043 if (Args.hasArg(options::OPT_extract_api))
5050 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
5051 !Args.getLastArg(options::OPT__precompile))
5056 "Cannot precompile this input type!");
5060 const char *ModName =
nullptr;
5061 if (OutputTy == types::TY_PCH) {
5062 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5063 ModName = A->getValue();
5065 OutputTy = types::TY_ModuleFile;
5068 if (Args.hasArg(options::OPT_fsyntax_only)) {
5070 OutputTy = types::TY_Nothing;
5076 if (Args.hasArg(options::OPT_fsyntax_only))
5078 if (Args.hasArg(options::OPT_rewrite_objc))
5080 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5082 types::TY_RewrittenLegacyObjC);
5083 if (Args.hasArg(options::OPT__analyze))
5085 if (Args.hasArg(options::OPT__migrate))
5087 if (Args.hasArg(options::OPT_emit_ast))
5089 if (Args.hasArg(options::OPT_emit_cir))
5091 if (Args.hasArg(options::OPT_module_file_info))
5093 if (Args.hasArg(options::OPT_verify_pch))
5095 if (Args.hasArg(options::OPT_extract_api))
5102 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5103 !Args.hasArg(options::OPT_emit_llvm))
5104 Output = types::TY_PP_Asm;
5105 else if (Args.hasArg(options::OPT_S))
5106 Output = types::TY_LTO_IR;
5108 Output = types::TY_LTO_BC;
5113 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5116 if (Args.hasArg(options::OPT_emit_llvm) ||
5121 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5125 Args.hasArg(options::OPT_S) &&
5129 !Args.hasFlag(options::OPT_offload_new_driver,
5130 options::OPT_no_offload_new_driver,
5133 : types::TY_LLVM_BC;
5142 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5146 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5148 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5168 unsigned NumOutputs = 0;
5169 unsigned NumIfsOutputs = 0;
5170 for (
const Action *A :
C.getActions()) {
5171 if (A->
getType() != types::TY_Nothing &&
5172 A->
getType() != types::TY_DX_CONTAINER &&
5174 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5176 0 == NumIfsOutputs++) ||
5181 A->
getType() == types::TY_Nothing &&
5182 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5183 NumOutputs += A->
size();
5186 if (NumOutputs > 1) {
5187 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5188 FinalOutput =
nullptr;
5192 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5195 llvm::StringSet<> ArchNames;
5196 if (RawTriple.isOSBinFormatMachO())
5197 for (
const Arg *A :
C.getArgs())
5198 if (A->getOption().matches(options::OPT_arch))
5199 ArchNames.insert(A->getValue());
5202 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5203 for (
Action *A :
C.getActions()) {
5210 const char *LinkingOutput =
nullptr;
5211 if (isa<LipoJobAction>(A)) {
5213 LinkingOutput = FinalOutput->getValue();
5221 ArchNames.size() > 1,
5222 LinkingOutput, CachedResults,
5229 for (
auto &J :
C.getJobs())
5230 J.InProcess =
false;
5233 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
5234 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5235 Cmd.getProcessStatistics();
5239 const char *LinkingOutput =
nullptr;
5241 LinkingOutput = FinalOutput->getValue();
5242 else if (!
Cmd.getOutputFilenames().empty())
5243 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
5248 using namespace llvm;
5250 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
5251 <<
"output=" << LinkingOutput;
5252 outs() <<
", total="
5253 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5255 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5256 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5260 llvm::raw_string_ostream Out(Buffer);
5261 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
5264 llvm::sys::printArg(Out, LinkingOutput, true);
5265 Out <<
',' << ProcStat->TotalTime.count() <<
','
5266 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5270 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5271 llvm::sys::fs::OF_Append |
5272 llvm::sys::fs::OF_Text);
5277 llvm::errs() <<
"ERROR: Cannot lock file "
5278 << CCPrintStatReportFilename <<
": "
5279 << toString(L.takeError()) <<
"\n";
5290 if (Diags.hasErrorOccurred() ||
5291 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5295 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5297 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5300 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5301 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5303 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5307 return strstr(J.getCreator().getShortName(),
"assembler");
5309 for (Arg *A :
C.getArgs()) {
5313 if (!A->isClaimed()) {
5319 const Option &Opt = A->getOption();
5320 if (Opt.getKind() == Option::FlagClass) {
5321 bool DuplicateClaimed =
false;
5323 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5324 if (AA->isClaimed()) {
5325 DuplicateClaimed =
true;
5330 if (DuplicateClaimed)
5336 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5338 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5343 !
C.getActions().empty()) {
5344 Diag(diag::err_drv_unsupported_opt_for_target)
5345 << A->getSpelling() << getTargetTriple();
5347 Diag(clang::diag::warn_drv_unused_argument)
5348 << A->getAsString(
C.getArgs());
5358class ToolSelector final {
5369 bool IsHostSelector;
5380 bool CanBeCollapsed =
true) {
5382 if (Inputs.size() != 1)
5385 Action *CurAction = *Inputs.begin();
5386 if (CanBeCollapsed &&
5392 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5396 if (!IsHostSelector) {
5397 if (OA->hasSingleDeviceDependence(
true)) {
5399 OA->getSingleDeviceDependence(
true);
5400 if (CanBeCollapsed &&
5403 SavedOffloadAction.push_back(OA);
5404 return dyn_cast<JobAction>(CurAction);
5406 }
else if (OA->hasHostDependence()) {
5407 CurAction = OA->getHostDependence();
5408 if (CanBeCollapsed &&
5411 SavedOffloadAction.push_back(OA);
5412 return dyn_cast<JobAction>(CurAction);
5417 return dyn_cast<JobAction>(CurAction);
5421 bool canCollapseAssembleAction()
const {
5422 return TC.useIntegratedAs() && !SaveTemps &&
5423 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5424 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5425 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5426 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5430 bool canCollapsePreprocessorAction()
const {
5431 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5432 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5433 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5438 struct JobActionInfo final {
5448 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5450 unsigned ElementNum) {
5451 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5452 for (
unsigned I = 0; I < ElementNum; ++I)
5453 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5454 ActionInfo[I].SavedOffloadAction.end());
5470 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5472 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5473 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5474 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5475 if (!AJ || !BJ || !CJ)
5479 const Tool *
T = TC.SelectTool(*CJ);
5486 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5492 const Tool *BT = TC.SelectTool(*BJ);
5497 if (!
T->hasIntegratedAssembler())
5500 Inputs = CJ->getInputs();
5501 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5508 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5510 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5511 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5516 const Tool *
T = TC.SelectTool(*BJ);
5520 if (!
T->hasIntegratedAssembler())
5523 Inputs = BJ->getInputs();
5524 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5531 if (ActionInfo.size() < 2)
5533 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5534 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5543 bool InputIsBitcode =
true;
5544 for (
size_t i = 1; i < ActionInfo.size(); i++)
5545 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5546 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5547 InputIsBitcode =
false;
5550 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5554 const Tool *
T = TC.SelectTool(*CJ);
5561 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5564 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5567 Inputs = CJ->getInputs();
5568 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5579 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5585 for (
Action *A : Inputs) {
5586 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5587 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5588 NewInputs.push_back(A);
5594 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5595 PreprocessJobOffloadActions.end());
5596 NewInputs.append(PJ->input_begin(), PJ->input_end());
5604 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5606 assert(BaseAction &&
"Invalid base action.");
5623 ActionChain.back().JA = BaseAction;
5624 while (ActionChain.back().JA) {
5625 const Action *CurAction = ActionChain.back().JA;
5628 ActionChain.resize(ActionChain.size() + 1);
5629 JobActionInfo &AI = ActionChain.back();
5633 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5637 ActionChain.pop_back();
5645 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5646 CollapsedOffloadAction);
5648 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5650 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5656 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5668 StringRef BoundArch,
5670 std::string TriplePlusArch = TC->
getTriple().normalize();
5671 if (!BoundArch.empty()) {
5672 TriplePlusArch +=
"-";
5673 TriplePlusArch += BoundArch;
5675 TriplePlusArch +=
"-";
5677 return TriplePlusArch;
5682 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5683 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5686 std::pair<const Action *, std::string> ActionTC = {
5688 auto CachedResult = CachedResults.find(ActionTC);
5689 if (CachedResult != CachedResults.end()) {
5690 return CachedResult->second;
5693 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5694 CachedResults, TargetDeviceOffloadKind);
5695 CachedResults[ActionTC] =
Result;
5700 const JobAction *JA,
const char *BaseInput,
5703 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5707 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5708 Path = A->getValue();
5709 if (llvm::sys::fs::is_directory(
Path)) {
5711 llvm::sys::path::replace_extension(Tmp,
"json");
5712 llvm::sys::path::append(
Path, llvm::sys::path::filename(Tmp));
5715 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5718 Path = DumpDir->getValue();
5719 Path += llvm::sys::path::filename(BaseInput);
5723 llvm::sys::path::replace_extension(
Path,
"json");
5725 const char *ResultFile =
C.getArgs().MakeArgString(
Path);
5726 C.addTimeTraceFile(ResultFile, JA);
5727 C.addResultFile(ResultFile, JA);
5732 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5733 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5736 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5739 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5772 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5774 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5775 const char *DepBoundArch) {
5778 LinkingOutput, CachedResults,
5788 OA->doOnEachDependence(
5789 BuildingForOffloadDevice,
5792 C, DepA, DepTC, DepBoundArch,
false,
5793 !!DepBoundArch, LinkingOutput, CachedResults,
5797 A = BuildingForOffloadDevice
5798 ? OA->getSingleDeviceDependence(
true)
5799 : OA->getHostDependence();
5803 std::pair<const Action *, std::string> ActionTC = {
5804 OA->getHostDependence(),
5806 auto It = CachedResults.find(ActionTC);
5807 if (It != CachedResults.end()) {
5809 Inputs.append(OffloadDependencesInputInfo);
5814 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5817 const Arg &Input = IA->getInputArg();
5819 if (Input.getOption().matches(options::OPT_INPUT)) {
5820 const char *
Name = Input.getValue();
5830 if (!ArchName.empty())
5831 TC = &getToolChain(
C.getArgs(),
5833 C.getArgs(), ArchName));
5835 TC = &
C.getDefaultToolChain();
5838 MultipleArchs, LinkingOutput, CachedResults,
5839 TargetDeviceOffloadKind);
5845 const JobAction *JA = cast<JobAction>(A);
5850 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5857 for (
const auto *OA : CollapsedOffloadActions)
5858 cast<OffloadAction>(OA)->doOnEachDependence(
5859 BuildingForOffloadDevice,
5862 C, DepA, DepTC, DepBoundArch,
false,
5863 !!DepBoundArch, LinkingOutput, CachedResults,
5869 for (
const Action *Input : Inputs) {
5873 bool SubJobAtTopLevel =
5874 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5876 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5881 const char *BaseInput = InputInfos[0].getBaseInput();
5882 for (
auto &Info : InputInfos) {
5883 if (Info.isFilename()) {
5884 BaseInput = Info.getBaseInput();
5891 if (JA->
getType() == types::TY_dSYM)
5892 BaseInput = InputInfos[0].getFilename();
5895 if (!OffloadDependencesInputInfo.empty())
5896 InputInfos.append(OffloadDependencesInputInfo.begin(),
5897 OffloadDependencesInputInfo.end());
5900 llvm::Triple EffectiveTriple;
5902 const ArgList &Args =
5904 if (InputInfos.size() != 1) {
5908 EffectiveTriple = llvm::Triple(
5916 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5920 for (
auto &UI : UA->getDependentActionsInfo()) {
5922 "Unbundling with no offloading??");
5929 UI.DependentOffloadKind,
5930 UI.DependentToolChain->getTriple().normalize(),
5941 UnbundlingResults.push_back(CurI);
5950 Arch = UI.DependentBoundArch;
5955 UI.DependentOffloadKind)}] = {
5961 std::pair<const Action *, std::string> ActionTC = {
5963 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5964 "Result does not exist??");
5965 Result = CachedResults[ActionTC].front();
5966 }
else if (JA->
getType() == types::TY_Nothing)
5973 isa<OffloadPackagerJobAction>(A) ||
5977 AtTopLevel, MultipleArchs,
5980 if (
T->canEmitIR() && OffloadingPrefix.empty())
5985 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5986 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5987 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5988 llvm::errs() << InputInfos[i].getAsString();
5990 llvm::errs() <<
", ";
5992 if (UnbundlingResults.empty())
5993 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5995 llvm::errs() <<
"], outputs: [";
5996 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5997 llvm::errs() << UnbundlingResults[i].getAsString();
5999 llvm::errs() <<
", ";
6001 llvm::errs() <<
"] \n";
6004 if (UnbundlingResults.empty())
6005 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6007 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6008 Args, LinkingOutput);
6014 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6015 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6027 if (ArgValue.empty()) {
6030 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
6032 llvm::sys::path::append(
Filename, BaseName);
6035 if (!llvm::sys::path::has_extension(ArgValue)) {
6040 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6045 llvm::sys::path::replace_extension(
Filename, Extension);
6048 return Args.MakeArgString(
Filename.c_str());
6052 if (isa<PreprocessJobAction>(JA))
6054 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
6056 if (isa<OffloadBundlingJobAction>(JA) &&
6063 StringRef Suffix,
bool MultipleArchs,
6064 StringRef BoundArch,
6065 bool NeedUniqueDirectory)
const {
6067 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6068 std::optional<std::string> CrashDirectory =
6070 ? std::string(A->getValue())
6071 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6072 if (CrashDirectory) {
6073 if (!
getVFS().exists(*CrashDirectory))
6074 llvm::sys::fs::create_directories(*CrashDirectory);
6076 llvm::sys::path::append(
Path, Prefix);
6077 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6078 if (std::error_code EC =
6079 llvm::sys::fs::createUniqueFile(
Path + Middle + Suffix, TmpName)) {
6080 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6084 if (MultipleArchs && !BoundArch.empty()) {
6085 if (NeedUniqueDirectory) {
6087 llvm::sys::path::append(TmpName,
6088 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6098 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6113 const char *BaseInput) {
6114 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
6115 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6116 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6121 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6125 const char *BaseInput,
6126 StringRef OrigBoundArch,
bool AtTopLevel,
6128 StringRef OffloadingPrefix)
const {
6129 std::string BoundArch = OrigBoundArch.str();
6130 if (is_style_windows(llvm::sys::path::Style::native)) {
6133 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
6136 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6138 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
6139 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6140 return C.addResultFile(FinalOutput->getValue(), &JA);
6144 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6145 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
6146 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6148 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6149 NameArg = A->getValue();
6150 return C.addResultFile(
6160 if (JA.
getType() == types::TY_ModuleFile &&
6161 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6165 if (JA.
getType() == types::TY_PP_Asm &&
6166 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6167 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6170 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6173 if (JA.
getType() == types::TY_Object &&
6174 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
6175 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6178 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6182 if (JA.
getType() == types::TY_PP_Asm &&
6183 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6184 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6186 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6187 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6188 return C.addResultFile(
6193 if (JA.
getType() == types::TY_API_INFO &&
6194 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6195 C.getArgs().hasArg(options::OPT_o))
6196 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6197 <<
C.getArgs().getLastArgValue(options::OPT_o);
6204 bool SpecifiedModuleOutput =
6205 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6206 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6207 if (MultipleArchs && SpecifiedModuleOutput)
6208 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6212 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
6213 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6214 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
6220 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6222 StringRef
Name = llvm::sys::path::filename(BaseInput);
6223 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6224 const char *Suffix =
6229 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6230 bool NeedUniqueDirectory =
6233 Triple.isOSDarwin();
6234 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6235 NeedUniqueDirectory);
6243 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
6244 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6249 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6250 llvm::sys::path::filename(BasePath));
6251 BaseName = ExternalPath;
6252 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
6253 BaseName = BasePath;
6255 BaseName = llvm::sys::path::filename(BasePath);
6258 const char *NamedOutput;
6260 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6261 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6265 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6269 }
else if (JA.
getType() == types::TY_Image &&
6270 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6271 options::OPT__SLASH_o)) {
6275 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6279 }
else if (JA.
getType() == types::TY_Image) {
6289 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6290 options::OPT_fno_gpu_rdc,
false);
6291 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6292 if (UseOutExtension) {
6294 llvm::sys::path::replace_extension(Output,
"");
6296 Output += OffloadingPrefix;
6297 if (MultipleArchs && !BoundArch.empty()) {
6299 Output.append(BoundArch);
6301 if (UseOutExtension)
6303 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6306 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6307 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6308 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6311 .getLastArg(options::OPT__SLASH_o)
6316 const char *Suffix =
6318 assert(Suffix &&
"All types used for output should have a suffix.");
6320 std::string::size_type End = std::string::npos;
6322 End = BaseName.rfind(
'.');
6324 Suffixed += OffloadingPrefix;
6325 if (MultipleArchs && !BoundArch.empty()) {
6327 Suffixed.append(BoundArch);
6332 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6333 const llvm::opt::DerivedArgList &Args) {
6338 return isa<CompileJobAction>(JA) &&
6340 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6345 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6346 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6347 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6351 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6355 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6356 JA.
getType() != types::TY_PCH) {
6357 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6359 llvm::sys::path::remove_filename(TempPath);
6360 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6361 llvm::sys::path::append(TempPath, OutputFileName);
6362 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6368 bool SameFile =
false;
6370 llvm::sys::fs::current_path(
Result);
6371 llvm::sys::path::append(
Result, BaseName);
6372 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6375 StringRef
Name = llvm::sys::path::filename(BaseInput);
6376 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6380 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6386 llvm::sys::path::remove_filename(BasePath);
6387 if (BasePath.empty())
6388 BasePath = NamedOutput;
6390 llvm::sys::path::append(BasePath, NamedOutput);
6391 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6394 return C.addResultFile(NamedOutput, &JA);
6400 -> std::optional<std::string> {
6403 for (
const auto &
Dir :
P) {
6407 llvm::sys::path::append(
P,
Name);
6408 if (llvm::sys::fs::exists(Twine(
P)))
6409 return std::string(
P);
6411 return std::nullopt;
6418 llvm::sys::path::append(R,
Name);
6419 if (llvm::sys::fs::exists(Twine(R)))
6420 return std::string(R);
6423 llvm::sys::path::append(
P,
Name);
6424 if (llvm::sys::fs::exists(Twine(
P)))
6425 return std::string(
P);
6428 llvm::sys::path::append(
D,
"..",
Name);
6429 if (llvm::sys::fs::exists(Twine(
D)))
6430 return std::string(
D);
6439 llvm::sys::path::append(R2,
"..",
"..",
Name);
6440 if (llvm::sys::fs::exists(Twine(R2)))
6441 return std::string(R2);
6443 return std::string(
Name);
6446void Driver::generatePrefixedToolNames(
6450 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6451 Names.emplace_back(
Tool);
6455 llvm::sys::path::append(Dir, Name);
6456 if (llvm::sys::fs::can_execute(Twine(Dir)))
6458 llvm::sys::path::remove_filename(Dir);
6464 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6469 if (llvm::sys::fs::is_directory(PrefixDir)) {
6472 return std::string(
P);
6475 if (llvm::sys::fs::can_execute(Twine(
P)))
6476 return std::string(
P);
6481 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6489 for (
const auto &
Path : List) {
6492 return std::string(
P);
6496 if (llvm::ErrorOr<std::string>
P =
6497 llvm::sys::findProgramByName(TargetSpecificExecutable))
6501 return std::string(
Name);
6506 std::string error =
"<NOT PRESENT>";
6510 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6527 llvm::sys::path::remove_filename(path);
6528 llvm::sys::path::append(path,
"libc++.modules.json");
6529 if (TC.
getVFS().exists(path))
6530 return static_cast<std::string
>(path);
6535 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6538 return evaluate(
"libc++.a").value_or(error);
6542 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6546 llvm::sys::path::remove_filename(path);
6547 llvm::sys::path::append(path,
"libstdc++.modules.json");
6548 if (TC.
getVFS().exists(path))
6549 return static_cast<std::string
>(path);
6554 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6557 return evaluate(
"libstdc++.a").value_or(error);
6566 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix,
Path);
6568 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6572 return std::string(
Path);
6577 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix,
Path);
6579 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6583 return std::string(
Path);
6588 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6592 Output = FpArg->getValue();
6596 if (!llvm::sys::path::has_extension(Output))
6599 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6600 Output = YcArg->getValue();
6603 llvm::sys::path::replace_extension(Output,
".pch");
6605 return std::string(Output);
6608const ToolChain &Driver::getToolChain(
const ArgList &Args,
6609 const llvm::Triple &
Target)
const {
6611 auto &TC = ToolChains[
Target.str()];
6613 switch (
Target.getOS()) {
6614 case llvm::Triple::AIX:
6615 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6617 case llvm::Triple::Haiku:
6618 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6620 case llvm::Triple::Darwin:
6621 case llvm::Triple::MacOSX:
6622 case llvm::Triple::IOS:
6623 case llvm::Triple::TvOS:
6624 case llvm::Triple::WatchOS:
6625 case llvm::Triple::XROS:
6626 case llvm::Triple::DriverKit:
6627 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6629 case llvm::Triple::DragonFly:
6630 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6632 case llvm::Triple::OpenBSD:
6633 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6635 case llvm::Triple::NetBSD:
6636 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6638 case llvm::Triple::FreeBSD:
6640 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6643 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6645 case llvm::Triple::Linux:
6646 case llvm::Triple::ELFIAMCU:
6647 if (
Target.getArch() == llvm::Triple::hexagon)
6648 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6650 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6651 !
Target.hasEnvironment())
6652 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6655 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6657 else if (
Target.getArch() == llvm::Triple::ve)
6658 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6659 else if (
Target.isOHOSFamily())
6660 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6662 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6664 case llvm::Triple::NaCl:
6665 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6667 case llvm::Triple::Fuchsia:
6668 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6670 case llvm::Triple::Solaris:
6671 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6673 case llvm::Triple::CUDA:
6674 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6676 case llvm::Triple::AMDHSA:
6677 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6679 case llvm::Triple::AMDPAL:
6680 case llvm::Triple::Mesa3D:
6681 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6683 case llvm::Triple::UEFI:
6684 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6686 case llvm::Triple::Win32:
6687 switch (
Target.getEnvironment()) {
6689 if (
Target.isOSBinFormatELF())
6690 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6691 else if (
Target.isOSBinFormatMachO())
6692 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6694 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6696 case llvm::Triple::GNU:
6697 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6699 case llvm::Triple::Itanium:
6700 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6703 case llvm::Triple::MSVC:
6704 case llvm::Triple::UnknownEnvironment:
6705 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6706 .starts_with_insensitive(
"bfd"))
6707 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6711 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6715 case llvm::Triple::PS4:
6716 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6718 case llvm::Triple::PS5:
6719 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6721 case llvm::Triple::Hurd:
6722 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6724 case llvm::Triple::LiteOS:
6725 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6727 case llvm::Triple::ZOS:
6728 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6730 case llvm::Triple::Vulkan:
6731 case llvm::Triple::ShaderModel:
6732 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6737 switch (
Target.getArch()) {
6738 case llvm::Triple::tce:
6739 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6741 case llvm::Triple::tcele:
6742 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6744 case llvm::Triple::hexagon:
6745 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6748 case llvm::Triple::lanai:
6749 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6751 case llvm::Triple::xcore:
6752 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6754 case llvm::Triple::wasm32:
6755 case llvm::Triple::wasm64:
6756 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6758 case llvm::Triple::avr:
6759 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6761 case llvm::Triple::msp430:
6763 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6765 case llvm::Triple::riscv32:
6766 case llvm::Triple::riscv64:
6769 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6771 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6773 case llvm::Triple::ve:
6774 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6776 case llvm::Triple::spirv32:
6777 case llvm::Triple::spirv64:
6778 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6780 case llvm::Triple::csky:
6781 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6785 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6786 else if (
Target.isOSBinFormatELF())
6787 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6788 else if (
Target.isAppleMachO())
6789 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6790 else if (
Target.isOSBinFormatMachO())
6791 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6793 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6801const ToolChain &Driver::getOffloadingDeviceToolChain(
6802 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6811 switch (TargetDeviceOffloadKind) {
6813 if (((
Target.getArch() == llvm::Triple::amdgcn ||
6814 Target.getArch() == llvm::Triple::spirv64) &&
6815 Target.getVendor() == llvm::Triple::AMD &&
6816 Target.getOS() == llvm::Triple::AMDHSA) ||
6817 !Args.hasArgNoClaim(options::OPT_offload_EQ))
6818 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6820 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6821 Target.getVendor() == llvm::Triple::UnknownVendor &&
6822 Target.getOS() == llvm::Triple::UnknownOS)
6823 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6828 if (
Target.isSPIROrSPIRV())
6829 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, HostTC,
6836 assert(TC &&
"Could not create offloading device tool chain.");
6842 if (JA.
size() != 1 ||
6847 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6848 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6849 !isa<ExtractAPIJobAction>(JA))
6857 if (JA.
size() != 1 ||
6862 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6863 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
6871 if (Args.hasArg(options::OPT_emit_static_lib))
6882 unsigned &Micro,
bool &HadExtra) {
6885 Major = Minor = Micro = 0;
6889 if (Str.consumeInteger(10, Major))
6893 if (!Str.consume_front(
"."))
6896 if (Str.consumeInteger(10, Minor))
6900 if (!Str.consume_front(
"."))
6903 if (Str.consumeInteger(10, Micro))
6921 unsigned CurDigit = 0;
6922 while (CurDigit < Digits.size()) {
6924 if (Str.consumeInteger(10, Digit))
6926 Digits[CurDigit] = Digit;
6929 if (!Str.consume_front(
"."))
6938llvm::opt::Visibility
6939Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6952const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6968 llvm_unreachable(
"Unhandled Mode");
6972 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6977 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6978 options::OPT_fno_save_optimization_record,
false))
6982 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6983 options::OPT_fno_save_optimization_record,
false))
6987 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6988 options::OPT_fno_save_optimization_record,
false))
6992 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6993 options::OPT_fno_save_optimization_record,
false))
7000 static StringRef OptName =
7002 llvm::StringRef Opt;
7003 for (StringRef Arg : Args) {
7004 if (!Arg.starts_with(OptName))
7010 return Opt.consume_front(OptName) ? Opt :
"";
7017 llvm::BumpPtrAllocator &Alloc,
7018 llvm::vfs::FileSystem *FS) {
7027 for (
const char *F : Args) {
7028 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7030 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7031 RSPQuoting = Windows;
7039 llvm::cl::TokenizerCallback Tokenizer;
7041 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7043 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7045 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7048 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7049 ECtx.setMarkEOLs(MarkEOLs);
7053 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7057 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7058 [](
const char *A) {
return A !=
nullptr; });
7059 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7062 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7063 Args.resize(newEnd - Args.begin());
7067 return llvm::Error::success();
7071 return SavedStrings.insert(S).first->getKeyData();
7104 llvm::StringSet<> &SavedStrings) {
7107 if (Edit[0] ==
'^') {
7108 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7109 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7110 Args.insert(Args.begin() + 1, Str);
7111 }
else if (Edit[0] ==
'+') {
7112 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7113 OS <<
"### Adding argument " << Str <<
" at end\n";
7114 Args.push_back(Str);
7115 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7116 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7117 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7118 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7119 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7121 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7123 if (Args[i] ==
nullptr)
7125 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7127 if (Repl != Args[i]) {
7128 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7132 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7133 auto Option = Edit.substr(1);
7134 for (
unsigned i = 1; i < Args.size();) {
7135 if (Option == Args[i]) {
7136 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7137 Args.erase(Args.begin() + i);
7138 if (Edit[0] ==
'X') {
7139 if (i < Args.size()) {
7140 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7141 Args.erase(Args.begin() + i);
7143 OS <<
"### Invalid X edit, end of command line!\n";
7148 }
else if (Edit[0] ==
'O') {
7149 for (
unsigned i = 1; i < Args.size();) {
7150 const char *A = Args[i];
7154 if (A[0] ==
'-' && A[1] ==
'O' &&
7155 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7156 (
'0' <= A[2] && A[2] <=
'9'))))) {
7157 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7158 Args.erase(Args.begin() + i);
7162 OS <<
"### Adding argument " << Edit <<
" at end\n";
7163 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7165 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7170 const char *OverrideStr,
7171 llvm::StringSet<> &SavedStrings,
7174 OS = &llvm::nulls();
7176 if (OverrideStr[0] ==
'#') {
7178 OS = &llvm::nulls();
7181 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
7185 const char *S = OverrideStr;
7187 const char *End = ::strchr(S,
' ');
7189 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.