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 (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
643 D.Diag(diag::err_drv_unsupported_opt_for_target)
644 << A->getAsString(Args) <<
Target.str();
647 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
648 options::OPT_m32, options::OPT_m16,
649 options::OPT_maix32, options::OPT_maix64);
651 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
653 if (A->getOption().matches(options::OPT_m64) ||
654 A->getOption().matches(options::OPT_maix64)) {
655 AT =
Target.get64BitArchVariant().getArch();
656 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
657 Target.getEnvironment() == llvm::Triple::GNUT64)
658 Target.setEnvironment(llvm::Triple::GNU);
659 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
660 Target.setEnvironment(llvm::Triple::Musl);
661 }
else if (A->getOption().matches(options::OPT_mx32) &&
662 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
663 AT = llvm::Triple::x86_64;
664 if (
Target.getEnvironment() == llvm::Triple::Musl)
665 Target.setEnvironment(llvm::Triple::MuslX32);
667 Target.setEnvironment(llvm::Triple::GNUX32);
668 }
else if (A->getOption().matches(options::OPT_m32) ||
669 A->getOption().matches(options::OPT_maix32)) {
670 AT =
Target.get32BitArchVariant().getArch();
671 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
672 Target.setEnvironment(llvm::Triple::GNU);
673 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
674 Target.setEnvironment(llvm::Triple::Musl);
675 }
else if (A->getOption().matches(options::OPT_m16) &&
676 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
677 AT = llvm::Triple::x86;
678 Target.setEnvironment(llvm::Triple::CODE16);
681 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
683 if (
Target.isWindowsGNUEnvironment())
689 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
690 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
691 D.Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
694 if (A && !A->getOption().matches(options::OPT_m32))
695 D.Diag(diag::err_drv_argument_not_allowed_with)
696 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
698 Target.setArch(llvm::Triple::x86);
699 Target.setArchName(
"i586");
700 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
701 Target.setEnvironmentName(
"");
702 Target.setOS(llvm::Triple::ELFIAMCU);
703 Target.setVendor(llvm::Triple::UnknownVendor);
704 Target.setVendorName(
"intel");
710 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
711 StringRef ABIName = A->getValue();
712 if (ABIName ==
"32") {
714 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
715 Target.getEnvironment() == llvm::Triple::GNUABIN32)
716 Target.setEnvironment(llvm::Triple::GNU);
717 }
else if (ABIName ==
"n32") {
719 if (
Target.getEnvironment() == llvm::Triple::GNU ||
720 Target.getEnvironment() == llvm::Triple::GNUT64 ||
721 Target.getEnvironment() == llvm::Triple::GNUABI64)
722 Target.setEnvironment(llvm::Triple::GNUABIN32);
723 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
724 Target.getEnvironment() == llvm::Triple::MuslABI64)
725 Target.setEnvironment(llvm::Triple::MuslABIN32);
726 }
else if (ABIName ==
"64") {
728 if (
Target.getEnvironment() == llvm::Triple::GNU ||
729 Target.getEnvironment() == llvm::Triple::GNUT64 ||
730 Target.getEnvironment() == llvm::Triple::GNUABIN32)
731 Target.setEnvironment(llvm::Triple::GNUABI64);
732 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
733 Target.getEnvironment() == llvm::Triple::MuslABIN32)
734 Target.setEnvironment(llvm::Triple::MuslABI64);
742 if (Args.hasArg(options::OPT_march_EQ) ||
743 Args.hasArg(options::OPT_mcpu_EQ)) {
745 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
747 if (!llvm::errorToBool(ISAInfo.takeError())) {
748 unsigned XLen = (*ISAInfo)->getXLen();
750 Target.setArch(llvm::Triple::riscv32);
752 Target.setArch(llvm::Triple::riscv64);
764 OptSpecifier OptEq, OptSpecifier OptNeg) {
765 if (!Args.hasFlag(OptEq, OptNeg,
false))
768 const Arg *A = Args.getLastArg(OptEq);
769 StringRef LTOName = A->getValue();
777 D.Diag(diag::err_drv_unsupported_option_argument)
778 << A->getSpelling() << A->getValue();
785void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
787 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
789 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
790 options::OPT_fno_offload_lto);
793 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
794 options::OPT_fno_openmp_target_jit,
false)) {
795 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
796 options::OPT_fno_offload_lto))
798 Diag(diag::err_drv_incompatible_options)
799 << A->getSpelling() <<
"-fopenmp-target-jit";
806 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
808 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
810 RuntimeName = A->getValue();
812 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
820 Diag(diag::err_drv_unsupported_option_argument)
821 << A->getSpelling() << A->getValue();
824 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
833 if (llvm::is_contained(SYCLAlias, TargetArch)) {
834 llvm::Triple TargetTriple;
835 TargetTriple.setArchName(TargetArch);
836 TargetTriple.setVendor(llvm::Triple::UnknownVendor);
837 TargetTriple.setOS(llvm::Triple::UnknownOS);
840 return llvm::Triple(TargetArch);
846 for (
const auto &SYCLTriple : SYCLTriples) {
847 if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
848 SYCLTriple.isSPIROrSPIRV())
853 C.getDefaultToolChain().getTriple().isArch32Bit() ?
"spirv32"
855 SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple);
868 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
873 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
876 C.getInputArgs().hasArg(options::OPT_hip_link) ||
877 C.getInputArgs().hasArg(options::OPT_hipstdpar);
878 bool UseLLVMOffload =
C.getInputArgs().hasArg(
879 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
880 if (IsCuda && IsHIP) {
881 Diag(clang::diag::err_drv_mix_cuda_hip);
884 if (IsCuda && !UseLLVMOffload) {
886 const llvm::Triple &HostTriple = HostTC->
getTriple();
894 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
896 CudaTC = std::make_unique<toolchains::CudaToolChain>(
897 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
902 if (CudaInstallation.
isValid())
905 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
906 }
else if (IsHIP && !UseLLVMOffload) {
907 if (
auto *OMPTargetArg =
908 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
909 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
910 << OMPTargetArg->getSpelling() <<
"HIP";
918 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
920 C.addOffloadDeviceToolChain(HIPTC, OFK);
931 bool IsOpenMPOffloading =
932 ((IsCuda || IsHIP) && UseLLVMOffload) ||
933 (
C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
934 options::OPT_fno_openmp,
false) &&
935 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
936 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ)));
937 if (IsOpenMPOffloading) {
943 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
947 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
948 llvm::StringMap<StringRef> FoundNormalizedTriples;
949 std::multiset<StringRef> OpenMPTriples;
954 if (Arg *OpenMPTargets =
955 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
956 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
957 Diag(clang::diag::warn_drv_empty_joined_argument)
958 << OpenMPTargets->getAsString(
C.getInputArgs());
961 for (StringRef
T : OpenMPTargets->getValues())
962 OpenMPTriples.insert(
T);
963 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
964 ((!IsHIP && !IsCuda) || UseLLVMOffload)) {
974 llvm::DenseSet<StringRef> Archs;
976 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
977 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
983 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
984 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
989 if (!AMDTriple && !NVPTXTriple) {
990 for (StringRef Arch :
995 for (StringRef Arch : Archs) {
998 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
999 }
else if (AMDTriple &&
1002 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
1004 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
1010 if (Archs.empty()) {
1011 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1016 for (
const auto &TripleAndArchs : DerivedArchs)
1017 OpenMPTriples.insert(TripleAndArchs.first());
1020 for (StringRef Val : OpenMPTriples) {
1022 std::string NormalizedName = TT.normalize();
1025 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
1026 if (Duplicate != FoundNormalizedTriples.end()) {
1027 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1028 << Val << Duplicate->second;
1034 FoundNormalizedTriples[NormalizedName] = Val;
1037 if (TT.getArch() == llvm::Triple::UnknownArch)
1038 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
1043 if (TT.isNVPTX() || TT.isAMDGCN() || TT.isSPIRV()) {
1046 assert(HostTC &&
"Host toolchain should be always defined.");
1048 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
1051 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
1052 *
this, TT, *HostTC,
C.getInputArgs());
1053 else if (TT.isAMDGCN())
1054 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
1055 *
this, TT, *HostTC,
C.getInputArgs());
1056 else if (TT.isSPIRV())
1057 DeviceTC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(
1058 *
this, TT, *HostTC,
C.getInputArgs());
1060 assert(DeviceTC &&
"Device toolchain not defined.");
1063 TC = DeviceTC.get();
1065 TC = &getToolChain(
C.getInputArgs(), TT);
1067 auto It = DerivedArchs.find(TT.getTriple());
1068 if (It != DerivedArchs.end())
1069 KnownArchs[TC] = It->second;
1072 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
1073 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1078 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1079 options::OPT_fno_sycl,
false);
1081 auto argSYCLIncompatible = [&](OptSpecifier OptId) {
1084 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(OptId))
1085 Diag(clang::diag::err_drv_argument_not_allowed_with)
1086 << IncompatArg->getSpelling() <<
"-fsycl";
1089 argSYCLIncompatible(options::OPT_static_libstdcxx);
1091 argSYCLIncompatible(options::OPT_ffreestanding);
1102 for (
const auto &TargetTriple : UniqueSYCLTriplesVec) {
1103 auto SYCLTC = &getOffloadingDeviceToolChain(
1114bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1119 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1123 if (!PathLIBEnv.empty()) {
1124 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1125 if (llvm::sys::fs::is_directory(PathLIBEnv))
1126 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1127 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1128 return readConfigFile(CustomizationFile, ExpCtx);
1129 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1134 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1135 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1136 return readConfigFile(CustomizationFile, ExpCtx);
1146 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1147 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1148 Copy->getValues() = Opt->getValues();
1149 if (Opt->isClaimed())
1151 Copy->setOwnsValues(Opt->getOwnsValues());
1152 Opt->setOwnsValues(
false);
1154 if (Opt->getAlias()) {
1155 const Arg *Alias = Opt->getAlias();
1156 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1157 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1158 Args.getArgString(Index), Index);
1159 AliasCopy->getValues() = Alias->getValues();
1160 AliasCopy->setOwnsValues(
false);
1161 if (Alias->isClaimed())
1163 Copy->setAlias(std::move(AliasCopy));
1167bool Driver::readConfigFile(StringRef
FileName,
1168 llvm::cl::ExpansionContext &ExpCtx) {
1172 Diag(diag::err_drv_cannot_open_config_file)
1173 <<
FileName << Status.getError().message();
1176 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1177 Diag(diag::err_drv_cannot_open_config_file)
1178 <<
FileName <<
"not a regular file";
1184 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1185 Diag(diag::err_drv_cannot_read_config_file)
1192 for (
const char *Opt : NewCfgFileArgs) {
1194 if (Opt[0] ==
'$' && Opt[1])
1195 NewCfgTailArgs.push_back(Opt + 1);
1197 NewCfgHeadArgs.push_back(Opt);
1202 llvm::sys::path::native(CfgFileName);
1203 bool ContainErrors =
false;
1204 auto NewHeadOptions = std::make_unique<InputArgList>(
1208 auto NewTailOptions = std::make_unique<InputArgList>(
1215 for (Arg *A : *NewHeadOptions)
1217 for (Arg *A : *NewTailOptions)
1220 if (!CfgOptionsHead)
1221 CfgOptionsHead = std::move(NewHeadOptions);
1224 for (
auto *Opt : *NewHeadOptions)
1228 if (!CfgOptionsTail)
1229 CfgOptionsTail = std::move(NewTailOptions);
1232 for (
auto *Opt : *NewTailOptions)
1236 ConfigFiles.push_back(std::string(CfgFileName));
1240bool Driver::loadConfigFiles() {
1241 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1242 llvm::cl::tokenizeConfigFile);
1243 ExpCtx.setVFS(&
getVFS());
1247 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1250 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1251 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1256 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1258 llvm::sys::fs::expand_tilde(
1259 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1260 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1269 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1272 if (loadDefaultConfigFiles(ExpCtx))
1278 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1281 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1282 CfgFilePath.assign(CfgFileName);
1283 if (llvm::sys::path::is_relative(CfgFilePath)) {
1284 if (
getVFS().makeAbsolute(CfgFilePath)) {
1285 Diag(diag::err_drv_cannot_open_config_file)
1286 << CfgFilePath <<
"cannot get absolute path";
1290 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1292 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1293 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1294 if (!SearchDir.empty())
1295 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1300 if (readConfigFile(CfgFilePath, ExpCtx))
1311 llvm::Triple Triple, std::string Suffix) {
1313 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1317 VersionTuple OSVersion = Triple.getOSVersion();
1318 if (!OSVersion.getMinor().has_value())
1321 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1325 if (OSVersion.getMajor() != 0) {
1326 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1327 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1333 Triple.setOSName(BaseOSName);
1334 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1337bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1340 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1344 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1347 std::string RealMode = getExecutableForDriverMode(Mode);
1348 llvm::Triple Triple;
1357 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1358 PrefixTriple.isOSUnknown())
1359 Triple = PrefixTriple;
1363 llvm::Triple RealTriple =
1365 if (Triple.str().empty()) {
1366 Triple = RealTriple;
1367 assert(!Triple.str().empty());
1372 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1388 "-" + RealMode +
".cfg"))
1389 return readConfigFile(CfgFilePath, ExpCtx);
1393 if (TryModeSuffix) {
1396 return readConfigFile(CfgFilePath, ExpCtx);
1401 std::string CfgFileName = RealMode +
".cfg";
1402 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1403 if (readConfigFile(CfgFilePath, ExpCtx))
1405 }
else if (TryModeSuffix) {
1407 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1408 readConfigFile(CfgFilePath, ExpCtx))
1414 return readConfigFile(CfgFilePath, ExpCtx);
1422 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1431 if (!DriverMode.empty())
1432 setDriverMode(DriverMode);
1438 CLOptions = std::make_unique<InputArgList>(
1443 ContainsError = loadConfigFiles();
1444 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1445 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1449 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1451 if (HasConfigFileHead)
1452 for (
auto *Opt : *CLOptions)
1453 if (!Opt->getOption().matches(options::OPT_config))
1457 if (
IsCLMode() && !ContainsError) {
1459 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1461 CLModePassThroughArgList.push_back(A->getValue());
1464 if (!CLModePassThroughArgList.empty()) {
1467 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1472 for (
auto *Opt : *CLModePassThroughOptions)
1478 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1479 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1480 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1484 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1485 if (!VFS->exists(IncludeDir))
1486 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1491 bool CCCPrintPhases;
1494 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1495 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1498 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1499 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1502 Args.ClaimAllArgs(options::OPT_pipe);
1510 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1512 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1513 CCCGenericGCCName = A->getValue();
1516 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1520 if (Args.hasArg(options::OPT_fproc_stat_report))
1527 llvm::Triple
T(TargetTriple);
1528 T.setOS(llvm::Triple::Win32);
1529 T.setVendor(llvm::Triple::PC);
1530 T.setEnvironment(llvm::Triple::MSVC);
1531 T.setObjectFormat(llvm::Triple::COFF);
1532 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1533 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1534 TargetTriple =
T.str();
1537 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1538 StringRef TargetProfile = A->getValue();
1541 TargetTriple = *Triple;
1543 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1547 if (Args.hasArg(options::OPT_spirv)) {
1548 llvm::Triple
T(TargetTriple);
1549 T.setArch(llvm::Triple::spirv);
1550 T.setOS(llvm::Triple::Vulkan);
1553 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1554 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1555 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1556 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1558 auto TargetInfo = ValidTargets.find(A->getValue());
1561 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1563 Diag(diag::err_drv_invalid_value)
1564 << A->getAsString(Args) << A->getValue();
1569 TargetTriple =
T.str();
1572 Diag(diag::err_drv_dxc_missing_target_profile);
1576 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1577 TargetTriple = A->getValue();
1578 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1579 Dir =
Dir = A->getValue();
1580 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1584 if (std::optional<std::string> CompilerPathValue =
1585 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1586 StringRef CompilerPath = *CompilerPathValue;
1587 while (!CompilerPath.empty()) {
1588 std::pair<StringRef, StringRef> Split =
1589 CompilerPath.split(llvm::sys::EnvPathSeparator);
1590 PrefixDirs.push_back(std::string(Split.first));
1591 CompilerPath = Split.second;
1594 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1596 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1599 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1602 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1603 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1604 .Case(
"cwd", SaveTempsCwd)
1605 .Case(
"obj", SaveTempsObj)
1606 .Default(SaveTempsCwd);
1609 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1610 options::OPT_offload_device_only,
1611 options::OPT_offload_host_device)) {
1612 if (A->getOption().matches(options::OPT_offload_host_only))
1613 Offload = OffloadHost;
1614 else if (A->getOption().matches(options::OPT_offload_device_only))
1615 Offload = OffloadDevice;
1617 Offload = OffloadHostDevice;
1623 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1624 StringRef
Name = A->getValue();
1625 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1626 .Case(
"off", EmbedNone)
1627 .Case(
"all", EmbedBitcode)
1628 .Case(
"bitcode", EmbedBitcode)
1629 .Case(
"marker", EmbedMarker)
1632 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1635 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1639 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1640 llvm::sys::fs::remove(A->getValue());
1646 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1648 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1649 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1650 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1651 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1652 Std->containsValue(
"c++latest"));
1655 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1656 options::OPT_fmodule_header)) {
1658 ModulesModeCXX20 =
true;
1659 if (A->getOption().matches(options::OPT_fmodule_header))
1662 StringRef ArgName = A->getValue();
1663 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1668 Diags.
Report(diag::err_drv_invalid_value)
1669 << A->getAsString(Args) << ArgName;
1675 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1676 std::make_unique<InputArgList>(std::move(Args));
1686 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1687 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1689 bool MLContainsError;
1690 auto MultilibMacroDefineList =
1692 MLMacroDefinesChar,
false, MLContainsError));
1693 if (!MLContainsError) {
1694 for (
auto *Opt : *MultilibMacroDefineList) {
1701 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1705 if (!Triple.isWasm()) {
1706 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1707 StringRef TripleObjectFormat =
1708 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1709 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1710 TripleVersionName != TripleObjectFormat) {
1711 Diags.
Report(diag::err_drv_triple_version_invalid)
1713 ContainsError =
true;
1718 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1719 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1720 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1728 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1729 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1731 case llvm::Triple::arm:
1732 case llvm::Triple::armeb:
1733 case llvm::Triple::thumb:
1734 case llvm::Triple::thumbeb:
1735 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1736 Diag(diag::warn_target_unrecognized_env)
1738 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1741 case llvm::Triple::aarch64:
1742 case llvm::Triple::aarch64_be:
1743 case llvm::Triple::aarch64_32:
1744 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1745 Diag(diag::warn_target_unrecognized_env)
1747 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1764 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1765 if (HasConfigFileTail && Inputs.size()) {
1768 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1769 for (Arg *A : *CfgOptionsTail)
1770 TranslatedLinkerIns.append(A);
1771 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1780 if (TC.
getTriple().isOSBinFormatMachO())
1785 if (CCCPrintPhases) {
1796 llvm::opt::ArgStringList ASL;
1797 for (
const auto *A : Args) {
1801 while (A->getAlias())
1803 A->render(Args, ASL);
1806 for (
auto I = ASL.begin(),
E = ASL.end(); I !=
E; ++I) {
1807 if (I != ASL.begin())
1809 llvm::sys::printArg(OS, *I,
true);
1814bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1816 using namespace llvm::sys;
1817 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1818 "Only knows about .crash files on Darwin");
1823 path::home_directory(CrashDiagDir);
1824 if (CrashDiagDir.starts_with(
"/var/root"))
1826 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1834 fs::file_status FileStatus;
1835 TimePoint<> LastAccessTime;
1839 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1840 File != FileEnd && !EC;
File.increment(EC)) {
1844 if (fs::status(
File->path(), FileStatus))
1846 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1847 llvm::MemoryBuffer::getFile(
File->path());
1852 StringRef
Data = CrashFile.get()->getBuffer();
1853 if (!
Data.starts_with(
"Process:"))
1856 size_t ParentProcPos =
Data.find(
"Parent Process:");
1857 if (ParentProcPos == StringRef::npos)
1859 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1860 if (LineEnd == StringRef::npos)
1862 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1863 int OpenBracket = -1, CloseBracket = -1;
1864 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1865 if (ParentProcess[i] ==
'[')
1867 if (ParentProcess[i] ==
']')
1873 if (OpenBracket < 0 || CloseBracket < 0 ||
1874 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1875 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1885 const auto FileAccessTime = FileStatus.getLastModificationTime();
1886 if (FileAccessTime > LastAccessTime) {
1887 CrashFilePath.assign(
File->path());
1888 LastAccessTime = FileAccessTime;
1893 if (!CrashFilePath.empty()) {
1894 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1904 "\n********************\n\n"
1905 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1906 "Preprocessed source(s) and associated run script(s) are located at:";
1914 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1918 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1919 Level = llvm::StringSwitch<unsigned>(A->getValue())
1921 .Case(
"compiler", 1)
1933 ArgStringList SavedTemps;
1935 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1936 if (!IsLLD || Level < 2)
1943 SavedTemps = std::move(
C.getTempFiles());
1944 assert(!
C.getTempFiles().size());
1961 C.initCompilationForDiagnostics();
1967 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1968 StringRef ReproduceOption =
1969 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1972 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1976 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1978 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1979 Diag(clang::diag::note_drv_command_failed_diag_msg)
1980 <<
"\n\n********************";
1982 Report->TemporaryFiles.push_back(TmpName);
1990 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1991 bool IgnoreInput =
false;
1997 }
else if (!strcmp(it->second->getValue(),
"-")) {
1998 Diag(clang::diag::note_drv_command_failed_diag_msg)
1999 <<
"Error generating preprocessed source(s) - "
2000 "ignoring input from stdin.";
2005 it = Inputs.erase(it);
2012 if (Inputs.empty()) {
2013 Diag(clang::diag::note_drv_command_failed_diag_msg)
2014 <<
"Error generating preprocessed source(s) - "
2015 "no preprocessable inputs.";
2021 llvm::StringSet<> ArchNames;
2022 for (
const Arg *A :
C.getArgs()) {
2023 if (A->getOption().matches(options::OPT_arch)) {
2024 StringRef ArchName = A->getValue();
2025 ArchNames.insert(ArchName);
2028 if (ArchNames.size() > 1) {
2029 Diag(clang::diag::note_drv_command_failed_diag_msg)
2030 <<
"Error generating preprocessed source(s) - cannot generate "
2031 "preprocessed source with multiple -arch options.";
2037 const ToolChain &TC =
C.getDefaultToolChain();
2038 if (TC.
getTriple().isOSBinFormatMachO())
2047 Diag(clang::diag::note_drv_command_failed_diag_msg)
2048 <<
"Error generating preprocessed source(s).";
2054 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2057 if (!FailingCommands.empty()) {
2058 Diag(clang::diag::note_drv_command_failed_diag_msg)
2059 <<
"Error generating preprocessed source(s).";
2063 const ArgStringList &TempFiles =
C.getTempFiles();
2064 if (TempFiles.empty()) {
2065 Diag(clang::diag::note_drv_command_failed_diag_msg)
2066 <<
"Error generating preprocessed source(s).";
2074 for (
const char *TempFile : TempFiles) {
2075 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2077 Report->TemporaryFiles.push_back(TempFile);
2078 if (ReproCrashFilename.empty()) {
2079 ReproCrashFilename = TempFile;
2080 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2082 if (StringRef(TempFile).ends_with(
".cache")) {
2085 VFS = llvm::sys::path::filename(TempFile);
2086 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2090 for (
const char *TempFile : SavedTemps)
2091 C.addTempFile(TempFile);
2097 llvm::sys::path::replace_extension(Script,
"sh");
2099 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2100 llvm::sys::fs::FA_Write,
2101 llvm::sys::fs::OF_Text);
2103 Diag(clang::diag::note_drv_command_failed_diag_msg)
2104 <<
"Error generating run script: " << Script <<
" " << EC.message();
2107 <<
"# Driver args: ";
2109 ScriptOS <<
"# Original command: ";
2110 Cmd.Print(ScriptOS,
"\n",
true);
2111 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
2112 if (!AdditionalInformation.empty())
2113 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2116 Report->TemporaryFiles.push_back(std::string(Script));
2117 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2121 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2123 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2124 Diag(clang::diag::note_drv_command_failed_diag_msg)
2125 << ReproCrashFilename.str();
2127 llvm::sys::path::append(CrashDiagDir,
Name);
2128 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2129 Diag(clang::diag::note_drv_command_failed_diag_msg)
2130 <<
"Crash backtrace is located in";
2131 Diag(clang::diag::note_drv_command_failed_diag_msg)
2132 << CrashDiagDir.str();
2133 Diag(clang::diag::note_drv_command_failed_diag_msg)
2134 <<
"(choose the .crash file that corresponds to your crash)";
2138 Diag(clang::diag::note_drv_command_failed_diag_msg)
2139 <<
"\n\n********************";
2147 if (
Cmd.getResponseFileSupport().ResponseKind ==
2149 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
2150 Cmd.getArguments()))
2154 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
2160 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2161 if (
C.getArgs().hasArg(options::OPT_v))
2162 C.getJobs().Print(llvm::errs(),
"\n",
true);
2164 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2174 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2175 C.getJobs().Print(llvm::errs(),
"\n",
true);
2184 for (
auto &Job :
C.getJobs())
2185 setUpResponseFiles(
C, Job);
2187 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2190 if (FailingCommands.empty())
2196 for (
const auto &CmdPair : FailingCommands) {
2197 int CommandRes = CmdPair.first;
2198 const Command *FailingCommand = CmdPair.second;
2203 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2207 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2212 if (CommandRes == EX_IOERR) {
2229 Diag(clang::diag::err_drv_command_signalled)
2232 Diag(clang::diag::err_drv_command_failed)
2240 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2242 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2256 const ToolChain &TC =
C.getDefaultToolChain();
2260 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2263 OS <<
"Thread model: " << A->getValue();
2269 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2274 if (!llvm::cl::getCompilerBuildConfig().empty())
2275 llvm::cl::printBuildConfig(OS);
2278 for (
auto ConfigFile : ConfigFiles)
2279 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2292 if (PassedFlags ==
"")
2296 std::vector<std::string> SuggestedCompletions;
2297 std::vector<std::string> Flags;
2309 const bool HasSpace = PassedFlags.ends_with(
",");
2313 StringRef TargetFlags = PassedFlags;
2314 while (TargetFlags !=
"") {
2316 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2317 Flags.push_back(std::string(CurFlag));
2322 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2325 const llvm::opt::OptTable &Opts =
getOpts();
2327 Cur = Flags.at(Flags.size() - 1);
2329 if (Flags.size() >= 2) {
2330 Prev = Flags.at(Flags.size() - 2);
2331 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2334 if (SuggestedCompletions.empty())
2335 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2342 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2343 llvm::outs() <<
'\n';
2349 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2353 SuggestedCompletions = Opts.findByPrefix(
2354 Cur, VisibilityMask,
2361 if (S.starts_with(Cur))
2362 SuggestedCompletions.push_back(std::string(S));
2369 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2370 if (
int X = A.compare_insensitive(B))
2372 return A.compare(B) > 0;
2375 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2382 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2383 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2387 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2390 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2394 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2399 if (
C.getArgs().hasArg(options::OPT_help) ||
2400 C.getArgs().hasArg(options::OPT__help_hidden)) {
2401 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2405 if (
C.getArgs().hasArg(options::OPT__version)) {
2411 if (
C.getArgs().hasArg(options::OPT_v) ||
2412 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2413 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2414 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2415 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2417 SuppressMissingInputWarning =
true;
2420 if (
C.getArgs().hasArg(options::OPT_v)) {
2422 llvm::errs() <<
"System configuration file directory: "
2425 llvm::errs() <<
"User configuration file directory: "
2429 const ToolChain &TC =
C.getDefaultToolChain();
2431 if (
C.getArgs().hasArg(options::OPT_v))
2434 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2439 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2440 llvm::outs() <<
"programs: =";
2441 bool separator =
false;
2445 llvm::outs() << llvm::sys::EnvPathSeparator;
2446 llvm::outs() <<
Path;
2451 llvm::outs() << llvm::sys::EnvPathSeparator;
2452 llvm::outs() <<
Path;
2455 llvm::outs() <<
"\n";
2458 StringRef sysroot =
C.getSysRoot();
2462 llvm::outs() << llvm::sys::EnvPathSeparator;
2465 llvm::outs() << sysroot <<
Path.substr(1);
2467 llvm::outs() <<
Path;
2469 llvm::outs() <<
"\n";
2473 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2479 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2480 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2481 llvm::outs() << *RuntimePath <<
'\n';
2487 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2489 for (std::size_t I = 0; I != Flags.size(); I += 2)
2490 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2496 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2497 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2501 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2502 StringRef ProgName = A->getValue();
2505 if (! ProgName.empty())
2508 llvm::outs() <<
"\n";
2512 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2513 StringRef PassedFlags = A->getValue();
2518 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2532 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2535 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2541 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2548 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2551 std::set<llvm::StringRef> SortedFlags;
2552 for (
const auto &FlagEntry : ExpandedFlags)
2553 SortedFlags.insert(FlagEntry.getKey());
2554 for (
auto Flag : SortedFlags)
2555 llvm::outs() << Flag <<
'\n';
2559 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2562 llvm::outs() <<
".\n";
2565 assert(Suffix.front() ==
'/');
2566 llvm::outs() << Suffix.substr(1) <<
"\n";
2572 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2577 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2579 llvm::outs() << Triple.getTriple() <<
"\n";
2583 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2584 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2601 std::map<Action *, unsigned> &Ids,
2603 if (
auto It = Ids.find(A); It != Ids.end())
2607 llvm::raw_string_ostream os(str);
2609 auto getSibIndent = [](
int K) -> Twine {
2613 Twine SibIndent = Indent + getSibIndent(Kind);
2617 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2619 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2620 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2621 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2622 bool IsFirst =
true;
2623 OA->doOnEachDependence(
2625 assert(TC &&
"Unknown host toolchain");
2637 os <<
":" << BoundArch;
2640 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2648 const char *Prefix =
"{";
2649 for (
Action *PreRequisite : *AL) {
2650 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2661 std::string offload_str;
2662 llvm::raw_string_ostream offload_os(offload_str);
2663 if (!isa<OffloadAction>(A)) {
2666 offload_os <<
", (" << S;
2673 auto getSelfIndent = [](
int K) -> Twine {
2677 unsigned Id = Ids.size();
2679 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2688 std::map<Action *, unsigned> Ids;
2689 for (
Action *A :
C.getActions())
2696 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2697 isa<AssembleJobAction>(A))
2705 DerivedArgList &Args =
C.getArgs();
2707 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2710 llvm::StringSet<> ArchNames;
2712 for (Arg *A : Args) {
2713 if (A->getOption().matches(options::OPT_arch)) {
2716 llvm::Triple::ArchType Arch =
2718 if (Arch == llvm::Triple::UnknownArch) {
2719 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2724 if (ArchNames.insert(A->getValue()).second)
2725 Archs.push_back(A->getValue());
2739 for (
Action* Act : SingleActions) {
2747 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2751 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2756 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2757 Actions.append(Inputs.begin(), Inputs.end());
2759 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2762 Arg *A = Args.getLastArg(options::OPT_g_Group);
2763 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2764 !A->getOption().matches(options::OPT_gstabs);
2772 if (Act->getType() == types::TY_Image) {
2774 Inputs.push_back(Actions.back());
2781 if (Args.hasArg(options::OPT_verify_debug_info)) {
2782 Action* LastAction = Actions.back();
2785 LastAction, types::TY_Nothing));
2804 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2805 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2817 std::string Nearest;
2818 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2819 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2820 <<
Value << Nearest;
2859 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2862 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2870 return types::TY_CXXUHeader;
2872 return types::TY_CXXSHeader;
2876 llvm_unreachable(
"should not be called in this case");
2878 return types::TY_CXXHUHeader;
2884 const llvm::opt::OptTable &Opts =
getOpts();
2888 types::ID InputType = types::TY_Nothing;
2889 Arg *InputTypeArg =
nullptr;
2892 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2893 options::OPT__SLASH_TP)) {
2894 InputTypeArg = TCTP;
2895 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2900 bool ShowNote =
false;
2902 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2904 Diag(clang::diag::warn_drv_overriding_option)
2905 <<
Previous->getSpelling() << A->getSpelling();
2911 Diag(clang::diag::note_drv_t_option_is_global);
2916 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2917 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2918 if (LastXArg && LastInputArg &&
2919 LastInputArg->getIndex() < LastXArg->getIndex())
2920 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2923 for (Arg *A : Args) {
2924 if (A->getOption().
getKind() == Option::InputClass) {
2925 const char *
Value = A->getValue();
2929 if (InputType == types::TY_Nothing) {
2932 InputTypeArg->claim();
2935 if (memcmp(
Value,
"-", 2) == 0) {
2937 Ty = types::TY_Fortran;
2939 Ty = types::TY_HLSL;
2948 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2949 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2950 : clang::diag::err_drv_unknown_stdin_type);
2959 if (
const char *Ext = strrchr(
Value,
'.'))
2968 Ty = types::TY_Object;
2979 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2980 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2981 << getTypeName(OldTy) << getTypeName(Ty);
2986 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2987 Ty == types::TY_Object)
2988 Ty = types::TY_LLVM_BC;
2996 if (Ty != types::TY_Object) {
2997 if (Args.hasArg(options::OPT_ObjC))
2998 Ty = types::TY_ObjC;
2999 else if (Args.hasArg(options::OPT_ObjCXX))
3000 Ty = types::TY_ObjCXX;
3007 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3011 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3012 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3015 const char *Ext = strrchr(
Value,
'.');
3017 Ty = types::TY_Object;
3021 InputTypeArg->claim();
3025 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3026 Args.hasArgNoClaim(options::OPT_hipstdpar))
3030 Inputs.push_back(std::make_pair(Ty, A));
3032 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3033 StringRef
Value = A->getValue();
3036 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3037 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3040 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3041 StringRef
Value = A->getValue();
3044 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3045 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3051 Inputs.push_back(std::make_pair(types::TY_Object, A));
3053 }
else if (A->getOption().matches(options::OPT_x)) {
3062 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3063 InputType = types::TY_Object;
3070 }
else if (A->getOption().getID() == options::OPT_U) {
3071 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3072 StringRef Val = A->getValue(0);
3073 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3075 Diag(diag::warn_slash_u_filename) << Val;
3076 Diag(diag::note_use_dashdash);
3080 if (
CCCIsCPP() && Inputs.empty()) {
3084 Inputs.push_back(std::make_pair(types::TY_C, A));
3091class OffloadingActionBuilder final {
3093 bool IsValid =
false;
3099 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3102 std::map<Action *, const Arg *> HostActionToInputArgMap;
3105 class DeviceActionBuilder {
3109 enum ActionBuilderReturnCode {
3128 DerivedArgList &Args;
3137 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3140 :
C(
C), Args(Args), Inputs(Inputs),
3141 AssociatedOffloadKind(AssociatedOffloadKind) {}
3142 virtual ~DeviceActionBuilder() {}
3147 virtual ActionBuilderReturnCode
3151 return ABRT_Inactive;
3156 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
3157 return ABRT_Inactive;
3161 virtual void appendTopLevelActions(
ActionList &AL) {}
3164 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3177 virtual bool canUseBundlerUnbundler()
const {
return false; }
3181 bool isValid() {
return !ToolChains.empty(); }
3185 return AssociatedOffloadKind;
3191 class CudaActionBuilderBase :
public DeviceActionBuilder {
3195 bool CompileHostOnly =
false;
3196 bool CompileDeviceOnly =
false;
3198 bool EmitAsm =
false;
3208 TargetID(
const char *
ID) :
ID(
ID) {}
3209 operator const char *() {
return ID; }
3210 operator StringRef() {
return StringRef(
ID); }
3219 Action *CudaFatBinary =
nullptr;
3222 bool IsActive =
false;
3225 bool Relocatable =
false;
3228 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3234 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
3237 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3238 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3240 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3241 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3242 options::OPT_fno_gpu_rdc,
false);
3245 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3252 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3253 assert(!GpuArchList.empty() &&
3254 "We should have at least one GPU architecture.");
3258 if (!(IA->getType() == types::TY_CUDA ||
3259 IA->getType() == types::TY_HIP ||
3260 IA->getType() == types::TY_PP_HIP)) {
3263 return ABRT_Inactive;
3270 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3272 if (CompileHostOnly)
3273 return ABRT_Success;
3276 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3277 : types::TY_CUDA_DEVICE;
3278 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3279 CudaDeviceActions.push_back(
3280 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3283 return ABRT_Success;
3287 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3291 if (UA->getType() == types::TY_Object && !Relocatable)
3292 return ABRT_Inactive;
3294 CudaDeviceActions.clear();
3295 auto *IA = cast<InputAction>(UA->getInputs().back());
3296 std::string
FileName = IA->getInputArg().getAsString(Args);
3302 const StringRef LibFileExt =
".lib";
3303 if (IA->getType() == types::TY_Object &&
3304 (!llvm::sys::path::has_extension(
FileName) ||
3306 llvm::sys::path::extension(
FileName).drop_front()) !=
3308 llvm::sys::path::extension(
FileName) == LibFileExt))
3309 return ABRT_Inactive;
3311 for (
auto Arch : GpuArchList) {
3312 CudaDeviceActions.push_back(UA);
3313 UA->registerDependentActionInfo(ToolChains[0], Arch,
3314 AssociatedOffloadKind);
3317 return ABRT_Success;
3320 return IsActive ? ABRT_Success : ABRT_Inactive;
3323 void appendTopLevelActions(
ActionList &AL)
override {
3325 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3327 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3332 if (CudaFatBinary) {
3333 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3334 CudaDeviceActions.clear();
3335 CudaFatBinary =
nullptr;
3339 if (CudaDeviceActions.empty())
3345 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3346 "Expecting one action per GPU architecture.");
3347 assert(ToolChains.size() == 1 &&
3348 "Expecting to have a single CUDA toolchain.");
3349 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I)
3350 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3352 CudaDeviceActions.clear();
3357 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3359 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3377 assert(HostTC &&
"No toolchain for host compilation.");
3379 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3383 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3388 ToolChains.push_back(
3393 CompileHostOnly =
C.getDriver().offloadHostOnly();
3394 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3395 EmitAsm = Args.getLastArg(options::OPT_S);
3398 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3399 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3400 options::OPT_no_offload_arch_EQ)) {
3401 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3406 std::set<StringRef> GpuArchs;
3408 for (Arg *A : Args) {
3409 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3410 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3414 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3415 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3418 }
else if (ArchStr ==
"native") {
3419 const ToolChain &TC = *ToolChains.front();
3420 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3423 << llvm::Triple::getArchTypeName(TC.
getArch())
3424 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3428 for (
auto GPU : *GPUsOrErr) {
3429 GpuArchs.insert(Args.MakeArgString(GPU));
3432 ArchStr = getCanonicalOffloadArch(ArchStr);
3433 if (ArchStr.empty()) {
3435 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3436 GpuArchs.insert(ArchStr);
3437 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3438 GpuArchs.erase(ArchStr);
3440 llvm_unreachable(
"Unexpected option.");
3446 if (ConflictingArchs) {
3447 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3448 << ConflictingArchs->first << ConflictingArchs->second;
3449 C.setContainsError();
3454 for (
auto Arch : GpuArchs)
3455 GpuArchList.push_back(Arch.data());
3460 if (GpuArchList.empty()) {
3461 if (ToolChains.front()->getTriple().isSPIRV()) {
3462 if (ToolChains.front()->getTriple().getVendor() == llvm::Triple::AMD)
3463 GpuArchList.push_back(OffloadArch::AMDGCNSPIRV);
3465 GpuArchList.push_back(OffloadArch::Generic);
3467 GpuArchList.push_back(DefaultOffloadArch);
3477 class CudaActionBuilder final :
public CudaActionBuilderBase {
3479 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3481 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3482 DefaultOffloadArch = OffloadArch::CudaDefault;
3485 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3488 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3494 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3496 const std::set<StringRef> &GpuArchs)
override {
3497 return std::nullopt;
3500 ActionBuilderReturnCode
3503 PhasesTy &Phases)
override {
3505 return ABRT_Inactive;
3509 if (CudaDeviceActions.empty())
3510 return ABRT_Success;
3512 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3513 "Expecting one action per GPU architecture.");
3514 assert(!CompileHostOnly &&
3515 "Not expecting CUDA actions in host-only compilation.");
3525 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3528 for (
auto Ph : Phases) {
3533 if (Ph > FinalPhase)
3536 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3546 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3550 Action *AssembleAction = CudaDeviceActions[I];
3551 assert(AssembleAction->
getType() == types::TY_Object);
3552 assert(AssembleAction->
getInputs().size() == 1);
3560 DeviceActions.push_back(
3566 if (!DeviceActions.empty()) {
3568 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3570 if (!CompileDeviceOnly) {
3571 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3575 CudaFatBinary =
nullptr;
3580 CudaDeviceActions.clear();
3584 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3589 return ABRT_Success;
3593 "instructions should only occur "
3594 "before the backend phase!");
3597 for (
Action *&A : CudaDeviceActions)
3598 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3600 return ABRT_Success;
3605 class HIPActionBuilder final :
public CudaActionBuilderBase {
3613 std::optional<bool> BundleOutput;
3614 std::optional<bool> EmitReloc;
3619 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3621 DefaultOffloadArch = OffloadArch::HIPDefault;
3623 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3624 options::OPT_fno_hip_emit_relocatable)) {
3625 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3626 options::OPT_fno_hip_emit_relocatable,
false);
3630 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3631 <<
"-fhip-emit-relocatable"
3635 if (!CompileDeviceOnly) {
3636 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3637 <<
"-fhip-emit-relocatable"
3638 <<
"--cuda-device-only";
3643 if (Args.hasArg(options::OPT_gpu_bundle_output,
3644 options::OPT_no_gpu_bundle_output))
3645 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3646 options::OPT_no_gpu_bundle_output,
true) &&
3647 (!EmitReloc || !*EmitReloc);
3650 bool canUseBundlerUnbundler()
const override {
return true; }
3652 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3653 llvm::StringMap<bool> Features;
3657 (IdStr ==
"amdgcnspirv")
3658 ? llvm::Triple(
"spirv64-amd-amdhsa")
3662 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3663 C.setContainsError();
3667 return Args.MakeArgStringRef(CanId);
3670 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3672 const std::set<StringRef> &GpuArchs)
override {
3676 ActionBuilderReturnCode
3679 PhasesTy &Phases)
override {
3681 return ABRT_Inactive;
3687 if (CudaDeviceActions.empty())
3688 return ABRT_Success;
3691 CudaDeviceActions.size() == GpuArchList.size()) &&
3692 "Expecting one action per GPU architecture.");
3693 assert(!CompileHostOnly &&
3694 "Not expecting HIP actions in host-only compilation.");
3696 bool ShouldLink = !EmitReloc || !*EmitReloc;
3699 !EmitAsm && ShouldLink) {
3705 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3706 if (
C.getDriver().isUsingOffloadLTO()) {
3710 AL.push_back(CudaDeviceActions[I]);
3713 CudaDeviceActions[I] =
3720 if (ToolChains.front()->getTriple().isSPIRV()) {
3723 types::ID Output = Args.hasArg(options::OPT_S)
3725 : types::TY_LLVM_BC;
3731 AssociatedOffloadKind);
3732 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3734 AssociatedOffloadKind);
3735 AL.push_back(AssembleAction);
3738 CudaDeviceActions[I] =
3749 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3750 AssociatedOffloadKind);
3752 DDep, CudaDeviceActions[I]->getType());
3755 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3758 types::TY_HIP_FATBIN);
3760 if (!CompileDeviceOnly) {
3761 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3762 AssociatedOffloadKind);
3765 CudaFatBinary =
nullptr;
3770 CudaDeviceActions.clear();
3773 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3776 return ABRT_Success;
3782 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3783 auto LI = DeviceLinkerInputs.begin();
3784 for (
auto *A : CudaDeviceActions) {
3791 CudaDeviceActions.clear();
3792 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3796 for (
Action *&A : CudaDeviceActions)
3797 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3798 AssociatedOffloadKind);
3800 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3802 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3804 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3805 AssociatedOffloadKind);
3807 DDep, CudaDeviceActions[I]->getType());
3811 CudaDeviceActions.clear();
3814 return (CompileDeviceOnly &&
3815 (CurPhase == FinalPhase ||
3821 void appendLinkDeviceActions(
ActionList &AL)
override {
3822 if (DeviceLinkerInputs.size() == 0)
3825 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3826 "Linker inputs and GPU arch list sizes do not match.");
3832 for (
auto &LI : DeviceLinkerInputs) {
3834 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3838 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3842 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3843 GpuArchList[I], AssociatedOffloadKind);
3845 DeviceLinkDeps, DeviceLinkAction->getType()));
3848 DeviceLinkerInputs.clear();
3851 if (Args.hasArg(options::OPT_emit_llvm)) {
3860 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3863 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3864 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3865 AssociatedOffloadKind);
3868 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3874 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3890 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3898 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3901 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3909 unsigned ValidBuilders = 0u;
3910 unsigned ValidBuildersSupportingBundling = 0u;
3911 for (
auto *SB : SpecializedBuilders) {
3912 IsValid = IsValid && !SB->initialize();
3915 if (SB->isValid()) {
3917 if (SB->canUseBundlerUnbundler())
3918 ++ValidBuildersSupportingBundling;
3922 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3925 ~OffloadingActionBuilder() {
3926 for (
auto *SB : SpecializedBuilders)
3931 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3932 assert(HostAction &&
"Invalid host action");
3933 assert(InputArg &&
"Invalid input argument");
3934 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3935 assert(
Loc->second == InputArg &&
3936 "host action mapped to multiple input arguments");
3945 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3947 DeviceActionBuilder::PhasesTy &Phases) {
3951 if (SpecializedBuilders.empty())
3954 assert(HostAction &&
"Invalid host action!");
3955 recordHostAction(HostAction, InputArg);
3960 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3961 unsigned InactiveBuilders = 0u;
3962 unsigned IgnoringBuilders = 0u;
3963 for (
auto *SB : SpecializedBuilders) {
3964 if (!SB->isValid()) {
3969 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3974 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3979 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3980 OffloadKind |= SB->getAssociatedOffloadKind();
3985 if (IgnoringBuilders &&
3986 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4003 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4004 const Arg *InputArg) {
4008 recordHostAction(HostAction, InputArg);
4016 if (CanUseBundler && isa<InputAction>(HostAction) &&
4017 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4019 HostAction->
getType() == types::TY_PP_HIP)) {
4020 auto UnbundlingHostAction =
4025 HostAction = UnbundlingHostAction;
4026 recordHostAction(HostAction, InputArg);
4029 assert(HostAction &&
"Invalid host action!");
4032 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4033 for (
auto *SB : SpecializedBuilders) {
4037 auto RetCode = SB->addDeviceDependences(HostAction);
4041 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4042 "Host dependence not expected to be ignored.!");
4046 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4047 OffloadKind |= SB->getAssociatedOffloadKind();
4052 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4062 const Arg *InputArg) {
4064 recordHostAction(HostAction, InputArg);
4068 for (
auto *SB : SpecializedBuilders) {
4071 SB->appendTopLevelActions(OffloadAL);
4078 if (CanUseBundler && HostAction &&
4079 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4081 OffloadAL.push_back(HostAction);
4085 assert(HostAction == AL.back() &&
"Host action not in the list??");
4087 recordHostAction(HostAction, InputArg);
4088 AL.back() = HostAction;
4090 AL.append(OffloadAL.begin(), OffloadAL.end());
4100 void appendDeviceLinkActions(
ActionList &AL) {
4101 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4104 SB->appendLinkDeviceActions(AL);
4108 Action *makeHostLinkAction() {
4111 appendDeviceLinkActions(DeviceAL);
4112 if (DeviceAL.empty())
4117 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4120 HA = SB->appendLinkHostActions(DeviceAL);
4137 for (
auto *SB : SpecializedBuilders) {
4141 SB->appendLinkDependences(DDeps);
4145 unsigned ActiveOffloadKinds = 0u;
4146 for (
auto &I : InputArgToOffloadKindMap)
4147 ActiveOffloadKinds |= I.second;
4159 for (
auto *A : HostAction->
inputs()) {
4160 auto ArgLoc = HostActionToInputArgMap.find(A);
4161 if (ArgLoc == HostActionToInputArgMap.end())
4163 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4164 if (OFKLoc == InputArgToOffloadKindMap.end())
4176 nullptr, ActiveOffloadKinds);
4182void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4183 const InputList &Inputs,
4187 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4188 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4189 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4190 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4191 Args.eraseArg(options::OPT__SLASH_Yc);
4192 Args.eraseArg(options::OPT__SLASH_Yu);
4193 YcArg = YuArg =
nullptr;
4195 if (YcArg && Inputs.size() > 1) {
4196 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4197 Args.eraseArg(options::OPT__SLASH_Yc);
4205 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4206 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4207 Args.AddFlagArg(
nullptr,
4208 getOpts().getOption(options::OPT_frtlib_add_rpath));
4211 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4212 Diag(clang::diag::err_drv_emit_llvm_link);
4213 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4215 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4216 .starts_with_insensitive(
"lld"))
4217 Diag(clang::diag::err_drv_lto_without_lld);
4223 if (!Args.hasArg(options::OPT_dumpdir)) {
4224 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4225 Arg *Arg = Args.MakeSeparateArg(
4226 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4228 (FinalOutput ? FinalOutput->getValue()
4240 Args.eraseArg(options::OPT__SLASH_Fp);
4241 Args.eraseArg(options::OPT__SLASH_Yc);
4242 Args.eraseArg(options::OPT__SLASH_Yu);
4243 YcArg = YuArg =
nullptr;
4246 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4247 for (
auto &I : Inputs) {
4249 const Arg *InputArg = I.second;
4254 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4258 if (InitialPhase > FinalPhase) {
4259 if (InputArg->isClaimed())
4266 if (Args.hasArg(options::OPT_Qunused_arguments))
4272 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4273 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4277 (Args.getLastArg(options::OPT__SLASH_EP,
4278 options::OPT__SLASH_P) ||
4279 Args.getLastArg(options::OPT_E) ||
4280 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4282 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4283 << InputArg->getAsString(Args) << !!FinalPhaseArg
4284 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4286 Diag(clang::diag::warn_drv_input_file_unused)
4287 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4289 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4302 Actions.push_back(ClangClPch);
4314 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4315 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4321 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4323 if (!SuppressMissingInputWarning && Inputs.empty()) {
4324 Diag(clang::diag::err_drv_no_input_files);
4329 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4330 StringRef
V = A->getValue();
4331 if (Inputs.size() > 1 && !
V.empty() &&
4332 !llvm::sys::path::is_separator(
V.back())) {
4334 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4335 << A->getSpelling() <<
V;
4336 Args.eraseArg(options::OPT__SLASH_Fo);
4341 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4342 StringRef
V = A->getValue();
4343 if (Inputs.size() > 1 && !
V.empty() &&
4344 !llvm::sys::path::is_separator(
V.back())) {
4346 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4347 << A->getSpelling() <<
V;
4348 Args.eraseArg(options::OPT__SLASH_Fa);
4353 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4354 if (A->getValue()[0] ==
'\0') {
4356 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4357 Args.eraseArg(options::OPT__SLASH_o);
4361 handleArguments(
C, Args, Inputs, Actions);
4363 bool UseNewOffloadingDriver =
4366 Args.hasFlag(options::OPT_foffload_via_llvm,
4367 options::OPT_fno_offload_via_llvm,
false) ||
4368 Args.hasFlag(options::OPT_offload_new_driver,
4369 options::OPT_no_offload_new_driver,
4373 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4374 !UseNewOffloadingDriver
4375 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4383 for (
auto &I : Inputs) {
4385 const Arg *InputArg = I.second;
4398 CUID = CUIDOpts.
getCUID(InputArg->getValue(), Args);
4399 cast<InputAction>(Current)->setId(CUID);
4404 if (!UseNewOffloadingDriver)
4405 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4411 if (!UseNewOffloadingDriver)
4412 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4413 Current, InputArg, Phase, PL.back(), FullPL);
4419 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4422 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4423 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4425 LinkerInputs.push_back(Current);
4435 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4436 MergerInputs.push_back(Current);
4454 if (NewCurrent == Current)
4457 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4460 Current = NewCurrent;
4464 if (UseNewOffloadingDriver)
4468 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4472 if (Current->getType() == types::TY_Nothing)
4478 Actions.push_back(Current);
4481 if (!UseNewOffloadingDriver)
4482 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4484 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4490 if (LinkerInputs.empty()) {
4493 if (!UseNewOffloadingDriver)
4494 OffloadBuilder->appendDeviceLinkActions(Actions);
4497 if (!LinkerInputs.empty()) {
4498 if (!UseNewOffloadingDriver)
4499 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4500 LinkerInputs.push_back(Wrapper);
4505 }
else if (UseNewOffloadingDriver ||
4506 Args.hasArg(options::OPT_offload_link)) {
4513 if (!UseNewOffloadingDriver)
4514 LA = OffloadBuilder->processHostLinkAction(LA);
4515 Actions.push_back(LA);
4519 if (!MergerInputs.empty())
4523 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4530 for (
auto &I : Inputs) {
4532 const Arg *InputArg = I.second;
4537 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4538 InputType == types::TY_Asm)
4543 for (
auto Phase : PhaseList) {
4547 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4552 if (InputType == types::TY_Object)
4559 assert(Phase == PhaseList.back() &&
4560 "merging must be final compilation step.");
4561 MergerInputs.push_back(Current);
4570 Actions.push_back(Current);
4574 if (!MergerInputs.empty())
4579 for (
auto Opt : {options::OPT_print_supported_cpus,
4580 options::OPT_print_supported_extensions,
4581 options::OPT_print_enabled_extensions}) {
4588 if (Arg *A = Args.getLastArg(Opt)) {
4589 if (Opt == options::OPT_print_supported_extensions &&
4590 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4591 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4592 !
C.getDefaultToolChain().getTriple().isARM()) {
4593 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4594 <<
"--print-supported-extensions";
4597 if (Opt == options::OPT_print_enabled_extensions &&
4598 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4599 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4600 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4601 <<
"--print-enabled-extensions";
4608 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4611 for (
auto &I : Inputs)
4617 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4621 if (TC.requiresValidation(Args)) {
4622 Action *LastAction = Actions.back();
4624 LastAction, types::TY_DX_CONTAINER));
4629 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4635 const llvm::opt::DerivedArgList &Args,
4637 const llvm::Triple &Triple,
4638 bool SuppressError =
false) {
4643 if (!SuppressError && Triple.isNVPTX() &&
4645 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4646 <<
"CUDA" << ArchStr;
4648 }
else if (!SuppressError && Triple.isAMDGPU() &&
4650 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4651 <<
"HIP" << ArchStr;
4659 llvm::StringMap<bool> Features;
4665 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4666 C.setContainsError();
4678static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4680 llvm::Triple Triple) {
4681 if (!Triple.isAMDGPU())
4682 return std::nullopt;
4684 std::set<StringRef> ArchSet;
4685 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4689llvm::DenseSet<StringRef>
4692 bool SuppressError)
const {
4694 TC = &
C.getDefaultToolChain();
4697 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4698 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4699 options::OPT_no_offload_arch_EQ)) {
4700 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4702 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4704 :
"--no-offload-arch");
4707 if (KnownArchs.contains(TC))
4708 return KnownArchs.lookup(TC);
4710 llvm::DenseSet<StringRef> Archs;
4711 for (
auto *Arg : Args) {
4713 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4714 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4717 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4718 unsigned Prev = Index;
4719 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4720 if (!ExtractedArg || Index > Prev + 1) {
4721 TC->
getDriver().
Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
4722 << Arg->getAsString(Args);
4725 Arg = ExtractedArg.get();
4730 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4731 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4732 if (Arch ==
"native" || Arch.empty()) {
4736 llvm::consumeError(GPUsOrErr.takeError());
4739 << llvm::Triple::getArchTypeName(TC->
getArch())
4740 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4744 for (
auto ArchStr : *GPUsOrErr) {
4751 C, Args, Arch, TC->
getTriple(), SuppressError);
4752 if (ArchStr.empty())
4754 Archs.insert(ArchStr);
4757 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4758 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4759 if (Arch ==
"all") {
4763 C, Args, Arch, TC->
getTriple(), SuppressError);
4764 if (ArchStr.empty())
4766 Archs.erase(ArchStr);
4772 if (
auto ConflictingArchs =
4774 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4775 << ConflictingArchs->first << ConflictingArchs->second;
4776 C.setContainsError();
4783 if (Archs.empty()) {
4789 Archs.insert(StringRef());
4791 Archs.insert(StringRef());
4793 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4794 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4801 llvm::opt::DerivedArgList &Args,
4802 const InputTy &Input, StringRef CUID,
4803 Action *HostAction)
const {
4808 !(isa<CompileJobAction>(HostAction) ||
4822 auto TCRange =
C.getOffloadToolChains(Kind);
4823 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4824 ToolChains.push_back(TI->second);
4826 if (ToolChains.empty())
4830 const Arg *InputArg = Input.second;
4839 for (
const ToolChain *TC : ToolChains) {
4843 for (StringRef Arch : Sorted) {
4844 TCAndArchs.push_back(std::make_pair(TC, Arch));
4845 DeviceActions.push_back(
4846 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4850 if (DeviceActions.empty())
4856 HostAction->
getType() != types::TY_Nothing &&
4866 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4875 auto TCAndArch = TCAndArchs.begin();
4876 for (
Action *&A : DeviceActions) {
4877 if (A->
getType() == types::TY_Nothing)
4885 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4887 HostAction->
getType() != types::TY_Nothing) {
4894 TCAndArch->second.data(), Kind);
4896 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4905 for (
Action *&A : DeviceActions) {
4906 if ((A->
getType() != types::TY_Object &&
4907 A->
getType() != types::TY_LTO_BC) ||
4909 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4915 auto TCAndArch = TCAndArchs.begin();
4916 for (
Action *A : DeviceActions) {
4917 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4919 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4924 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4926 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4934 bool ShouldBundleHIP =
4936 Args.hasFlag(options::OPT_gpu_bundle_output,
4937 options::OPT_no_gpu_bundle_output,
true) &&
4938 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4939 !llvm::any_of(OffloadActions,
4946 if (OffloadActions.empty())
4951 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4955 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4959 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4964 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4973 nullptr,
C.getActiveOffloadKinds());
4982 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4983 return A->
getType() == types::TY_Nothing;
4984 }) && isa<CompileJobAction>(HostAction);
4987 nullptr, SingleDeviceOutput ? DDep : DDeps);
4988 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4994 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5004 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5010 llvm_unreachable(
"link action invalid here.");
5012 llvm_unreachable(
"ifsmerge action invalid here.");
5017 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5018 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5019 OutputTy = types::TY_Dependencies;
5024 if (!Args.hasFlag(options::OPT_frewrite_includes,
5025 options::OPT_fno_rewrite_includes,
false) &&
5026 !Args.hasFlag(options::OPT_frewrite_imports,
5027 options::OPT_fno_rewrite_imports,
false) &&
5028 !Args.hasFlag(options::OPT_fdirectives_only,
5029 options::OPT_fno_directives_only,
false) &&
5033 "Cannot preprocess this input type!");
5039 if (Args.hasArg(options::OPT_extract_api))
5046 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
5047 !Args.getLastArg(options::OPT__precompile))
5052 "Cannot precompile this input type!");
5056 const char *ModName =
nullptr;
5057 if (OutputTy == types::TY_PCH) {
5058 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5059 ModName = A->getValue();
5061 OutputTy = types::TY_ModuleFile;
5064 if (Args.hasArg(options::OPT_fsyntax_only)) {
5066 OutputTy = types::TY_Nothing;
5072 if (Args.hasArg(options::OPT_fsyntax_only))
5074 if (Args.hasArg(options::OPT_rewrite_objc))
5076 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5078 types::TY_RewrittenLegacyObjC);
5079 if (Args.hasArg(options::OPT__analyze))
5081 if (Args.hasArg(options::OPT__migrate))
5083 if (Args.hasArg(options::OPT_emit_ast))
5085 if (Args.hasArg(options::OPT_emit_cir))
5087 if (Args.hasArg(options::OPT_module_file_info))
5089 if (Args.hasArg(options::OPT_verify_pch))
5091 if (Args.hasArg(options::OPT_extract_api))
5098 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5099 !Args.hasArg(options::OPT_emit_llvm))
5100 Output = types::TY_PP_Asm;
5101 else if (Args.hasArg(options::OPT_S))
5102 Output = types::TY_LTO_IR;
5104 Output = types::TY_LTO_BC;
5109 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5112 if (Args.hasArg(options::OPT_emit_llvm) ||
5117 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5121 Args.hasArg(options::OPT_S) &&
5125 !Args.hasFlag(options::OPT_offload_new_driver,
5126 options::OPT_no_offload_new_driver,
5129 : types::TY_LLVM_BC;
5138 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5142 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5144 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5164 unsigned NumOutputs = 0;
5165 unsigned NumIfsOutputs = 0;
5166 for (
const Action *A :
C.getActions()) {
5167 if (A->
getType() != types::TY_Nothing &&
5168 A->
getType() != types::TY_DX_CONTAINER &&
5170 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5172 0 == NumIfsOutputs++) ||
5177 A->
getType() == types::TY_Nothing &&
5178 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5179 NumOutputs += A->
size();
5182 if (NumOutputs > 1) {
5183 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5184 FinalOutput =
nullptr;
5188 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5191 llvm::StringSet<> ArchNames;
5192 if (RawTriple.isOSBinFormatMachO())
5193 for (
const Arg *A :
C.getArgs())
5194 if (A->getOption().matches(options::OPT_arch))
5195 ArchNames.insert(A->getValue());
5198 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5199 for (
Action *A :
C.getActions()) {
5206 const char *LinkingOutput =
nullptr;
5207 if (isa<LipoJobAction>(A)) {
5209 LinkingOutput = FinalOutput->getValue();
5217 ArchNames.size() > 1,
5218 LinkingOutput, CachedResults,
5225 for (
auto &J :
C.getJobs())
5226 J.InProcess =
false;
5229 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
5230 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5231 Cmd.getProcessStatistics();
5235 const char *LinkingOutput =
nullptr;
5237 LinkingOutput = FinalOutput->getValue();
5238 else if (!
Cmd.getOutputFilenames().empty())
5239 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
5244 using namespace llvm;
5246 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
5247 <<
"output=" << LinkingOutput;
5248 outs() <<
", total="
5249 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5251 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5252 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5256 llvm::raw_string_ostream Out(Buffer);
5257 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
5260 llvm::sys::printArg(Out, LinkingOutput, true);
5261 Out <<
',' << ProcStat->TotalTime.count() <<
','
5262 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5266 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5267 llvm::sys::fs::OF_Append |
5268 llvm::sys::fs::OF_Text);
5273 llvm::errs() <<
"ERROR: Cannot lock file "
5274 << CCPrintStatReportFilename <<
": "
5275 << toString(L.takeError()) <<
"\n";
5286 if (Diags.hasErrorOccurred() ||
5287 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5291 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5293 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5296 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5297 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5299 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5303 return strstr(J.getCreator().getShortName(),
"assembler");
5305 for (Arg *A :
C.getArgs()) {
5309 if (!A->isClaimed()) {
5315 const Option &Opt = A->getOption();
5316 if (Opt.getKind() == Option::FlagClass) {
5317 bool DuplicateClaimed =
false;
5319 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5320 if (AA->isClaimed()) {
5321 DuplicateClaimed =
true;
5326 if (DuplicateClaimed)
5332 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5334 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5339 !
C.getActions().empty()) {
5340 Diag(diag::err_drv_unsupported_opt_for_target)
5341 << A->getSpelling() << getTargetTriple();
5343 Diag(clang::diag::warn_drv_unused_argument)
5344 << A->getAsString(
C.getArgs());
5354class ToolSelector final {
5365 bool IsHostSelector;
5376 bool CanBeCollapsed =
true) {
5378 if (Inputs.size() != 1)
5381 Action *CurAction = *Inputs.begin();
5382 if (CanBeCollapsed &&
5388 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5392 if (!IsHostSelector) {
5393 if (OA->hasSingleDeviceDependence(
true)) {
5395 OA->getSingleDeviceDependence(
true);
5396 if (CanBeCollapsed &&
5399 SavedOffloadAction.push_back(OA);
5400 return dyn_cast<JobAction>(CurAction);
5402 }
else if (OA->hasHostDependence()) {
5403 CurAction = OA->getHostDependence();
5404 if (CanBeCollapsed &&
5407 SavedOffloadAction.push_back(OA);
5408 return dyn_cast<JobAction>(CurAction);
5413 return dyn_cast<JobAction>(CurAction);
5417 bool canCollapseAssembleAction()
const {
5418 return TC.useIntegratedAs() && !SaveTemps &&
5419 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5420 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5421 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5422 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5426 bool canCollapsePreprocessorAction()
const {
5427 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5428 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5429 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5434 struct JobActionInfo final {
5444 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5446 unsigned ElementNum) {
5447 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5448 for (
unsigned I = 0; I < ElementNum; ++I)
5449 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5450 ActionInfo[I].SavedOffloadAction.end());
5466 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5468 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5469 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5470 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5471 if (!AJ || !BJ || !CJ)
5475 const Tool *
T = TC.SelectTool(*CJ);
5482 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5488 const Tool *BT = TC.SelectTool(*BJ);
5493 if (!
T->hasIntegratedAssembler())
5496 Inputs = CJ->getInputs();
5497 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5504 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5506 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5507 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5512 const Tool *
T = TC.SelectTool(*BJ);
5516 if (!
T->hasIntegratedAssembler())
5519 Inputs = BJ->getInputs();
5520 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5527 if (ActionInfo.size() < 2)
5529 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5530 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5539 bool InputIsBitcode =
true;
5540 for (
size_t i = 1; i < ActionInfo.size(); i++)
5541 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5542 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5543 InputIsBitcode =
false;
5546 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5550 const Tool *
T = TC.SelectTool(*CJ);
5557 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5560 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5563 Inputs = CJ->getInputs();
5564 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5575 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5581 for (
Action *A : Inputs) {
5582 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5583 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5584 NewInputs.push_back(A);
5590 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5591 PreprocessJobOffloadActions.end());
5592 NewInputs.append(PJ->input_begin(), PJ->input_end());
5600 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5602 assert(BaseAction &&
"Invalid base action.");
5619 ActionChain.back().JA = BaseAction;
5620 while (ActionChain.back().JA) {
5621 const Action *CurAction = ActionChain.back().JA;
5624 ActionChain.resize(ActionChain.size() + 1);
5625 JobActionInfo &AI = ActionChain.back();
5629 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5633 ActionChain.pop_back();
5641 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5642 CollapsedOffloadAction);
5644 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5646 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5652 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5664 StringRef BoundArch,
5666 std::string TriplePlusArch = TC->
getTriple().normalize();
5667 if (!BoundArch.empty()) {
5668 TriplePlusArch +=
"-";
5669 TriplePlusArch += BoundArch;
5671 TriplePlusArch +=
"-";
5673 return TriplePlusArch;
5678 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5679 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5682 std::pair<const Action *, std::string> ActionTC = {
5684 auto CachedResult = CachedResults.find(ActionTC);
5685 if (CachedResult != CachedResults.end()) {
5686 return CachedResult->second;
5689 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5690 CachedResults, TargetDeviceOffloadKind);
5691 CachedResults[ActionTC] =
Result;
5696 const JobAction *JA,
const char *BaseInput,
5699 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5703 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5704 Path = A->getValue();
5705 if (llvm::sys::fs::is_directory(
Path)) {
5707 llvm::sys::path::replace_extension(Tmp,
"json");
5708 llvm::sys::path::append(
Path, llvm::sys::path::filename(Tmp));
5711 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5714 Path = DumpDir->getValue();
5715 Path += llvm::sys::path::filename(BaseInput);
5719 llvm::sys::path::replace_extension(
Path,
"json");
5721 const char *ResultFile =
C.getArgs().MakeArgString(
Path);
5722 C.addTimeTraceFile(ResultFile, JA);
5723 C.addResultFile(ResultFile, JA);
5728 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5729 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5732 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5735 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5768 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5770 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5771 const char *DepBoundArch) {
5774 LinkingOutput, CachedResults,
5784 OA->doOnEachDependence(
5785 BuildingForOffloadDevice,
5788 C, DepA, DepTC, DepBoundArch,
false,
5789 !!DepBoundArch, LinkingOutput, CachedResults,
5793 A = BuildingForOffloadDevice
5794 ? OA->getSingleDeviceDependence(
true)
5795 : OA->getHostDependence();
5799 std::pair<const Action *, std::string> ActionTC = {
5800 OA->getHostDependence(),
5802 auto It = CachedResults.find(ActionTC);
5803 if (It != CachedResults.end()) {
5805 Inputs.append(OffloadDependencesInputInfo);
5810 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5813 const Arg &Input = IA->getInputArg();
5815 if (Input.getOption().matches(options::OPT_INPUT)) {
5816 const char *
Name = Input.getValue();
5826 if (!ArchName.empty())
5827 TC = &getToolChain(
C.getArgs(),
5829 C.getArgs(), ArchName));
5831 TC = &
C.getDefaultToolChain();
5834 MultipleArchs, LinkingOutput, CachedResults,
5835 TargetDeviceOffloadKind);
5841 const JobAction *JA = cast<JobAction>(A);
5846 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5853 for (
const auto *OA : CollapsedOffloadActions)
5854 cast<OffloadAction>(OA)->doOnEachDependence(
5855 BuildingForOffloadDevice,
5858 C, DepA, DepTC, DepBoundArch,
false,
5859 !!DepBoundArch, LinkingOutput, CachedResults,
5865 for (
const Action *Input : Inputs) {
5869 bool SubJobAtTopLevel =
5870 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5872 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5877 const char *BaseInput = InputInfos[0].getBaseInput();
5878 for (
auto &Info : InputInfos) {
5879 if (Info.isFilename()) {
5880 BaseInput = Info.getBaseInput();
5887 if (JA->
getType() == types::TY_dSYM)
5888 BaseInput = InputInfos[0].getFilename();
5891 if (!OffloadDependencesInputInfo.empty())
5892 InputInfos.append(OffloadDependencesInputInfo.begin(),
5893 OffloadDependencesInputInfo.end());
5896 llvm::Triple EffectiveTriple;
5898 const ArgList &Args =
5900 if (InputInfos.size() != 1) {
5904 EffectiveTriple = llvm::Triple(
5912 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5916 for (
auto &UI : UA->getDependentActionsInfo()) {
5918 "Unbundling with no offloading??");
5925 UI.DependentOffloadKind,
5926 UI.DependentToolChain->getTriple().normalize(),
5937 UnbundlingResults.push_back(CurI);
5946 Arch = UI.DependentBoundArch;
5951 UI.DependentOffloadKind)}] = {
5957 std::pair<const Action *, std::string> ActionTC = {
5959 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5960 "Result does not exist??");
5961 Result = CachedResults[ActionTC].front();
5962 }
else if (JA->
getType() == types::TY_Nothing)
5969 isa<OffloadPackagerJobAction>(A) ||
5973 AtTopLevel, MultipleArchs,
5976 if (
T->canEmitIR() && OffloadingPrefix.empty())
5981 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5982 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5983 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5984 llvm::errs() << InputInfos[i].getAsString();
5986 llvm::errs() <<
", ";
5988 if (UnbundlingResults.empty())
5989 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5991 llvm::errs() <<
"], outputs: [";
5992 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5993 llvm::errs() << UnbundlingResults[i].getAsString();
5995 llvm::errs() <<
", ";
5997 llvm::errs() <<
"] \n";
6000 if (UnbundlingResults.empty())
6001 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6003 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6004 Args, LinkingOutput);
6010 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6011 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6023 if (ArgValue.empty()) {
6026 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
6028 llvm::sys::path::append(
Filename, BaseName);
6031 if (!llvm::sys::path::has_extension(ArgValue)) {
6036 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6041 llvm::sys::path::replace_extension(
Filename, Extension);
6044 return Args.MakeArgString(
Filename.c_str());
6048 if (isa<PreprocessJobAction>(JA))
6050 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
6052 if (isa<OffloadBundlingJobAction>(JA) &&
6059 StringRef Suffix,
bool MultipleArchs,
6060 StringRef BoundArch,
6061 bool NeedUniqueDirectory)
const {
6063 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6064 std::optional<std::string> CrashDirectory =
6066 ? std::string(A->getValue())
6067 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6068 if (CrashDirectory) {
6069 if (!
getVFS().exists(*CrashDirectory))
6070 llvm::sys::fs::create_directories(*CrashDirectory);
6072 llvm::sys::path::append(
Path, Prefix);
6073 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6074 if (std::error_code EC =
6075 llvm::sys::fs::createUniqueFile(
Path + Middle + Suffix, TmpName)) {
6076 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6080 if (MultipleArchs && !BoundArch.empty()) {
6081 if (NeedUniqueDirectory) {
6083 llvm::sys::path::append(TmpName,
6084 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6094 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6109 const char *BaseInput) {
6110 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
6111 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6112 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6117 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6121 const char *BaseInput,
6122 StringRef OrigBoundArch,
bool AtTopLevel,
6124 StringRef OffloadingPrefix)
const {
6125 std::string BoundArch = OrigBoundArch.str();
6126 if (is_style_windows(llvm::sys::path::Style::native)) {
6129 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
6132 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6134 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
6135 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6136 return C.addResultFile(FinalOutput->getValue(), &JA);
6140 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6141 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
6142 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6144 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6145 NameArg = A->getValue();
6146 return C.addResultFile(
6156 if (JA.
getType() == types::TY_ModuleFile &&
6157 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6161 if (JA.
getType() == types::TY_PP_Asm &&
6162 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6163 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6166 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6169 if (JA.
getType() == types::TY_Object &&
6170 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
6171 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6174 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6178 if (JA.
getType() == types::TY_PP_Asm &&
6179 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6180 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6182 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6183 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6184 return C.addResultFile(
6189 if (JA.
getType() == types::TY_API_INFO &&
6190 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6191 C.getArgs().hasArg(options::OPT_o))
6192 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6193 <<
C.getArgs().getLastArgValue(options::OPT_o);
6200 bool SpecifiedModuleOutput =
6201 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6202 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6203 if (MultipleArchs && SpecifiedModuleOutput)
6204 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6208 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
6209 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6210 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
6216 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6218 StringRef
Name = llvm::sys::path::filename(BaseInput);
6219 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6220 const char *Suffix =
6225 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6226 bool NeedUniqueDirectory =
6229 Triple.isOSDarwin();
6230 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6231 NeedUniqueDirectory);
6239 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
6240 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6245 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6246 llvm::sys::path::filename(BasePath));
6247 BaseName = ExternalPath;
6248 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
6249 BaseName = BasePath;
6251 BaseName = llvm::sys::path::filename(BasePath);
6254 const char *NamedOutput;
6256 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6257 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6261 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6265 }
else if (JA.
getType() == types::TY_Image &&
6266 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6267 options::OPT__SLASH_o)) {
6271 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6275 }
else if (JA.
getType() == types::TY_Image) {
6285 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6286 options::OPT_fno_gpu_rdc,
false);
6287 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6288 if (UseOutExtension) {
6290 llvm::sys::path::replace_extension(Output,
"");
6292 Output += OffloadingPrefix;
6293 if (MultipleArchs && !BoundArch.empty()) {
6295 Output.append(BoundArch);
6297 if (UseOutExtension)
6299 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6302 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6303 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6304 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6307 .getLastArg(options::OPT__SLASH_o)
6312 const char *Suffix =
6314 assert(Suffix &&
"All types used for output should have a suffix.");
6316 std::string::size_type End = std::string::npos;
6318 End = BaseName.rfind(
'.');
6320 Suffixed += OffloadingPrefix;
6321 if (MultipleArchs && !BoundArch.empty()) {
6323 Suffixed.append(BoundArch);
6328 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6329 const llvm::opt::DerivedArgList &Args) {
6334 return isa<CompileJobAction>(JA) &&
6336 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6341 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6342 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6343 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6347 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6351 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6352 JA.
getType() != types::TY_PCH) {
6353 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6355 llvm::sys::path::remove_filename(TempPath);
6356 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6357 llvm::sys::path::append(TempPath, OutputFileName);
6358 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6364 bool SameFile =
false;
6366 llvm::sys::fs::current_path(
Result);
6367 llvm::sys::path::append(
Result, BaseName);
6368 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6371 StringRef
Name = llvm::sys::path::filename(BaseInput);
6372 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6376 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6382 llvm::sys::path::remove_filename(BasePath);
6383 if (BasePath.empty())
6384 BasePath = NamedOutput;
6386 llvm::sys::path::append(BasePath, NamedOutput);
6387 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6390 return C.addResultFile(NamedOutput, &JA);
6396 -> std::optional<std::string> {
6399 for (
const auto &
Dir :
P) {
6403 llvm::sys::path::append(
P,
Name);
6404 if (llvm::sys::fs::exists(Twine(
P)))
6405 return std::string(
P);
6407 return std::nullopt;
6414 llvm::sys::path::append(R,
Name);
6415 if (llvm::sys::fs::exists(Twine(R)))
6416 return std::string(R);
6419 llvm::sys::path::append(
P,
Name);
6420 if (llvm::sys::fs::exists(Twine(
P)))
6421 return std::string(
P);
6424 llvm::sys::path::append(
D,
"..",
Name);
6425 if (llvm::sys::fs::exists(Twine(
D)))
6426 return std::string(
D);
6435 llvm::sys::path::append(R2,
"..",
"..",
Name);
6436 if (llvm::sys::fs::exists(Twine(R2)))
6437 return std::string(R2);
6439 return std::string(
Name);
6442void Driver::generatePrefixedToolNames(
6446 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6447 Names.emplace_back(
Tool);
6451 llvm::sys::path::append(Dir, Name);
6452 if (llvm::sys::fs::can_execute(Twine(Dir)))
6454 llvm::sys::path::remove_filename(Dir);
6460 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6465 if (llvm::sys::fs::is_directory(PrefixDir)) {
6468 return std::string(
P);
6471 if (llvm::sys::fs::can_execute(Twine(
P)))
6472 return std::string(
P);
6477 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6485 for (
const auto &
Path : List) {
6488 return std::string(
P);
6492 if (llvm::ErrorOr<std::string>
P =
6493 llvm::sys::findProgramByName(TargetSpecificExecutable))
6497 return std::string(
Name);
6502 std::string error =
"<NOT PRESENT>";
6506 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6523 llvm::sys::path::remove_filename(path);
6524 llvm::sys::path::append(path,
"libc++.modules.json");
6525 if (TC.
getVFS().exists(path))
6526 return static_cast<std::string
>(path);
6531 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6534 return evaluate(
"libc++.a").value_or(error);
6538 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6542 llvm::sys::path::remove_filename(path);
6543 llvm::sys::path::append(path,
"libstdc++.modules.json");
6544 if (TC.
getVFS().exists(path))
6545 return static_cast<std::string
>(path);
6550 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6553 return evaluate(
"libstdc++.a").value_or(error);
6562 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix,
Path);
6564 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6568 return std::string(
Path);
6573 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix,
Path);
6575 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6579 return std::string(
Path);
6584 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6588 Output = FpArg->getValue();
6592 if (!llvm::sys::path::has_extension(Output))
6595 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6596 Output = YcArg->getValue();
6599 llvm::sys::path::replace_extension(Output,
".pch");
6601 return std::string(Output);
6604const ToolChain &Driver::getToolChain(
const ArgList &Args,
6605 const llvm::Triple &
Target)
const {
6607 auto &TC = ToolChains[
Target.str()];
6609 switch (
Target.getOS()) {
6610 case llvm::Triple::AIX:
6611 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6613 case llvm::Triple::Haiku:
6614 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6616 case llvm::Triple::Darwin:
6617 case llvm::Triple::MacOSX:
6618 case llvm::Triple::IOS:
6619 case llvm::Triple::TvOS:
6620 case llvm::Triple::WatchOS:
6621 case llvm::Triple::XROS:
6622 case llvm::Triple::DriverKit:
6623 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6625 case llvm::Triple::DragonFly:
6626 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6628 case llvm::Triple::OpenBSD:
6629 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6631 case llvm::Triple::NetBSD:
6632 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6634 case llvm::Triple::FreeBSD:
6636 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6639 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6641 case llvm::Triple::Linux:
6642 case llvm::Triple::ELFIAMCU:
6643 if (
Target.getArch() == llvm::Triple::hexagon)
6644 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6646 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6647 !
Target.hasEnvironment())
6648 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6651 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6653 else if (
Target.getArch() == llvm::Triple::ve)
6654 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6655 else if (
Target.isOHOSFamily())
6656 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6658 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6660 case llvm::Triple::NaCl:
6661 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6663 case llvm::Triple::Fuchsia:
6664 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6666 case llvm::Triple::Solaris:
6667 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6669 case llvm::Triple::CUDA:
6670 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6672 case llvm::Triple::AMDHSA:
6673 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6675 case llvm::Triple::AMDPAL:
6676 case llvm::Triple::Mesa3D:
6677 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6679 case llvm::Triple::UEFI:
6680 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6682 case llvm::Triple::Win32:
6683 switch (
Target.getEnvironment()) {
6685 if (
Target.isOSBinFormatELF())
6686 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6687 else if (
Target.isOSBinFormatMachO())
6688 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6690 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6692 case llvm::Triple::GNU:
6693 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6695 case llvm::Triple::Itanium:
6696 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6699 case llvm::Triple::MSVC:
6700 case llvm::Triple::UnknownEnvironment:
6701 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6702 .starts_with_insensitive(
"bfd"))
6703 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6707 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6711 case llvm::Triple::PS4:
6712 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6714 case llvm::Triple::PS5:
6715 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6717 case llvm::Triple::Hurd:
6718 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6720 case llvm::Triple::LiteOS:
6721 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6723 case llvm::Triple::ZOS:
6724 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6726 case llvm::Triple::Vulkan:
6727 case llvm::Triple::ShaderModel:
6728 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6733 switch (
Target.getArch()) {
6734 case llvm::Triple::tce:
6735 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6737 case llvm::Triple::tcele:
6738 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6740 case llvm::Triple::hexagon:
6741 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6744 case llvm::Triple::lanai:
6745 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6747 case llvm::Triple::xcore:
6748 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6750 case llvm::Triple::wasm32:
6751 case llvm::Triple::wasm64:
6752 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6754 case llvm::Triple::avr:
6755 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6757 case llvm::Triple::msp430:
6759 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6761 case llvm::Triple::riscv32:
6762 case llvm::Triple::riscv64:
6765 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6767 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6769 case llvm::Triple::ve:
6770 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6772 case llvm::Triple::spirv32:
6773 case llvm::Triple::spirv64:
6774 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6776 case llvm::Triple::csky:
6777 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6781 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6782 else if (
Target.isOSBinFormatELF())
6783 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6784 else if (
Target.isAppleMachO())
6785 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6786 else if (
Target.isOSBinFormatMachO())
6787 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6789 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6797const ToolChain &Driver::getOffloadingDeviceToolChain(
6798 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6807 switch (TargetDeviceOffloadKind) {
6809 if (((
Target.getArch() == llvm::Triple::amdgcn ||
6810 Target.getArch() == llvm::Triple::spirv64) &&
6811 Target.getVendor() == llvm::Triple::AMD &&
6812 Target.getOS() == llvm::Triple::AMDHSA) ||
6813 !Args.hasArgNoClaim(options::OPT_offload_EQ))
6814 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6816 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6817 Target.getVendor() == llvm::Triple::UnknownVendor &&
6818 Target.getOS() == llvm::Triple::UnknownOS)
6819 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6824 if (
Target.isSPIROrSPIRV())
6825 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, HostTC,
6832 assert(TC &&
"Could not create offloading device tool chain.");
6838 if (JA.
size() != 1 ||
6843 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6844 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6845 !isa<ExtractAPIJobAction>(JA))
6853 if (JA.
size() != 1 ||
6858 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6859 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
6867 if (Args.hasArg(options::OPT_emit_static_lib))
6878 unsigned &Micro,
bool &HadExtra) {
6881 Major = Minor = Micro = 0;
6885 if (Str.consumeInteger(10, Major))
6889 if (!Str.consume_front(
"."))
6892 if (Str.consumeInteger(10, Minor))
6896 if (!Str.consume_front(
"."))
6899 if (Str.consumeInteger(10, Micro))
6917 unsigned CurDigit = 0;
6918 while (CurDigit < Digits.size()) {
6920 if (Str.consumeInteger(10, Digit))
6922 Digits[CurDigit] = Digit;
6925 if (!Str.consume_front(
"."))
6934llvm::opt::Visibility
6935Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6948const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6964 llvm_unreachable(
"Unhandled Mode");
6968 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6973 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6974 options::OPT_fno_save_optimization_record,
false))
6978 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6979 options::OPT_fno_save_optimization_record,
false))
6983 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6984 options::OPT_fno_save_optimization_record,
false))
6988 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6989 options::OPT_fno_save_optimization_record,
false))
6996 static StringRef OptName =
6998 llvm::StringRef Opt;
6999 for (StringRef Arg : Args) {
7000 if (!Arg.starts_with(OptName))
7006 return Opt.consume_front(OptName) ? Opt :
"";
7013 llvm::BumpPtrAllocator &Alloc,
7014 llvm::vfs::FileSystem *FS) {
7023 for (
const char *F : Args) {
7024 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7026 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7027 RSPQuoting = Windows;
7035 llvm::cl::TokenizerCallback Tokenizer;
7037 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7039 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7041 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7044 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7045 ECtx.setMarkEOLs(MarkEOLs);
7049 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7053 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7054 [](
const char *A) {
return A !=
nullptr; });
7055 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7058 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7059 Args.resize(newEnd - Args.begin());
7063 return llvm::Error::success();
7067 return SavedStrings.insert(S).first->getKeyData();
7100 llvm::StringSet<> &SavedStrings) {
7103 if (Edit[0] ==
'^') {
7104 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7105 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7106 Args.insert(Args.begin() + 1, Str);
7107 }
else if (Edit[0] ==
'+') {
7108 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7109 OS <<
"### Adding argument " << Str <<
" at end\n";
7110 Args.push_back(Str);
7111 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7112 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7113 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7114 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7115 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7117 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7119 if (Args[i] ==
nullptr)
7121 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7123 if (Repl != Args[i]) {
7124 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7128 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7129 auto Option = Edit.substr(1);
7130 for (
unsigned i = 1; i < Args.size();) {
7131 if (Option == Args[i]) {
7132 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7133 Args.erase(Args.begin() + i);
7134 if (Edit[0] ==
'X') {
7135 if (i < Args.size()) {
7136 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7137 Args.erase(Args.begin() + i);
7139 OS <<
"### Invalid X edit, end of command line!\n";
7144 }
else if (Edit[0] ==
'O') {
7145 for (
unsigned i = 1; i < Args.size();) {
7146 const char *A = Args[i];
7150 if (A[0] ==
'-' && A[1] ==
'O' &&
7151 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7152 (
'0' <= A[2] && A[2] <=
'9'))))) {
7153 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7154 Args.erase(Args.begin() + i);
7158 OS <<
"### Adding argument " << Edit <<
" at end\n";
7159 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7161 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7166 const char *OverrideStr,
7167 llvm::StringSet<> &SavedStrings,
7170 OS = &llvm::nulls();
7172 if (OverrideStr[0] ==
'#') {
7174 OS = &llvm::nulls();
7177 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
7181 const char *S = OverrideStr;
7183 const char *End = ::strchr(S,
' ');
7185 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.