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;
311 bool UseDriverMode,
bool &ContainsError) {
312 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
313 ContainsError =
false;
315 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
316 unsigned MissingArgIndex, MissingArgCount;
317 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
318 MissingArgCount, VisibilityMask);
321 if (MissingArgCount) {
322 Diag(diag::err_drv_missing_argument)
323 << Args.getArgString(MissingArgIndex) << MissingArgCount;
330 for (
const Arg *A : Args) {
332 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
340 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
341 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
343 diag::warn_drv_empty_joined_argument,
348 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
350 auto ArgString = A->getAsString(Args);
352 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
354 getOpts().findExact(ArgString, Nearest,
356 DiagID = diag::err_drv_unknown_argument_with_suggestion;
357 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
359 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
360 : diag::err_drv_unknown_argument;
361 Diags.
Report(DiagID) << ArgString;
365 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
366 : diag::err_drv_unknown_argument_with_suggestion;
367 Diags.
Report(DiagID) << ArgString << Nearest;
373 for (
const Arg *A : Args.filtered(options::OPT_o)) {
374 if (ArgStrings[A->getIndex()] == A->getSpelling())
378 std::string ArgString = ArgStrings[A->getIndex()];
380 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
381 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
382 << A->getAsString(Args) << Nearest;
392 Arg **FinalPhaseArg)
const {
393 Arg *PhaseArg =
nullptr;
397 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
398 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
399 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
400 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
407 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
408 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
409 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
410 options::OPT_fmodule_header_EQ))) {
413 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
414 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
415 (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
416 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
417 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
418 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
419 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
420 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
421 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
422 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
423 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
427 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
431 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
434 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
442 *FinalPhaseArg = PhaseArg;
448 StringRef
Value,
bool Claim =
true) {
449 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
450 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
451 Args.AddSynthesizedArg(A);
457DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
458 const llvm::opt::OptTable &Opts =
getOpts();
459 DerivedArgList *DAL =
new DerivedArgList(Args);
461 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
462 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
463 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
464 bool IgnoreUnused =
false;
465 for (Arg *A : Args) {
469 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
473 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
474 IgnoreUnused =
false;
484 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
485 A->getOption().matches(options::OPT_Xlinker)) &&
486 A->containsValue(
"--no-demangle")) {
488 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
491 for (StringRef Val : A->getValues())
492 if (Val !=
"--no-demangle")
493 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
501 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
502 A->getNumValues() > 0 &&
503 (A->getValue(0) == StringRef(
"-MD") ||
504 A->getValue(0) == StringRef(
"-MMD"))) {
506 if (A->getValue(0) == StringRef(
"-MD"))
507 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
509 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
510 if (A->getNumValues() == 2)
511 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
516 if (A->getOption().matches(options::OPT_l)) {
517 StringRef
Value = A->getValue();
520 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
522 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
527 if (
Value ==
"cc_kext") {
528 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
534 if (A->getOption().matches(options::OPT__DASH_DASH)) {
536 for (StringRef Val : A->getValues())
545 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
546 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
549 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
550 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
554#if defined(HOST_LINK_VERSION)
555 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
556 strlen(HOST_LINK_VERSION) > 0) {
557 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
559 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
571 StringRef TargetTriple,
573 StringRef DarwinArchName =
"") {
575 if (
const Arg *A = Args.getLastArg(options::OPT_target))
576 TargetTriple = A->getValue();
578 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
583 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
587 if (
Target.isOSBinFormatMachO()) {
589 if (!DarwinArchName.empty()) {
596 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
597 StringRef ArchName = A->getValue();
604 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
605 options::OPT_mbig_endian)) {
606 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
607 ?
Target.getLittleEndianArchVariant()
608 :
Target.getBigEndianArchVariant();
609 if (
T.getArch() != llvm::Triple::UnknownArch) {
611 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
616 if (
Target.getArch() == llvm::Triple::tce)
621 if (std::optional<std::string> ObjectModeValue =
622 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
623 StringRef ObjectMode = *ObjectModeValue;
624 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
626 if (ObjectMode ==
"64") {
627 AT =
Target.get64BitArchVariant().getArch();
628 }
else if (ObjectMode ==
"32") {
629 AT =
Target.get32BitArchVariant().getArch();
631 D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
634 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
640 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
642 D.Diag(diag::err_drv_unsupported_opt_for_target)
643 << A->getAsString(Args) <<
Target.str();
646 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
647 options::OPT_m32, options::OPT_m16,
648 options::OPT_maix32, options::OPT_maix64);
650 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
652 if (A->getOption().matches(options::OPT_m64) ||
653 A->getOption().matches(options::OPT_maix64)) {
654 AT =
Target.get64BitArchVariant().getArch();
655 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
656 Target.getEnvironment() == llvm::Triple::GNUT64)
657 Target.setEnvironment(llvm::Triple::GNU);
658 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
659 Target.setEnvironment(llvm::Triple::Musl);
660 }
else if (A->getOption().matches(options::OPT_mx32) &&
661 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
662 AT = llvm::Triple::x86_64;
663 if (
Target.getEnvironment() == llvm::Triple::Musl)
664 Target.setEnvironment(llvm::Triple::MuslX32);
666 Target.setEnvironment(llvm::Triple::GNUX32);
667 }
else if (A->getOption().matches(options::OPT_m32) ||
668 A->getOption().matches(options::OPT_maix32)) {
669 AT =
Target.get32BitArchVariant().getArch();
670 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
671 Target.setEnvironment(llvm::Triple::GNU);
672 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
673 Target.setEnvironment(llvm::Triple::Musl);
674 }
else if (A->getOption().matches(options::OPT_m16) &&
675 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
676 AT = llvm::Triple::x86;
677 Target.setEnvironment(llvm::Triple::CODE16);
680 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
682 if (
Target.isWindowsGNUEnvironment())
688 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
689 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
690 D.Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
693 if (A && !A->getOption().matches(options::OPT_m32))
694 D.Diag(diag::err_drv_argument_not_allowed_with)
695 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
697 Target.setArch(llvm::Triple::x86);
698 Target.setArchName(
"i586");
699 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
700 Target.setEnvironmentName(
"");
701 Target.setOS(llvm::Triple::ELFIAMCU);
702 Target.setVendor(llvm::Triple::UnknownVendor);
703 Target.setVendorName(
"intel");
709 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
710 StringRef ABIName = A->getValue();
711 if (ABIName ==
"32") {
713 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
714 Target.getEnvironment() == llvm::Triple::GNUABIN32)
715 Target.setEnvironment(llvm::Triple::GNU);
716 }
else if (ABIName ==
"n32") {
718 if (
Target.getEnvironment() == llvm::Triple::GNU ||
719 Target.getEnvironment() == llvm::Triple::GNUT64 ||
720 Target.getEnvironment() == llvm::Triple::GNUABI64)
721 Target.setEnvironment(llvm::Triple::GNUABIN32);
722 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
723 Target.getEnvironment() == llvm::Triple::MuslABI64)
724 Target.setEnvironment(llvm::Triple::MuslABIN32);
725 }
else if (ABIName ==
"64") {
727 if (
Target.getEnvironment() == llvm::Triple::GNU ||
728 Target.getEnvironment() == llvm::Triple::GNUT64 ||
729 Target.getEnvironment() == llvm::Triple::GNUABIN32)
730 Target.setEnvironment(llvm::Triple::GNUABI64);
731 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
732 Target.getEnvironment() == llvm::Triple::MuslABIN32)
733 Target.setEnvironment(llvm::Triple::MuslABI64);
741 if (Args.hasArg(options::OPT_march_EQ) ||
742 Args.hasArg(options::OPT_mcpu_EQ)) {
744 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
746 if (!llvm::errorToBool(ISAInfo.takeError())) {
747 unsigned XLen = (*ISAInfo)->getXLen();
749 Target.setArch(llvm::Triple::riscv32);
751 Target.setArch(llvm::Triple::riscv64);
763 OptSpecifier OptEq, OptSpecifier OptNeg) {
764 if (!Args.hasFlag(OptEq, OptNeg,
false))
767 const Arg *A = Args.getLastArg(OptEq);
768 StringRef LTOName = A->getValue();
776 D.Diag(diag::err_drv_unsupported_option_argument)
777 << A->getSpelling() << A->getValue();
784void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
786 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
788 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
789 options::OPT_fno_offload_lto);
792 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
793 options::OPT_fno_openmp_target_jit,
false)) {
794 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
795 options::OPT_fno_offload_lto))
797 Diag(diag::err_drv_incompatible_options)
798 << A->getSpelling() <<
"-fopenmp-target-jit";
805 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
807 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
809 RuntimeName = A->getValue();
811 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
819 Diag(diag::err_drv_unsupported_option_argument)
820 << A->getSpelling() << A->getValue();
823 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
832 if (llvm::is_contained(SYCLAlias, TargetArch)) {
833 llvm::Triple TargetTriple;
834 TargetTriple.setArchName(TargetArch);
835 TargetTriple.setVendor(llvm::Triple::UnknownVendor);
836 TargetTriple.setOS(llvm::Triple::UnknownOS);
839 return llvm::Triple(TargetArch);
845 for (
const auto &SYCLTriple : SYCLTriples) {
846 if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
847 SYCLTriple.isSPIROrSPIRV())
852 C.getDefaultToolChain().getTriple().isArch32Bit() ?
"spirv32"
854 SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple);
867 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
872 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
875 C.getInputArgs().hasArg(options::OPT_hip_link) ||
876 C.getInputArgs().hasArg(options::OPT_hipstdpar);
877 bool UseLLVMOffload =
C.getInputArgs().hasArg(
878 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
879 if (IsCuda && IsHIP) {
880 Diag(clang::diag::err_drv_mix_cuda_hip);
883 if (IsCuda && !UseLLVMOffload) {
885 const llvm::Triple &HostTriple = HostTC->
getTriple();
893 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
895 CudaTC = std::make_unique<toolchains::CudaToolChain>(
896 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
901 if (CudaInstallation.
isValid())
904 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
905 }
else if (IsHIP && !UseLLVMOffload) {
906 if (
auto *OMPTargetArg =
907 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
908 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
909 << OMPTargetArg->getSpelling() <<
"HIP";
917 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
919 C.addOffloadDeviceToolChain(HIPTC, OFK);
930 bool IsOpenMPOffloading =
931 ((IsCuda || IsHIP) && UseLLVMOffload) ||
932 (
C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
933 options::OPT_fno_openmp,
false) &&
934 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
935 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ)));
936 if (IsOpenMPOffloading) {
942 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
946 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
947 llvm::StringMap<StringRef> FoundNormalizedTriples;
948 std::multiset<StringRef> OpenMPTriples;
953 if (Arg *OpenMPTargets =
954 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
955 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
956 Diag(clang::diag::warn_drv_empty_joined_argument)
957 << OpenMPTargets->getAsString(
C.getInputArgs());
960 for (StringRef
T : OpenMPTargets->getValues())
961 OpenMPTriples.insert(
T);
962 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
963 ((!IsHIP && !IsCuda) || UseLLVMOffload)) {
973 llvm::DenseSet<StringRef> Archs;
975 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
976 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
982 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
983 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
988 if (!AMDTriple && !NVPTXTriple) {
989 for (StringRef Arch :
994 for (StringRef Arch : Archs) {
997 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
998 }
else if (AMDTriple &&
1001 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
1003 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
1009 if (Archs.empty()) {
1010 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
1015 for (
const auto &TripleAndArchs : DerivedArchs)
1016 OpenMPTriples.insert(TripleAndArchs.first());
1019 for (StringRef Val : OpenMPTriples) {
1021 std::string NormalizedName = TT.normalize();
1024 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
1025 if (Duplicate != FoundNormalizedTriples.end()) {
1026 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1027 << Val << Duplicate->second;
1033 FoundNormalizedTriples[NormalizedName] = Val;
1036 if (TT.getArch() == llvm::Triple::UnknownArch)
1037 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
1042 if (TT.isNVPTX() || TT.isAMDGCN() || TT.isSPIRV()) {
1045 assert(HostTC &&
"Host toolchain should be always defined.");
1047 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
1050 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
1051 *
this, TT, *HostTC,
C.getInputArgs());
1052 else if (TT.isAMDGCN())
1053 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
1054 *
this, TT, *HostTC,
C.getInputArgs());
1055 else if (TT.isSPIRV())
1056 DeviceTC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(
1057 *
this, TT, *HostTC,
C.getInputArgs());
1059 assert(DeviceTC &&
"Device toolchain not defined.");
1062 TC = DeviceTC.get();
1064 TC = &getToolChain(
C.getInputArgs(), TT);
1066 auto It = DerivedArchs.find(TT.getTriple());
1067 if (It != DerivedArchs.end())
1068 KnownArchs[TC] = It->second;
1071 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
1072 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1077 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1078 options::OPT_fno_sycl,
false);
1080 auto argSYCLIncompatible = [&](OptSpecifier OptId) {
1083 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(OptId))
1084 Diag(clang::diag::err_drv_argument_not_allowed_with)
1085 << IncompatArg->getSpelling() <<
"-fsycl";
1088 argSYCLIncompatible(options::OPT_static_libstdcxx);
1090 argSYCLIncompatible(options::OPT_ffreestanding);
1101 for (
const auto &TargetTriple : UniqueSYCLTriplesVec) {
1102 auto SYCLTC = &getOffloadingDeviceToolChain(
1113bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1118 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1122 if (!PathLIBEnv.empty()) {
1123 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1124 if (llvm::sys::fs::is_directory(PathLIBEnv))
1125 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1126 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1127 return readConfigFile(CustomizationFile, ExpCtx);
1128 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1133 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1134 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1135 return readConfigFile(CustomizationFile, ExpCtx);
1145 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1146 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1147 Copy->getValues() = Opt->getValues();
1148 if (Opt->isClaimed())
1150 Copy->setOwnsValues(Opt->getOwnsValues());
1151 Opt->setOwnsValues(
false);
1153 if (Opt->getAlias()) {
1154 const Arg *Alias = Opt->getAlias();
1155 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1156 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1157 Args.getArgString(Index), Index);
1158 AliasCopy->getValues() = Alias->getValues();
1159 AliasCopy->setOwnsValues(
false);
1160 if (Alias->isClaimed())
1162 Copy->setAlias(std::move(AliasCopy));
1166bool Driver::readConfigFile(StringRef
FileName,
1167 llvm::cl::ExpansionContext &ExpCtx) {
1171 Diag(diag::err_drv_cannot_open_config_file)
1172 <<
FileName << Status.getError().message();
1175 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1176 Diag(diag::err_drv_cannot_open_config_file)
1177 <<
FileName <<
"not a regular file";
1183 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1184 Diag(diag::err_drv_cannot_read_config_file)
1191 for (
const char *Opt : NewCfgFileArgs) {
1193 if (Opt[0] ==
'$' && Opt[1])
1194 NewCfgTailArgs.push_back(Opt + 1);
1196 NewCfgHeadArgs.push_back(Opt);
1201 llvm::sys::path::native(CfgFileName);
1202 bool ContainErrors =
false;
1203 auto NewHeadOptions = std::make_unique<InputArgList>(
1207 auto NewTailOptions = std::make_unique<InputArgList>(
1214 for (Arg *A : *NewHeadOptions)
1216 for (Arg *A : *NewTailOptions)
1219 if (!CfgOptionsHead)
1220 CfgOptionsHead = std::move(NewHeadOptions);
1223 for (
auto *Opt : *NewHeadOptions)
1227 if (!CfgOptionsTail)
1228 CfgOptionsTail = std::move(NewTailOptions);
1231 for (
auto *Opt : *NewTailOptions)
1235 ConfigFiles.push_back(std::string(CfgFileName));
1239bool Driver::loadConfigFiles() {
1240 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1241 llvm::cl::tokenizeConfigFile);
1242 ExpCtx.setVFS(&
getVFS());
1246 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1249 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1250 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1255 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1257 llvm::sys::fs::expand_tilde(
1258 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1259 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1268 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1271 if (loadDefaultConfigFiles(ExpCtx))
1277 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1280 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1281 CfgFilePath.assign(CfgFileName);
1282 if (llvm::sys::path::is_relative(CfgFilePath)) {
1283 if (
getVFS().makeAbsolute(CfgFilePath)) {
1284 Diag(diag::err_drv_cannot_open_config_file)
1285 << CfgFilePath <<
"cannot get absolute path";
1289 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1291 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1292 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1293 if (!SearchDir.empty())
1294 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1299 if (readConfigFile(CfgFilePath, ExpCtx))
1310 llvm::Triple Triple, std::string Suffix) {
1312 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1316 VersionTuple OSVersion = Triple.getOSVersion();
1317 if (!OSVersion.getMinor().has_value())
1320 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1324 if (OSVersion.getMajor() != 0) {
1325 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1326 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1332 Triple.setOSName(BaseOSName);
1333 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1336bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1339 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1343 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1346 std::string RealMode = getExecutableForDriverMode(Mode);
1347 llvm::Triple Triple;
1356 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1357 PrefixTriple.isOSUnknown())
1358 Triple = PrefixTriple;
1362 llvm::Triple RealTriple =
1364 if (Triple.str().empty()) {
1365 Triple = RealTriple;
1366 assert(!Triple.str().empty());
1371 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1387 "-" + RealMode +
".cfg"))
1388 return readConfigFile(CfgFilePath, ExpCtx);
1392 if (TryModeSuffix) {
1395 return readConfigFile(CfgFilePath, ExpCtx);
1400 std::string CfgFileName = RealMode +
".cfg";
1401 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1402 if (readConfigFile(CfgFilePath, ExpCtx))
1404 }
else if (TryModeSuffix) {
1406 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1407 readConfigFile(CfgFilePath, ExpCtx))
1413 return readConfigFile(CfgFilePath, ExpCtx);
1421 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1430 if (!DriverMode.empty())
1431 setDriverMode(DriverMode);
1437 CLOptions = std::make_unique<InputArgList>(
1442 ContainsError = loadConfigFiles();
1443 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1444 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1448 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1450 if (HasConfigFileHead)
1451 for (
auto *Opt : *CLOptions)
1452 if (!Opt->getOption().matches(options::OPT_config))
1456 if (
IsCLMode() && !ContainsError) {
1458 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1460 CLModePassThroughArgList.push_back(A->getValue());
1463 if (!CLModePassThroughArgList.empty()) {
1466 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1471 for (
auto *Opt : *CLModePassThroughOptions)
1477 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1478 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1479 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1483 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1484 if (!VFS->exists(IncludeDir))
1485 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1490 bool CCCPrintPhases;
1493 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1494 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1497 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1498 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1501 Args.ClaimAllArgs(options::OPT_pipe);
1509 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1511 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1512 CCCGenericGCCName = A->getValue();
1515 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1519 if (Args.hasArg(options::OPT_fproc_stat_report))
1526 llvm::Triple
T(TargetTriple);
1527 T.setOS(llvm::Triple::Win32);
1528 T.setVendor(llvm::Triple::PC);
1529 T.setEnvironment(llvm::Triple::MSVC);
1530 T.setObjectFormat(llvm::Triple::COFF);
1531 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1532 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1533 TargetTriple =
T.str();
1536 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1537 StringRef TargetProfile = A->getValue();
1540 TargetTriple = *Triple;
1542 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1546 if (Args.hasArg(options::OPT_spirv)) {
1547 llvm::Triple
T(TargetTriple);
1548 T.setArch(llvm::Triple::spirv);
1549 T.setOS(llvm::Triple::Vulkan);
1552 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1553 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1554 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1555 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1557 auto TargetInfo = ValidTargets.find(A->getValue());
1560 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1562 Diag(diag::err_drv_invalid_value)
1563 << A->getAsString(Args) << A->getValue();
1568 TargetTriple =
T.str();
1571 Diag(diag::err_drv_dxc_missing_target_profile);
1575 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1576 TargetTriple = A->getValue();
1577 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1578 Dir =
Dir = A->getValue();
1579 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1583 if (std::optional<std::string> CompilerPathValue =
1584 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1585 StringRef CompilerPath = *CompilerPathValue;
1586 while (!CompilerPath.empty()) {
1587 std::pair<StringRef, StringRef> Split =
1588 CompilerPath.split(llvm::sys::EnvPathSeparator);
1589 PrefixDirs.push_back(std::string(Split.first));
1590 CompilerPath = Split.second;
1593 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1595 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1598 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1601 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1602 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1603 .Case(
"cwd", SaveTempsCwd)
1604 .Case(
"obj", SaveTempsObj)
1605 .Default(SaveTempsCwd);
1608 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1609 options::OPT_offload_device_only,
1610 options::OPT_offload_host_device)) {
1611 if (A->getOption().matches(options::OPT_offload_host_only))
1612 Offload = OffloadHost;
1613 else if (A->getOption().matches(options::OPT_offload_device_only))
1614 Offload = OffloadDevice;
1616 Offload = OffloadHostDevice;
1622 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1623 StringRef
Name = A->getValue();
1624 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1625 .Case(
"off", EmbedNone)
1626 .Case(
"all", EmbedBitcode)
1627 .Case(
"bitcode", EmbedBitcode)
1628 .Case(
"marker", EmbedMarker)
1631 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1634 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1638 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1639 llvm::sys::fs::remove(A->getValue());
1645 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1647 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1648 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1649 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1650 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1651 Std->containsValue(
"c++latest"));
1654 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1655 options::OPT_fmodule_header)) {
1657 ModulesModeCXX20 =
true;
1658 if (A->getOption().matches(options::OPT_fmodule_header))
1661 StringRef ArgName = A->getValue();
1662 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1667 Diags.
Report(diag::err_drv_invalid_value)
1668 << A->getAsString(Args) << ArgName;
1674 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1675 std::make_unique<InputArgList>(std::move(Args));
1678 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1686 if (!Triple.isWasm()) {
1687 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1688 StringRef TripleObjectFormat =
1689 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1690 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1691 TripleVersionName != TripleObjectFormat) {
1692 Diags.
Report(diag::err_drv_triple_version_invalid)
1694 ContainsError =
true;
1699 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1700 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1701 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1709 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1710 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1712 case llvm::Triple::arm:
1713 case llvm::Triple::armeb:
1714 case llvm::Triple::thumb:
1715 case llvm::Triple::thumbeb:
1716 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1717 Diag(diag::warn_target_unrecognized_env)
1719 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1722 case llvm::Triple::aarch64:
1723 case llvm::Triple::aarch64_be:
1724 case llvm::Triple::aarch64_32:
1725 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1726 Diag(diag::warn_target_unrecognized_env)
1728 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1745 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1746 if (HasConfigFileTail && Inputs.size()) {
1749 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1750 for (Arg *A : *CfgOptionsTail)
1751 TranslatedLinkerIns.append(A);
1752 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1761 if (TC.
getTriple().isOSBinFormatMachO())
1766 if (CCCPrintPhases) {
1777 llvm::opt::ArgStringList ASL;
1778 for (
const auto *A : Args) {
1782 while (A->getAlias())
1784 A->render(Args, ASL);
1787 for (
auto I = ASL.begin(),
E = ASL.end(); I !=
E; ++I) {
1788 if (I != ASL.begin())
1790 llvm::sys::printArg(OS, *I,
true);
1795bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1797 using namespace llvm::sys;
1798 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1799 "Only knows about .crash files on Darwin");
1804 path::home_directory(CrashDiagDir);
1805 if (CrashDiagDir.starts_with(
"/var/root"))
1807 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1815 fs::file_status FileStatus;
1816 TimePoint<> LastAccessTime;
1820 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1821 File != FileEnd && !EC;
File.increment(EC)) {
1825 if (fs::status(
File->path(), FileStatus))
1827 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1828 llvm::MemoryBuffer::getFile(
File->path());
1833 StringRef
Data = CrashFile.get()->getBuffer();
1834 if (!
Data.starts_with(
"Process:"))
1837 size_t ParentProcPos =
Data.find(
"Parent Process:");
1838 if (ParentProcPos == StringRef::npos)
1840 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1841 if (LineEnd == StringRef::npos)
1843 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1844 int OpenBracket = -1, CloseBracket = -1;
1845 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1846 if (ParentProcess[i] ==
'[')
1848 if (ParentProcess[i] ==
']')
1854 if (OpenBracket < 0 || CloseBracket < 0 ||
1855 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1856 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1866 const auto FileAccessTime = FileStatus.getLastModificationTime();
1867 if (FileAccessTime > LastAccessTime) {
1868 CrashFilePath.assign(
File->path());
1869 LastAccessTime = FileAccessTime;
1874 if (!CrashFilePath.empty()) {
1875 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1885 "\n********************\n\n"
1886 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1887 "Preprocessed source(s) and associated run script(s) are located at:";
1895 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1899 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1900 Level = llvm::StringSwitch<unsigned>(A->getValue())
1902 .Case(
"compiler", 1)
1914 ArgStringList SavedTemps;
1916 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1917 if (!IsLLD || Level < 2)
1924 SavedTemps = std::move(
C.getTempFiles());
1925 assert(!
C.getTempFiles().size());
1942 C.initCompilationForDiagnostics();
1948 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1949 StringRef ReproduceOption =
1950 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1953 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1957 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1959 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1960 Diag(clang::diag::note_drv_command_failed_diag_msg)
1961 <<
"\n\n********************";
1963 Report->TemporaryFiles.push_back(TmpName);
1971 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1972 bool IgnoreInput =
false;
1978 }
else if (!strcmp(it->second->getValue(),
"-")) {
1979 Diag(clang::diag::note_drv_command_failed_diag_msg)
1980 <<
"Error generating preprocessed source(s) - "
1981 "ignoring input from stdin.";
1986 it = Inputs.erase(it);
1993 if (Inputs.empty()) {
1994 Diag(clang::diag::note_drv_command_failed_diag_msg)
1995 <<
"Error generating preprocessed source(s) - "
1996 "no preprocessable inputs.";
2002 llvm::StringSet<> ArchNames;
2003 for (
const Arg *A :
C.getArgs()) {
2004 if (A->getOption().matches(options::OPT_arch)) {
2005 StringRef ArchName = A->getValue();
2006 ArchNames.insert(ArchName);
2009 if (ArchNames.size() > 1) {
2010 Diag(clang::diag::note_drv_command_failed_diag_msg)
2011 <<
"Error generating preprocessed source(s) - cannot generate "
2012 "preprocessed source with multiple -arch options.";
2018 const ToolChain &TC =
C.getDefaultToolChain();
2019 if (TC.
getTriple().isOSBinFormatMachO())
2028 Diag(clang::diag::note_drv_command_failed_diag_msg)
2029 <<
"Error generating preprocessed source(s).";
2035 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2038 if (!FailingCommands.empty()) {
2039 Diag(clang::diag::note_drv_command_failed_diag_msg)
2040 <<
"Error generating preprocessed source(s).";
2044 const ArgStringList &TempFiles =
C.getTempFiles();
2045 if (TempFiles.empty()) {
2046 Diag(clang::diag::note_drv_command_failed_diag_msg)
2047 <<
"Error generating preprocessed source(s).";
2055 for (
const char *TempFile : TempFiles) {
2056 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2058 Report->TemporaryFiles.push_back(TempFile);
2059 if (ReproCrashFilename.empty()) {
2060 ReproCrashFilename = TempFile;
2061 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2063 if (StringRef(TempFile).ends_with(
".cache")) {
2066 VFS = llvm::sys::path::filename(TempFile);
2067 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2071 for (
const char *TempFile : SavedTemps)
2072 C.addTempFile(TempFile);
2078 llvm::sys::path::replace_extension(Script,
"sh");
2080 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2081 llvm::sys::fs::FA_Write,
2082 llvm::sys::fs::OF_Text);
2084 Diag(clang::diag::note_drv_command_failed_diag_msg)
2085 <<
"Error generating run script: " << Script <<
" " << EC.message();
2088 <<
"# Driver args: ";
2090 ScriptOS <<
"# Original command: ";
2091 Cmd.Print(ScriptOS,
"\n",
true);
2092 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
2093 if (!AdditionalInformation.empty())
2094 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2097 Report->TemporaryFiles.push_back(std::string(Script));
2098 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2102 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2104 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2105 Diag(clang::diag::note_drv_command_failed_diag_msg)
2106 << ReproCrashFilename.str();
2108 llvm::sys::path::append(CrashDiagDir,
Name);
2109 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2110 Diag(clang::diag::note_drv_command_failed_diag_msg)
2111 <<
"Crash backtrace is located in";
2112 Diag(clang::diag::note_drv_command_failed_diag_msg)
2113 << CrashDiagDir.str();
2114 Diag(clang::diag::note_drv_command_failed_diag_msg)
2115 <<
"(choose the .crash file that corresponds to your crash)";
2119 Diag(clang::diag::note_drv_command_failed_diag_msg)
2120 <<
"\n\n********************";
2128 if (
Cmd.getResponseFileSupport().ResponseKind ==
2130 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
2131 Cmd.getArguments()))
2135 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
2141 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2142 if (
C.getArgs().hasArg(options::OPT_v))
2143 C.getJobs().Print(llvm::errs(),
"\n",
true);
2145 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2155 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2156 C.getJobs().Print(llvm::errs(),
"\n",
true);
2165 for (
auto &Job :
C.getJobs())
2166 setUpResponseFiles(
C, Job);
2168 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2171 if (FailingCommands.empty())
2177 for (
const auto &CmdPair : FailingCommands) {
2178 int CommandRes = CmdPair.first;
2179 const Command *FailingCommand = CmdPair.second;
2184 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2188 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2193 if (CommandRes == EX_IOERR) {
2210 Diag(clang::diag::err_drv_command_signalled)
2213 Diag(clang::diag::err_drv_command_failed)
2221 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2223 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2237 const ToolChain &TC =
C.getDefaultToolChain();
2241 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2244 OS <<
"Thread model: " << A->getValue();
2250 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2255 if (!llvm::cl::getCompilerBuildConfig().empty())
2256 llvm::cl::printBuildConfig(OS);
2259 for (
auto ConfigFile : ConfigFiles)
2260 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2273 if (PassedFlags ==
"")
2277 std::vector<std::string> SuggestedCompletions;
2278 std::vector<std::string> Flags;
2290 const bool HasSpace = PassedFlags.ends_with(
",");
2294 StringRef TargetFlags = PassedFlags;
2295 while (TargetFlags !=
"") {
2297 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2298 Flags.push_back(std::string(CurFlag));
2303 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2306 const llvm::opt::OptTable &Opts =
getOpts();
2308 Cur = Flags.at(Flags.size() - 1);
2310 if (Flags.size() >= 2) {
2311 Prev = Flags.at(Flags.size() - 2);
2312 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2315 if (SuggestedCompletions.empty())
2316 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2323 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2324 llvm::outs() <<
'\n';
2330 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2334 SuggestedCompletions = Opts.findByPrefix(
2335 Cur, VisibilityMask,
2342 if (S.starts_with(Cur))
2343 SuggestedCompletions.push_back(std::string(S));
2350 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2351 if (
int X = A.compare_insensitive(B))
2353 return A.compare(B) > 0;
2356 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2363 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2364 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2368 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2371 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2375 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2380 if (
C.getArgs().hasArg(options::OPT_help) ||
2381 C.getArgs().hasArg(options::OPT__help_hidden)) {
2382 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2386 if (
C.getArgs().hasArg(options::OPT__version)) {
2392 if (
C.getArgs().hasArg(options::OPT_v) ||
2393 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2394 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2395 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2396 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2398 SuppressMissingInputWarning =
true;
2401 if (
C.getArgs().hasArg(options::OPT_v)) {
2403 llvm::errs() <<
"System configuration file directory: "
2406 llvm::errs() <<
"User configuration file directory: "
2410 const ToolChain &TC =
C.getDefaultToolChain();
2412 if (
C.getArgs().hasArg(options::OPT_v))
2415 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2420 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2421 llvm::outs() <<
"programs: =";
2422 bool separator =
false;
2426 llvm::outs() << llvm::sys::EnvPathSeparator;
2427 llvm::outs() <<
Path;
2432 llvm::outs() << llvm::sys::EnvPathSeparator;
2433 llvm::outs() <<
Path;
2436 llvm::outs() <<
"\n";
2439 StringRef sysroot =
C.getSysRoot();
2443 llvm::outs() << llvm::sys::EnvPathSeparator;
2446 llvm::outs() << sysroot <<
Path.substr(1);
2448 llvm::outs() <<
Path;
2450 llvm::outs() <<
"\n";
2454 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2460 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2461 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2462 llvm::outs() << *RuntimePath <<
'\n';
2468 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2470 for (std::size_t I = 0; I != Flags.size(); I += 2)
2471 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2477 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2478 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2482 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2483 StringRef ProgName = A->getValue();
2486 if (! ProgName.empty())
2489 llvm::outs() <<
"\n";
2493 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2494 StringRef PassedFlags = A->getValue();
2499 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2513 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2516 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2522 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2529 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2532 std::set<llvm::StringRef> SortedFlags;
2533 for (
const auto &FlagEntry : ExpandedFlags)
2534 SortedFlags.insert(FlagEntry.getKey());
2535 for (
auto Flag : SortedFlags)
2536 llvm::outs() << Flag <<
'\n';
2540 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2543 llvm::outs() <<
".\n";
2546 assert(Suffix.front() ==
'/');
2547 llvm::outs() << Suffix.substr(1) <<
"\n";
2553 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2558 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2560 llvm::outs() << Triple.getTriple() <<
"\n";
2564 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2565 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2582 std::map<Action *, unsigned> &Ids,
2584 if (
auto It = Ids.find(A); It != Ids.end())
2588 llvm::raw_string_ostream os(str);
2590 auto getSibIndent = [](
int K) -> Twine {
2594 Twine SibIndent = Indent + getSibIndent(Kind);
2598 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2600 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2601 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2602 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2603 bool IsFirst =
true;
2604 OA->doOnEachDependence(
2606 assert(TC &&
"Unknown host toolchain");
2618 os <<
":" << BoundArch;
2621 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2629 const char *Prefix =
"{";
2630 for (
Action *PreRequisite : *AL) {
2631 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2642 std::string offload_str;
2643 llvm::raw_string_ostream offload_os(offload_str);
2644 if (!isa<OffloadAction>(A)) {
2647 offload_os <<
", (" << S;
2654 auto getSelfIndent = [](
int K) -> Twine {
2658 unsigned Id = Ids.size();
2660 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2669 std::map<Action *, unsigned> Ids;
2670 for (
Action *A :
C.getActions())
2677 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2678 isa<AssembleJobAction>(A))
2686 DerivedArgList &Args =
C.getArgs();
2688 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2691 llvm::StringSet<> ArchNames;
2693 for (Arg *A : Args) {
2694 if (A->getOption().matches(options::OPT_arch)) {
2697 llvm::Triple::ArchType Arch =
2699 if (Arch == llvm::Triple::UnknownArch) {
2700 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2705 if (ArchNames.insert(A->getValue()).second)
2706 Archs.push_back(A->getValue());
2720 for (
Action* Act : SingleActions) {
2728 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2732 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2737 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2738 Actions.append(Inputs.begin(), Inputs.end());
2740 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2743 Arg *A = Args.getLastArg(options::OPT_g_Group);
2744 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2745 !A->getOption().matches(options::OPT_gstabs);
2753 if (Act->getType() == types::TY_Image) {
2755 Inputs.push_back(Actions.back());
2762 if (Args.hasArg(options::OPT_verify_debug_info)) {
2763 Action* LastAction = Actions.back();
2766 LastAction, types::TY_Nothing));
2785 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2786 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2798 std::string Nearest;
2799 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2800 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2801 <<
Value << Nearest;
2840 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2843 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2851 return types::TY_CXXUHeader;
2853 return types::TY_CXXSHeader;
2857 llvm_unreachable(
"should not be called in this case");
2859 return types::TY_CXXHUHeader;
2865 const llvm::opt::OptTable &Opts =
getOpts();
2869 types::ID InputType = types::TY_Nothing;
2870 Arg *InputTypeArg =
nullptr;
2873 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2874 options::OPT__SLASH_TP)) {
2875 InputTypeArg = TCTP;
2876 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2881 bool ShowNote =
false;
2883 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2885 Diag(clang::diag::warn_drv_overriding_option)
2886 <<
Previous->getSpelling() << A->getSpelling();
2892 Diag(clang::diag::note_drv_t_option_is_global);
2897 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2898 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2899 if (LastXArg && LastInputArg &&
2900 LastInputArg->getIndex() < LastXArg->getIndex())
2901 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2904 for (Arg *A : Args) {
2905 if (A->getOption().
getKind() == Option::InputClass) {
2906 const char *
Value = A->getValue();
2910 if (InputType == types::TY_Nothing) {
2913 InputTypeArg->claim();
2916 if (memcmp(
Value,
"-", 2) == 0) {
2918 Ty = types::TY_Fortran;
2920 Ty = types::TY_HLSL;
2929 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2930 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2931 : clang::diag::err_drv_unknown_stdin_type);
2940 if (
const char *Ext = strrchr(
Value,
'.'))
2949 Ty = types::TY_Object;
2960 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2961 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2962 << getTypeName(OldTy) << getTypeName(Ty);
2967 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2968 Ty == types::TY_Object)
2969 Ty = types::TY_LLVM_BC;
2977 if (Ty != types::TY_Object) {
2978 if (Args.hasArg(options::OPT_ObjC))
2979 Ty = types::TY_ObjC;
2980 else if (Args.hasArg(options::OPT_ObjCXX))
2981 Ty = types::TY_ObjCXX;
2988 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
2992 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2993 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2996 const char *Ext = strrchr(
Value,
'.');
2998 Ty = types::TY_Object;
3002 InputTypeArg->claim();
3006 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3007 Args.hasArgNoClaim(options::OPT_hipstdpar))
3011 Inputs.push_back(std::make_pair(Ty, A));
3013 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3014 StringRef
Value = A->getValue();
3017 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3018 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3021 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3022 StringRef
Value = A->getValue();
3025 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3026 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3032 Inputs.push_back(std::make_pair(types::TY_Object, A));
3034 }
else if (A->getOption().matches(options::OPT_x)) {
3043 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3044 InputType = types::TY_Object;
3051 }
else if (A->getOption().getID() == options::OPT_U) {
3052 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3053 StringRef Val = A->getValue(0);
3054 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3056 Diag(diag::warn_slash_u_filename) << Val;
3057 Diag(diag::note_use_dashdash);
3061 if (
CCCIsCPP() && Inputs.empty()) {
3065 Inputs.push_back(std::make_pair(types::TY_C, A));
3072class OffloadingActionBuilder final {
3074 bool IsValid =
false;
3080 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3083 std::map<Action *, const Arg *> HostActionToInputArgMap;
3086 class DeviceActionBuilder {
3090 enum ActionBuilderReturnCode {
3109 DerivedArgList &Args;
3118 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3121 :
C(
C), Args(Args), Inputs(Inputs),
3122 AssociatedOffloadKind(AssociatedOffloadKind) {}
3123 virtual ~DeviceActionBuilder() {}
3128 virtual ActionBuilderReturnCode
3132 return ABRT_Inactive;
3137 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
3138 return ABRT_Inactive;
3142 virtual void appendTopLevelActions(
ActionList &AL) {}
3145 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3158 virtual bool canUseBundlerUnbundler()
const {
return false; }
3162 bool isValid() {
return !ToolChains.empty(); }
3166 return AssociatedOffloadKind;
3172 class CudaActionBuilderBase :
public DeviceActionBuilder {
3176 bool CompileHostOnly =
false;
3177 bool CompileDeviceOnly =
false;
3179 bool EmitAsm =
false;
3189 TargetID(
const char *
ID) :
ID(
ID) {}
3190 operator const char *() {
return ID; }
3191 operator StringRef() {
return StringRef(
ID); }
3200 Action *CudaFatBinary =
nullptr;
3203 bool IsActive =
false;
3206 bool Relocatable =
false;
3209 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3215 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
3218 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3219 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3221 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3222 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3223 options::OPT_fno_gpu_rdc,
false);
3226 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3233 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3234 assert(!GpuArchList.empty() &&
3235 "We should have at least one GPU architecture.");
3239 if (!(IA->getType() == types::TY_CUDA ||
3240 IA->getType() == types::TY_HIP ||
3241 IA->getType() == types::TY_PP_HIP)) {
3244 return ABRT_Inactive;
3251 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3253 if (CompileHostOnly)
3254 return ABRT_Success;
3257 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3258 : types::TY_CUDA_DEVICE;
3259 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3260 CudaDeviceActions.push_back(
3261 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3264 return ABRT_Success;
3268 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3272 if (UA->getType() == types::TY_Object && !Relocatable)
3273 return ABRT_Inactive;
3275 CudaDeviceActions.clear();
3276 auto *IA = cast<InputAction>(UA->getInputs().back());
3277 std::string
FileName = IA->getInputArg().getAsString(Args);
3283 const StringRef LibFileExt =
".lib";
3284 if (IA->getType() == types::TY_Object &&
3285 (!llvm::sys::path::has_extension(
FileName) ||
3287 llvm::sys::path::extension(
FileName).drop_front()) !=
3289 llvm::sys::path::extension(
FileName) == LibFileExt))
3290 return ABRT_Inactive;
3292 for (
auto Arch : GpuArchList) {
3293 CudaDeviceActions.push_back(UA);
3294 UA->registerDependentActionInfo(ToolChains[0], Arch,
3295 AssociatedOffloadKind);
3298 return ABRT_Success;
3301 return IsActive ? ABRT_Success : ABRT_Inactive;
3304 void appendTopLevelActions(
ActionList &AL)
override {
3306 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3308 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3313 if (CudaFatBinary) {
3314 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3315 CudaDeviceActions.clear();
3316 CudaFatBinary =
nullptr;
3320 if (CudaDeviceActions.empty())
3326 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3327 "Expecting one action per GPU architecture.");
3328 assert(ToolChains.size() == 1 &&
3329 "Expecting to have a single CUDA toolchain.");
3330 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I)
3331 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3333 CudaDeviceActions.clear();
3338 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3340 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3358 assert(HostTC &&
"No toolchain for host compilation.");
3360 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3364 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3369 ToolChains.push_back(
3374 CompileHostOnly =
C.getDriver().offloadHostOnly();
3375 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3376 EmitAsm = Args.getLastArg(options::OPT_S);
3379 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3380 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3381 options::OPT_no_offload_arch_EQ)) {
3382 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3387 std::set<StringRef> GpuArchs;
3389 for (Arg *A : Args) {
3390 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3391 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3395 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3396 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3399 }
else if (ArchStr ==
"native") {
3400 const ToolChain &TC = *ToolChains.front();
3401 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3404 << llvm::Triple::getArchTypeName(TC.
getArch())
3405 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3409 for (
auto GPU : *GPUsOrErr) {
3410 GpuArchs.insert(Args.MakeArgString(GPU));
3413 ArchStr = getCanonicalOffloadArch(ArchStr);
3414 if (ArchStr.empty()) {
3416 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3417 GpuArchs.insert(ArchStr);
3418 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3419 GpuArchs.erase(ArchStr);
3421 llvm_unreachable(
"Unexpected option.");
3427 if (ConflictingArchs) {
3428 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3429 << ConflictingArchs->first << ConflictingArchs->second;
3430 C.setContainsError();
3435 for (
auto Arch : GpuArchs)
3436 GpuArchList.push_back(Arch.data());
3441 if (GpuArchList.empty()) {
3442 if (ToolChains.front()->getTriple().isSPIRV()) {
3443 if (ToolChains.front()->getTriple().getVendor() == llvm::Triple::AMD)
3444 GpuArchList.push_back(OffloadArch::AMDGCNSPIRV);
3446 GpuArchList.push_back(OffloadArch::Generic);
3448 GpuArchList.push_back(DefaultOffloadArch);
3458 class CudaActionBuilder final :
public CudaActionBuilderBase {
3460 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3462 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3463 DefaultOffloadArch = OffloadArch::CudaDefault;
3466 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3469 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3475 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3477 const std::set<StringRef> &GpuArchs)
override {
3478 return std::nullopt;
3481 ActionBuilderReturnCode
3484 PhasesTy &Phases)
override {
3486 return ABRT_Inactive;
3490 if (CudaDeviceActions.empty())
3491 return ABRT_Success;
3493 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3494 "Expecting one action per GPU architecture.");
3495 assert(!CompileHostOnly &&
3496 "Not expecting CUDA actions in host-only compilation.");
3506 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3509 for (
auto Ph : Phases) {
3514 if (Ph > FinalPhase)
3517 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3527 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3531 Action *AssembleAction = CudaDeviceActions[I];
3532 assert(AssembleAction->
getType() == types::TY_Object);
3533 assert(AssembleAction->
getInputs().size() == 1);
3541 DeviceActions.push_back(
3547 if (!DeviceActions.empty()) {
3549 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3551 if (!CompileDeviceOnly) {
3552 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3556 CudaFatBinary =
nullptr;
3561 CudaDeviceActions.clear();
3565 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3570 return ABRT_Success;
3574 "instructions should only occur "
3575 "before the backend phase!");
3578 for (
Action *&A : CudaDeviceActions)
3579 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3581 return ABRT_Success;
3586 class HIPActionBuilder final :
public CudaActionBuilderBase {
3594 std::optional<bool> BundleOutput;
3595 std::optional<bool> EmitReloc;
3600 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3602 DefaultOffloadArch = OffloadArch::HIPDefault;
3604 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3605 options::OPT_fno_hip_emit_relocatable)) {
3606 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3607 options::OPT_fno_hip_emit_relocatable,
false);
3611 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3612 <<
"-fhip-emit-relocatable"
3616 if (!CompileDeviceOnly) {
3617 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3618 <<
"-fhip-emit-relocatable"
3619 <<
"--cuda-device-only";
3624 if (Args.hasArg(options::OPT_gpu_bundle_output,
3625 options::OPT_no_gpu_bundle_output))
3626 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3627 options::OPT_no_gpu_bundle_output,
true) &&
3628 (!EmitReloc || !*EmitReloc);
3631 bool canUseBundlerUnbundler()
const override {
return true; }
3633 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3634 llvm::StringMap<bool> Features;
3638 (IdStr ==
"amdgcnspirv")
3639 ? llvm::Triple(
"spirv64-amd-amdhsa")
3643 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3644 C.setContainsError();
3648 return Args.MakeArgStringRef(CanId);
3651 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3653 const std::set<StringRef> &GpuArchs)
override {
3657 ActionBuilderReturnCode
3660 PhasesTy &Phases)
override {
3662 return ABRT_Inactive;
3668 if (CudaDeviceActions.empty())
3669 return ABRT_Success;
3672 CudaDeviceActions.size() == GpuArchList.size()) &&
3673 "Expecting one action per GPU architecture.");
3674 assert(!CompileHostOnly &&
3675 "Not expecting HIP actions in host-only compilation.");
3677 bool ShouldLink = !EmitReloc || !*EmitReloc;
3680 !EmitAsm && ShouldLink) {
3686 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3687 if (
C.getDriver().isUsingOffloadLTO()) {
3691 AL.push_back(CudaDeviceActions[I]);
3694 CudaDeviceActions[I] =
3701 if (ToolChains.front()->getTriple().isSPIRV()) {
3704 types::ID Output = Args.hasArg(options::OPT_S)
3706 : types::TY_LLVM_BC;
3712 AssociatedOffloadKind);
3713 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3715 AssociatedOffloadKind);
3716 AL.push_back(AssembleAction);
3719 CudaDeviceActions[I] =
3730 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3731 AssociatedOffloadKind);
3733 DDep, CudaDeviceActions[I]->getType());
3736 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3739 types::TY_HIP_FATBIN);
3741 if (!CompileDeviceOnly) {
3742 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3743 AssociatedOffloadKind);
3746 CudaFatBinary =
nullptr;
3751 CudaDeviceActions.clear();
3754 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3757 return ABRT_Success;
3763 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3764 auto LI = DeviceLinkerInputs.begin();
3765 for (
auto *A : CudaDeviceActions) {
3772 CudaDeviceActions.clear();
3773 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3777 for (
Action *&A : CudaDeviceActions)
3778 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3779 AssociatedOffloadKind);
3781 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3783 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3785 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3786 AssociatedOffloadKind);
3788 DDep, CudaDeviceActions[I]->getType());
3792 CudaDeviceActions.clear();
3795 return (CompileDeviceOnly &&
3796 (CurPhase == FinalPhase ||
3802 void appendLinkDeviceActions(
ActionList &AL)
override {
3803 if (DeviceLinkerInputs.size() == 0)
3806 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3807 "Linker inputs and GPU arch list sizes do not match.");
3813 for (
auto &LI : DeviceLinkerInputs) {
3815 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3819 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3823 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3824 GpuArchList[I], AssociatedOffloadKind);
3826 DeviceLinkDeps, DeviceLinkAction->getType()));
3829 DeviceLinkerInputs.clear();
3832 if (Args.hasArg(options::OPT_emit_llvm)) {
3841 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3844 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3845 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3846 AssociatedOffloadKind);
3849 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3855 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3871 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3879 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3882 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3890 unsigned ValidBuilders = 0u;
3891 unsigned ValidBuildersSupportingBundling = 0u;
3892 for (
auto *SB : SpecializedBuilders) {
3893 IsValid = IsValid && !SB->initialize();
3896 if (SB->isValid()) {
3898 if (SB->canUseBundlerUnbundler())
3899 ++ValidBuildersSupportingBundling;
3903 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3906 ~OffloadingActionBuilder() {
3907 for (
auto *SB : SpecializedBuilders)
3912 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3913 assert(HostAction &&
"Invalid host action");
3914 assert(InputArg &&
"Invalid input argument");
3915 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3916 assert(
Loc->second == InputArg &&
3917 "host action mapped to multiple input arguments");
3926 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3928 DeviceActionBuilder::PhasesTy &Phases) {
3932 if (SpecializedBuilders.empty())
3935 assert(HostAction &&
"Invalid host action!");
3936 recordHostAction(HostAction, InputArg);
3941 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3942 unsigned InactiveBuilders = 0u;
3943 unsigned IgnoringBuilders = 0u;
3944 for (
auto *SB : SpecializedBuilders) {
3945 if (!SB->isValid()) {
3950 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3955 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3960 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3961 OffloadKind |= SB->getAssociatedOffloadKind();
3966 if (IgnoringBuilders &&
3967 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3984 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3985 const Arg *InputArg) {
3989 recordHostAction(HostAction, InputArg);
3997 if (CanUseBundler && isa<InputAction>(HostAction) &&
3998 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4000 HostAction->
getType() == types::TY_PP_HIP)) {
4001 auto UnbundlingHostAction =
4006 HostAction = UnbundlingHostAction;
4007 recordHostAction(HostAction, InputArg);
4010 assert(HostAction &&
"Invalid host action!");
4013 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4014 for (
auto *SB : SpecializedBuilders) {
4018 auto RetCode = SB->addDeviceDependences(HostAction);
4022 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4023 "Host dependence not expected to be ignored.!");
4027 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4028 OffloadKind |= SB->getAssociatedOffloadKind();
4033 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4043 const Arg *InputArg) {
4045 recordHostAction(HostAction, InputArg);
4049 for (
auto *SB : SpecializedBuilders) {
4052 SB->appendTopLevelActions(OffloadAL);
4059 if (CanUseBundler && HostAction &&
4060 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4062 OffloadAL.push_back(HostAction);
4066 assert(HostAction == AL.back() &&
"Host action not in the list??");
4068 recordHostAction(HostAction, InputArg);
4069 AL.back() = HostAction;
4071 AL.append(OffloadAL.begin(), OffloadAL.end());
4081 void appendDeviceLinkActions(
ActionList &AL) {
4082 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4085 SB->appendLinkDeviceActions(AL);
4089 Action *makeHostLinkAction() {
4092 appendDeviceLinkActions(DeviceAL);
4093 if (DeviceAL.empty())
4098 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4101 HA = SB->appendLinkHostActions(DeviceAL);
4118 for (
auto *SB : SpecializedBuilders) {
4122 SB->appendLinkDependences(DDeps);
4126 unsigned ActiveOffloadKinds = 0u;
4127 for (
auto &I : InputArgToOffloadKindMap)
4128 ActiveOffloadKinds |= I.second;
4140 for (
auto *A : HostAction->
inputs()) {
4141 auto ArgLoc = HostActionToInputArgMap.find(A);
4142 if (ArgLoc == HostActionToInputArgMap.end())
4144 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4145 if (OFKLoc == InputArgToOffloadKindMap.end())
4157 nullptr, ActiveOffloadKinds);
4163void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4164 const InputList &Inputs,
4168 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4169 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4170 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4171 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4172 Args.eraseArg(options::OPT__SLASH_Yc);
4173 Args.eraseArg(options::OPT__SLASH_Yu);
4174 YcArg = YuArg =
nullptr;
4176 if (YcArg && Inputs.size() > 1) {
4177 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4178 Args.eraseArg(options::OPT__SLASH_Yc);
4186 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4187 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4188 Args.AddFlagArg(
nullptr,
4189 getOpts().getOption(options::OPT_frtlib_add_rpath));
4192 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4193 Diag(clang::diag::err_drv_emit_llvm_link);
4194 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4196 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4197 .starts_with_insensitive(
"lld"))
4198 Diag(clang::diag::err_drv_lto_without_lld);
4204 if (!Args.hasArg(options::OPT_dumpdir)) {
4205 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4206 Arg *Arg = Args.MakeSeparateArg(
4207 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4209 (FinalOutput ? FinalOutput->getValue()
4221 Args.eraseArg(options::OPT__SLASH_Fp);
4222 Args.eraseArg(options::OPT__SLASH_Yc);
4223 Args.eraseArg(options::OPT__SLASH_Yu);
4224 YcArg = YuArg =
nullptr;
4227 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4228 for (
auto &I : Inputs) {
4230 const Arg *InputArg = I.second;
4235 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4239 if (InitialPhase > FinalPhase) {
4240 if (InputArg->isClaimed())
4247 if (Args.hasArg(options::OPT_Qunused_arguments))
4253 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4254 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4258 (Args.getLastArg(options::OPT__SLASH_EP,
4259 options::OPT__SLASH_P) ||
4260 Args.getLastArg(options::OPT_E) ||
4261 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4263 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4264 << InputArg->getAsString(Args) << !!FinalPhaseArg
4265 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4267 Diag(clang::diag::warn_drv_input_file_unused)
4268 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4270 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4283 Actions.push_back(ClangClPch);
4295 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4296 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4302 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4304 if (!SuppressMissingInputWarning && Inputs.empty()) {
4305 Diag(clang::diag::err_drv_no_input_files);
4310 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4311 StringRef
V = A->getValue();
4312 if (Inputs.size() > 1 && !
V.empty() &&
4313 !llvm::sys::path::is_separator(
V.back())) {
4315 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4316 << A->getSpelling() <<
V;
4317 Args.eraseArg(options::OPT__SLASH_Fo);
4322 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4323 StringRef
V = A->getValue();
4324 if (Inputs.size() > 1 && !
V.empty() &&
4325 !llvm::sys::path::is_separator(
V.back())) {
4327 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4328 << A->getSpelling() <<
V;
4329 Args.eraseArg(options::OPT__SLASH_Fa);
4334 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4335 if (A->getValue()[0] ==
'\0') {
4337 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4338 Args.eraseArg(options::OPT__SLASH_o);
4342 handleArguments(
C, Args, Inputs, Actions);
4344 bool UseNewOffloadingDriver =
4347 Args.hasFlag(options::OPT_foffload_via_llvm,
4348 options::OPT_fno_offload_via_llvm,
false) ||
4349 Args.hasFlag(options::OPT_offload_new_driver,
4350 options::OPT_no_offload_new_driver,
4354 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4355 !UseNewOffloadingDriver
4356 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4364 for (
auto &I : Inputs) {
4366 const Arg *InputArg = I.second;
4379 CUID = CUIDOpts.
getCUID(InputArg->getValue(), Args);
4380 cast<InputAction>(Current)->setId(CUID);
4385 if (!UseNewOffloadingDriver)
4386 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4392 if (!UseNewOffloadingDriver)
4393 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4394 Current, InputArg, Phase, PL.back(), FullPL);
4400 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4403 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4404 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4406 LinkerInputs.push_back(Current);
4416 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4417 MergerInputs.push_back(Current);
4435 if (NewCurrent == Current)
4438 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4441 Current = NewCurrent;
4445 if (UseNewOffloadingDriver)
4449 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4453 if (Current->getType() == types::TY_Nothing)
4459 Actions.push_back(Current);
4462 if (!UseNewOffloadingDriver)
4463 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4465 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4471 if (LinkerInputs.empty()) {
4474 if (!UseNewOffloadingDriver)
4475 OffloadBuilder->appendDeviceLinkActions(Actions);
4478 if (!LinkerInputs.empty()) {
4479 if (!UseNewOffloadingDriver)
4480 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4481 LinkerInputs.push_back(Wrapper);
4486 }
else if (UseNewOffloadingDriver ||
4487 Args.hasArg(options::OPT_offload_link)) {
4494 if (!UseNewOffloadingDriver)
4495 LA = OffloadBuilder->processHostLinkAction(LA);
4496 Actions.push_back(LA);
4500 if (!MergerInputs.empty())
4504 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4511 for (
auto &I : Inputs) {
4513 const Arg *InputArg = I.second;
4518 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4519 InputType == types::TY_Asm)
4524 for (
auto Phase : PhaseList) {
4528 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4533 if (InputType == types::TY_Object)
4540 assert(Phase == PhaseList.back() &&
4541 "merging must be final compilation step.");
4542 MergerInputs.push_back(Current);
4551 Actions.push_back(Current);
4555 if (!MergerInputs.empty())
4560 for (
auto Opt : {options::OPT_print_supported_cpus,
4561 options::OPT_print_supported_extensions,
4562 options::OPT_print_enabled_extensions}) {
4569 if (Arg *A = Args.getLastArg(Opt)) {
4570 if (Opt == options::OPT_print_supported_extensions &&
4571 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4572 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4573 !
C.getDefaultToolChain().getTriple().isARM()) {
4574 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4575 <<
"--print-supported-extensions";
4578 if (Opt == options::OPT_print_enabled_extensions &&
4579 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4580 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4581 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4582 <<
"--print-enabled-extensions";
4589 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4592 for (
auto &I : Inputs)
4598 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4602 if (TC.requiresValidation(Args)) {
4603 Action *LastAction = Actions.back();
4605 LastAction, types::TY_DX_CONTAINER));
4610 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4616 const llvm::opt::DerivedArgList &Args,
4618 const llvm::Triple &Triple,
4619 bool SuppressError =
false) {
4624 if (!SuppressError && Triple.isNVPTX() &&
4626 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4627 <<
"CUDA" << ArchStr;
4629 }
else if (!SuppressError && Triple.isAMDGPU() &&
4631 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4632 <<
"HIP" << ArchStr;
4640 llvm::StringMap<bool> Features;
4646 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4647 C.setContainsError();
4659static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4661 llvm::Triple Triple) {
4662 if (!Triple.isAMDGPU())
4663 return std::nullopt;
4665 std::set<StringRef> ArchSet;
4666 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4670llvm::DenseSet<StringRef>
4673 bool SuppressError)
const {
4675 TC = &
C.getDefaultToolChain();
4678 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4679 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4680 options::OPT_no_offload_arch_EQ)) {
4681 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4683 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4685 :
"--no-offload-arch");
4688 if (KnownArchs.contains(TC))
4689 return KnownArchs.lookup(TC);
4691 llvm::DenseSet<StringRef> Archs;
4692 for (
auto *Arg : Args) {
4694 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4695 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4698 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4699 unsigned Prev = Index;
4700 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4701 if (!ExtractedArg || Index > Prev + 1) {
4702 TC->
getDriver().
Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
4703 << Arg->getAsString(Args);
4706 Arg = ExtractedArg.get();
4711 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4712 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4713 if (Arch ==
"native" || Arch.empty()) {
4717 llvm::consumeError(GPUsOrErr.takeError());
4720 << llvm::Triple::getArchTypeName(TC->
getArch())
4721 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4725 for (
auto ArchStr : *GPUsOrErr) {
4732 C, Args, Arch, TC->
getTriple(), SuppressError);
4733 if (ArchStr.empty())
4735 Archs.insert(ArchStr);
4738 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4739 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4740 if (Arch ==
"all") {
4744 C, Args, Arch, TC->
getTriple(), SuppressError);
4745 if (ArchStr.empty())
4747 Archs.erase(ArchStr);
4753 if (
auto ConflictingArchs =
4755 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4756 << ConflictingArchs->first << ConflictingArchs->second;
4757 C.setContainsError();
4764 if (Archs.empty()) {
4770 Archs.insert(StringRef());
4772 Archs.insert(StringRef());
4774 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4775 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4782 llvm::opt::DerivedArgList &Args,
4783 const InputTy &Input, StringRef CUID,
4784 Action *HostAction)
const {
4789 !(isa<CompileJobAction>(HostAction) ||
4803 auto TCRange =
C.getOffloadToolChains(Kind);
4804 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4805 ToolChains.push_back(TI->second);
4807 if (ToolChains.empty())
4811 const Arg *InputArg = Input.second;
4820 for (
const ToolChain *TC : ToolChains) {
4824 for (StringRef Arch : Sorted) {
4825 TCAndArchs.push_back(std::make_pair(TC, Arch));
4826 DeviceActions.push_back(
4827 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4831 if (DeviceActions.empty())
4837 HostAction->
getType() != types::TY_Nothing &&
4847 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4856 auto TCAndArch = TCAndArchs.begin();
4857 for (
Action *&A : DeviceActions) {
4858 if (A->
getType() == types::TY_Nothing)
4866 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4868 HostAction->
getType() != types::TY_Nothing) {
4875 TCAndArch->second.data(), Kind);
4877 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4886 for (
Action *&A : DeviceActions) {
4887 if ((A->
getType() != types::TY_Object &&
4888 A->
getType() != types::TY_LTO_BC) ||
4890 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4896 auto TCAndArch = TCAndArchs.begin();
4897 for (
Action *A : DeviceActions) {
4898 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4900 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4905 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4907 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4915 bool ShouldBundleHIP =
4917 Args.hasFlag(options::OPT_gpu_bundle_output,
4918 options::OPT_no_gpu_bundle_output,
true) &&
4919 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4920 !llvm::any_of(OffloadActions,
4927 if (OffloadActions.empty())
4932 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4936 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4940 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4945 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4954 nullptr,
C.getActiveOffloadKinds());
4963 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4964 return A->
getType() == types::TY_Nothing;
4965 }) && isa<CompileJobAction>(HostAction);
4968 nullptr, SingleDeviceOutput ? DDep : DDeps);
4969 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4975 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4985 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
4991 llvm_unreachable(
"link action invalid here.");
4993 llvm_unreachable(
"ifsmerge action invalid here.");
4998 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4999 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5000 OutputTy = types::TY_Dependencies;
5005 if (!Args.hasFlag(options::OPT_frewrite_includes,
5006 options::OPT_fno_rewrite_includes,
false) &&
5007 !Args.hasFlag(options::OPT_frewrite_imports,
5008 options::OPT_fno_rewrite_imports,
false) &&
5009 !Args.hasFlag(options::OPT_fdirectives_only,
5010 options::OPT_fno_directives_only,
false) &&
5014 "Cannot preprocess this input type!");
5020 if (Args.hasArg(options::OPT_extract_api))
5027 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
5028 !Args.getLastArg(options::OPT__precompile))
5033 "Cannot precompile this input type!");
5037 const char *ModName =
nullptr;
5038 if (OutputTy == types::TY_PCH) {
5039 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5040 ModName = A->getValue();
5042 OutputTy = types::TY_ModuleFile;
5045 if (Args.hasArg(options::OPT_fsyntax_only)) {
5047 OutputTy = types::TY_Nothing;
5053 if (Args.hasArg(options::OPT_fsyntax_only))
5055 if (Args.hasArg(options::OPT_rewrite_objc))
5057 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5059 types::TY_RewrittenLegacyObjC);
5060 if (Args.hasArg(options::OPT__analyze))
5062 if (Args.hasArg(options::OPT__migrate))
5064 if (Args.hasArg(options::OPT_emit_ast))
5066 if (Args.hasArg(options::OPT_emit_cir))
5068 if (Args.hasArg(options::OPT_module_file_info))
5070 if (Args.hasArg(options::OPT_verify_pch))
5072 if (Args.hasArg(options::OPT_extract_api))
5079 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5080 !Args.hasArg(options::OPT_emit_llvm))
5081 Output = types::TY_PP_Asm;
5082 else if (Args.hasArg(options::OPT_S))
5083 Output = types::TY_LTO_IR;
5085 Output = types::TY_LTO_BC;
5090 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5093 if (Args.hasArg(options::OPT_emit_llvm) ||
5098 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5102 Args.hasArg(options::OPT_S) &&
5106 !Args.hasFlag(options::OPT_offload_new_driver,
5107 options::OPT_no_offload_new_driver,
5110 : types::TY_LLVM_BC;
5119 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5123 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5125 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5145 unsigned NumOutputs = 0;
5146 unsigned NumIfsOutputs = 0;
5147 for (
const Action *A :
C.getActions()) {
5148 if (A->
getType() != types::TY_Nothing &&
5149 A->
getType() != types::TY_DX_CONTAINER &&
5151 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5153 0 == NumIfsOutputs++) ||
5158 A->
getType() == types::TY_Nothing &&
5159 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5160 NumOutputs += A->
size();
5163 if (NumOutputs > 1) {
5164 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5165 FinalOutput =
nullptr;
5169 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5172 llvm::StringSet<> ArchNames;
5173 if (RawTriple.isOSBinFormatMachO())
5174 for (
const Arg *A :
C.getArgs())
5175 if (A->getOption().matches(options::OPT_arch))
5176 ArchNames.insert(A->getValue());
5179 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5180 for (
Action *A :
C.getActions()) {
5187 const char *LinkingOutput =
nullptr;
5188 if (isa<LipoJobAction>(A)) {
5190 LinkingOutput = FinalOutput->getValue();
5198 ArchNames.size() > 1,
5199 LinkingOutput, CachedResults,
5206 for (
auto &J :
C.getJobs())
5207 J.InProcess =
false;
5210 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
5211 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5212 Cmd.getProcessStatistics();
5216 const char *LinkingOutput =
nullptr;
5218 LinkingOutput = FinalOutput->getValue();
5219 else if (!
Cmd.getOutputFilenames().empty())
5220 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
5225 using namespace llvm;
5227 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
5228 <<
"output=" << LinkingOutput;
5229 outs() <<
", total="
5230 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5232 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5233 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5237 llvm::raw_string_ostream Out(Buffer);
5238 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
5241 llvm::sys::printArg(Out, LinkingOutput, true);
5242 Out <<
',' << ProcStat->TotalTime.count() <<
','
5243 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5247 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5248 llvm::sys::fs::OF_Append |
5249 llvm::sys::fs::OF_Text);
5254 llvm::errs() <<
"ERROR: Cannot lock file "
5255 << CCPrintStatReportFilename <<
": "
5256 << toString(L.takeError()) <<
"\n";
5267 if (Diags.hasErrorOccurred() ||
5268 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5272 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5274 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5277 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5278 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5280 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5284 return strstr(J.getCreator().getShortName(),
"assembler");
5286 for (Arg *A :
C.getArgs()) {
5290 if (!A->isClaimed()) {
5296 const Option &Opt = A->getOption();
5297 if (Opt.getKind() == Option::FlagClass) {
5298 bool DuplicateClaimed =
false;
5300 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5301 if (AA->isClaimed()) {
5302 DuplicateClaimed =
true;
5307 if (DuplicateClaimed)
5313 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5315 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5320 !
C.getActions().empty()) {
5321 Diag(diag::err_drv_unsupported_opt_for_target)
5322 << A->getSpelling() << getTargetTriple();
5324 Diag(clang::diag::warn_drv_unused_argument)
5325 << A->getAsString(
C.getArgs());
5335class ToolSelector final {
5346 bool IsHostSelector;
5357 bool CanBeCollapsed =
true) {
5359 if (Inputs.size() != 1)
5362 Action *CurAction = *Inputs.begin();
5363 if (CanBeCollapsed &&
5369 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5373 if (!IsHostSelector) {
5374 if (OA->hasSingleDeviceDependence(
true)) {
5376 OA->getSingleDeviceDependence(
true);
5377 if (CanBeCollapsed &&
5380 SavedOffloadAction.push_back(OA);
5381 return dyn_cast<JobAction>(CurAction);
5383 }
else if (OA->hasHostDependence()) {
5384 CurAction = OA->getHostDependence();
5385 if (CanBeCollapsed &&
5388 SavedOffloadAction.push_back(OA);
5389 return dyn_cast<JobAction>(CurAction);
5394 return dyn_cast<JobAction>(CurAction);
5398 bool canCollapseAssembleAction()
const {
5399 return TC.useIntegratedAs() && !SaveTemps &&
5400 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5401 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5402 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5403 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5407 bool canCollapsePreprocessorAction()
const {
5408 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5409 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5410 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5415 struct JobActionInfo final {
5425 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5427 unsigned ElementNum) {
5428 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5429 for (
unsigned I = 0; I < ElementNum; ++I)
5430 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5431 ActionInfo[I].SavedOffloadAction.end());
5447 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5449 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5450 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5451 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5452 if (!AJ || !BJ || !CJ)
5456 const Tool *
T = TC.SelectTool(*CJ);
5463 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5469 const Tool *BT = TC.SelectTool(*BJ);
5474 if (!
T->hasIntegratedAssembler())
5477 Inputs = CJ->getInputs();
5478 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5485 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5487 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5488 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5493 const Tool *
T = TC.SelectTool(*BJ);
5497 if (!
T->hasIntegratedAssembler())
5500 Inputs = BJ->getInputs();
5501 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5508 if (ActionInfo.size() < 2)
5510 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5511 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5520 bool InputIsBitcode =
true;
5521 for (
size_t i = 1; i < ActionInfo.size(); i++)
5522 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5523 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5524 InputIsBitcode =
false;
5527 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5531 const Tool *
T = TC.SelectTool(*CJ);
5538 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5541 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5544 Inputs = CJ->getInputs();
5545 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5556 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5562 for (
Action *A : Inputs) {
5563 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5564 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5565 NewInputs.push_back(A);
5571 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5572 PreprocessJobOffloadActions.end());
5573 NewInputs.append(PJ->input_begin(), PJ->input_end());
5581 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5583 assert(BaseAction &&
"Invalid base action.");
5600 ActionChain.back().JA = BaseAction;
5601 while (ActionChain.back().JA) {
5602 const Action *CurAction = ActionChain.back().JA;
5605 ActionChain.resize(ActionChain.size() + 1);
5606 JobActionInfo &AI = ActionChain.back();
5610 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5614 ActionChain.pop_back();
5622 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5623 CollapsedOffloadAction);
5625 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5627 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5633 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5645 StringRef BoundArch,
5647 std::string TriplePlusArch = TC->
getTriple().normalize();
5648 if (!BoundArch.empty()) {
5649 TriplePlusArch +=
"-";
5650 TriplePlusArch += BoundArch;
5652 TriplePlusArch +=
"-";
5654 return TriplePlusArch;
5659 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5660 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5663 std::pair<const Action *, std::string> ActionTC = {
5665 auto CachedResult = CachedResults.find(ActionTC);
5666 if (CachedResult != CachedResults.end()) {
5667 return CachedResult->second;
5670 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5671 CachedResults, TargetDeviceOffloadKind);
5672 CachedResults[ActionTC] =
Result;
5677 const JobAction *JA,
const char *BaseInput,
5680 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5684 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5685 Path = A->getValue();
5686 if (llvm::sys::fs::is_directory(
Path)) {
5688 llvm::sys::path::replace_extension(Tmp,
"json");
5689 llvm::sys::path::append(
Path, llvm::sys::path::filename(Tmp));
5692 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5695 Path = DumpDir->getValue();
5696 Path += llvm::sys::path::filename(BaseInput);
5700 llvm::sys::path::replace_extension(
Path,
"json");
5702 const char *ResultFile =
C.getArgs().MakeArgString(
Path);
5703 C.addTimeTraceFile(ResultFile, JA);
5704 C.addResultFile(ResultFile, JA);
5709 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5710 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5713 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5716 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5749 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5751 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5752 const char *DepBoundArch) {
5755 LinkingOutput, CachedResults,
5765 OA->doOnEachDependence(
5766 BuildingForOffloadDevice,
5769 C, DepA, DepTC, DepBoundArch,
false,
5770 !!DepBoundArch, LinkingOutput, CachedResults,
5774 A = BuildingForOffloadDevice
5775 ? OA->getSingleDeviceDependence(
true)
5776 : OA->getHostDependence();
5780 std::pair<const Action *, std::string> ActionTC = {
5781 OA->getHostDependence(),
5783 auto It = CachedResults.find(ActionTC);
5784 if (It != CachedResults.end()) {
5786 Inputs.append(OffloadDependencesInputInfo);
5791 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5794 const Arg &Input = IA->getInputArg();
5796 if (Input.getOption().matches(options::OPT_INPUT)) {
5797 const char *
Name = Input.getValue();
5807 if (!ArchName.empty())
5808 TC = &getToolChain(
C.getArgs(),
5810 C.getArgs(), ArchName));
5812 TC = &
C.getDefaultToolChain();
5815 MultipleArchs, LinkingOutput, CachedResults,
5816 TargetDeviceOffloadKind);
5822 const JobAction *JA = cast<JobAction>(A);
5827 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5834 for (
const auto *OA : CollapsedOffloadActions)
5835 cast<OffloadAction>(OA)->doOnEachDependence(
5836 BuildingForOffloadDevice,
5839 C, DepA, DepTC, DepBoundArch,
false,
5840 !!DepBoundArch, LinkingOutput, CachedResults,
5846 for (
const Action *Input : Inputs) {
5850 bool SubJobAtTopLevel =
5851 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5853 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5858 const char *BaseInput = InputInfos[0].getBaseInput();
5859 for (
auto &Info : InputInfos) {
5860 if (Info.isFilename()) {
5861 BaseInput = Info.getBaseInput();
5868 if (JA->
getType() == types::TY_dSYM)
5869 BaseInput = InputInfos[0].getFilename();
5872 if (!OffloadDependencesInputInfo.empty())
5873 InputInfos.append(OffloadDependencesInputInfo.begin(),
5874 OffloadDependencesInputInfo.end());
5877 llvm::Triple EffectiveTriple;
5879 const ArgList &Args =
5881 if (InputInfos.size() != 1) {
5885 EffectiveTriple = llvm::Triple(
5893 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5897 for (
auto &UI : UA->getDependentActionsInfo()) {
5899 "Unbundling with no offloading??");
5906 UI.DependentOffloadKind,
5907 UI.DependentToolChain->getTriple().normalize(),
5918 UnbundlingResults.push_back(CurI);
5927 Arch = UI.DependentBoundArch;
5932 UI.DependentOffloadKind)}] = {
5938 std::pair<const Action *, std::string> ActionTC = {
5940 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5941 "Result does not exist??");
5942 Result = CachedResults[ActionTC].front();
5943 }
else if (JA->
getType() == types::TY_Nothing)
5950 isa<OffloadPackagerJobAction>(A) ||
5954 AtTopLevel, MultipleArchs,
5957 if (
T->canEmitIR() && OffloadingPrefix.empty())
5962 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5963 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5964 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5965 llvm::errs() << InputInfos[i].getAsString();
5967 llvm::errs() <<
", ";
5969 if (UnbundlingResults.empty())
5970 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5972 llvm::errs() <<
"], outputs: [";
5973 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5974 llvm::errs() << UnbundlingResults[i].getAsString();
5976 llvm::errs() <<
", ";
5978 llvm::errs() <<
"] \n";
5981 if (UnbundlingResults.empty())
5982 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
5984 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
5985 Args, LinkingOutput);
5991 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5992 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6004 if (ArgValue.empty()) {
6007 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
6009 llvm::sys::path::append(
Filename, BaseName);
6012 if (!llvm::sys::path::has_extension(ArgValue)) {
6017 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6022 llvm::sys::path::replace_extension(
Filename, Extension);
6025 return Args.MakeArgString(
Filename.c_str());
6029 if (isa<PreprocessJobAction>(JA))
6031 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
6033 if (isa<OffloadBundlingJobAction>(JA) &&
6040 StringRef Suffix,
bool MultipleArchs,
6041 StringRef BoundArch,
6042 bool NeedUniqueDirectory)
const {
6044 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6045 std::optional<std::string> CrashDirectory =
6047 ? std::string(A->getValue())
6048 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6049 if (CrashDirectory) {
6050 if (!
getVFS().exists(*CrashDirectory))
6051 llvm::sys::fs::create_directories(*CrashDirectory);
6053 llvm::sys::path::append(
Path, Prefix);
6054 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6055 if (std::error_code EC =
6056 llvm::sys::fs::createUniqueFile(
Path + Middle + Suffix, TmpName)) {
6057 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6061 if (MultipleArchs && !BoundArch.empty()) {
6062 if (NeedUniqueDirectory) {
6064 llvm::sys::path::append(TmpName,
6065 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6075 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6090 const char *BaseInput) {
6091 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
6092 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6093 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6098 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6102 const char *BaseInput,
6103 StringRef OrigBoundArch,
bool AtTopLevel,
6105 StringRef OffloadingPrefix)
const {
6106 std::string BoundArch = OrigBoundArch.str();
6107 if (is_style_windows(llvm::sys::path::Style::native)) {
6110 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
6113 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6115 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
6116 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6117 return C.addResultFile(FinalOutput->getValue(), &JA);
6121 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6122 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
6123 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6125 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6126 NameArg = A->getValue();
6127 return C.addResultFile(
6137 if (JA.
getType() == types::TY_ModuleFile &&
6138 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6142 if (JA.
getType() == types::TY_PP_Asm &&
6143 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6144 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6147 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6150 if (JA.
getType() == types::TY_Object &&
6151 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
6152 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6155 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6159 if (JA.
getType() == types::TY_PP_Asm &&
6160 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6161 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6163 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6164 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6165 return C.addResultFile(
6170 if (JA.
getType() == types::TY_API_INFO &&
6171 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6172 C.getArgs().hasArg(options::OPT_o))
6173 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6174 <<
C.getArgs().getLastArgValue(options::OPT_o);
6181 bool SpecifiedModuleOutput =
6182 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6183 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6184 if (MultipleArchs && SpecifiedModuleOutput)
6185 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6189 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
6190 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6191 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
6197 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6199 StringRef
Name = llvm::sys::path::filename(BaseInput);
6200 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6201 const char *Suffix =
6206 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6207 bool NeedUniqueDirectory =
6210 Triple.isOSDarwin();
6211 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6212 NeedUniqueDirectory);
6220 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
6221 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6226 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6227 llvm::sys::path::filename(BasePath));
6228 BaseName = ExternalPath;
6229 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
6230 BaseName = BasePath;
6232 BaseName = llvm::sys::path::filename(BasePath);
6235 const char *NamedOutput;
6237 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6238 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6242 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6246 }
else if (JA.
getType() == types::TY_Image &&
6247 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6248 options::OPT__SLASH_o)) {
6252 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6256 }
else if (JA.
getType() == types::TY_Image) {
6266 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6267 options::OPT_fno_gpu_rdc,
false);
6268 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6269 if (UseOutExtension) {
6271 llvm::sys::path::replace_extension(Output,
"");
6273 Output += OffloadingPrefix;
6274 if (MultipleArchs && !BoundArch.empty()) {
6276 Output.append(BoundArch);
6278 if (UseOutExtension)
6280 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6283 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6284 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6285 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6288 .getLastArg(options::OPT__SLASH_o)
6293 const char *Suffix =
6295 assert(Suffix &&
"All types used for output should have a suffix.");
6297 std::string::size_type End = std::string::npos;
6299 End = BaseName.rfind(
'.');
6301 Suffixed += OffloadingPrefix;
6302 if (MultipleArchs && !BoundArch.empty()) {
6304 Suffixed.append(BoundArch);
6309 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6310 const llvm::opt::DerivedArgList &Args) {
6315 return isa<CompileJobAction>(JA) &&
6317 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6322 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6323 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6324 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6328 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6332 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6333 JA.
getType() != types::TY_PCH) {
6334 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6336 llvm::sys::path::remove_filename(TempPath);
6337 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6338 llvm::sys::path::append(TempPath, OutputFileName);
6339 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6345 bool SameFile =
false;
6347 llvm::sys::fs::current_path(
Result);
6348 llvm::sys::path::append(
Result, BaseName);
6349 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6352 StringRef
Name = llvm::sys::path::filename(BaseInput);
6353 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6357 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6363 llvm::sys::path::remove_filename(BasePath);
6364 if (BasePath.empty())
6365 BasePath = NamedOutput;
6367 llvm::sys::path::append(BasePath, NamedOutput);
6368 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6371 return C.addResultFile(NamedOutput, &JA);
6377 -> std::optional<std::string> {
6380 for (
const auto &
Dir :
P) {
6384 llvm::sys::path::append(
P,
Name);
6385 if (llvm::sys::fs::exists(Twine(
P)))
6386 return std::string(
P);
6388 return std::nullopt;
6395 llvm::sys::path::append(R,
Name);
6396 if (llvm::sys::fs::exists(Twine(R)))
6397 return std::string(R);
6400 llvm::sys::path::append(
P,
Name);
6401 if (llvm::sys::fs::exists(Twine(
P)))
6402 return std::string(
P);
6405 llvm::sys::path::append(
D,
"..",
Name);
6406 if (llvm::sys::fs::exists(Twine(
D)))
6407 return std::string(
D);
6416 llvm::sys::path::append(R2,
"..",
"..",
Name);
6417 if (llvm::sys::fs::exists(Twine(R2)))
6418 return std::string(R2);
6420 return std::string(
Name);
6423void Driver::generatePrefixedToolNames(
6427 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6428 Names.emplace_back(
Tool);
6432 llvm::sys::path::append(Dir, Name);
6433 if (llvm::sys::fs::can_execute(Twine(Dir)))
6435 llvm::sys::path::remove_filename(Dir);
6441 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6446 if (llvm::sys::fs::is_directory(PrefixDir)) {
6449 return std::string(
P);
6452 if (llvm::sys::fs::can_execute(Twine(
P)))
6453 return std::string(
P);
6458 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6466 for (
const auto &
Path : List) {
6469 return std::string(
P);
6473 if (llvm::ErrorOr<std::string>
P =
6474 llvm::sys::findProgramByName(TargetSpecificExecutable))
6478 return std::string(
Name);
6483 std::string error =
"<NOT PRESENT>";
6487 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6504 llvm::sys::path::remove_filename(path);
6505 llvm::sys::path::append(path,
"libc++.modules.json");
6506 if (TC.
getVFS().exists(path))
6507 return static_cast<std::string
>(path);
6512 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6515 return evaluate(
"libc++.a").value_or(error);
6519 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6523 llvm::sys::path::remove_filename(path);
6524 llvm::sys::path::append(path,
"libstdc++.modules.json");
6525 if (TC.
getVFS().exists(path))
6526 return static_cast<std::string
>(path);
6531 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6534 return evaluate(
"libstdc++.a").value_or(error);
6543 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix,
Path);
6545 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6549 return std::string(
Path);
6554 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix,
Path);
6556 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6560 return std::string(
Path);
6565 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6569 Output = FpArg->getValue();
6573 if (!llvm::sys::path::has_extension(Output))
6576 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6577 Output = YcArg->getValue();
6580 llvm::sys::path::replace_extension(Output,
".pch");
6582 return std::string(Output);
6585const ToolChain &Driver::getToolChain(
const ArgList &Args,
6586 const llvm::Triple &
Target)
const {
6588 auto &TC = ToolChains[
Target.str()];
6590 switch (
Target.getOS()) {
6591 case llvm::Triple::AIX:
6592 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6594 case llvm::Triple::Haiku:
6595 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6597 case llvm::Triple::Darwin:
6598 case llvm::Triple::MacOSX:
6599 case llvm::Triple::IOS:
6600 case llvm::Triple::TvOS:
6601 case llvm::Triple::WatchOS:
6602 case llvm::Triple::XROS:
6603 case llvm::Triple::DriverKit:
6604 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6606 case llvm::Triple::DragonFly:
6607 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6609 case llvm::Triple::OpenBSD:
6610 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6612 case llvm::Triple::NetBSD:
6613 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6615 case llvm::Triple::FreeBSD:
6617 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6620 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6622 case llvm::Triple::Linux:
6623 case llvm::Triple::ELFIAMCU:
6624 if (
Target.getArch() == llvm::Triple::hexagon)
6625 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6627 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6628 !
Target.hasEnvironment())
6629 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6632 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6634 else if (
Target.getArch() == llvm::Triple::ve)
6635 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6636 else if (
Target.isOHOSFamily())
6637 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6639 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6641 case llvm::Triple::NaCl:
6642 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6644 case llvm::Triple::Fuchsia:
6645 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6647 case llvm::Triple::Solaris:
6648 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6650 case llvm::Triple::CUDA:
6651 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6653 case llvm::Triple::AMDHSA:
6654 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6656 case llvm::Triple::AMDPAL:
6657 case llvm::Triple::Mesa3D:
6658 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6660 case llvm::Triple::UEFI:
6661 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6663 case llvm::Triple::Win32:
6664 switch (
Target.getEnvironment()) {
6666 if (
Target.isOSBinFormatELF())
6667 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6668 else if (
Target.isOSBinFormatMachO())
6669 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6671 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6673 case llvm::Triple::GNU:
6674 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6676 case llvm::Triple::Itanium:
6677 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6680 case llvm::Triple::MSVC:
6681 case llvm::Triple::UnknownEnvironment:
6682 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6683 .starts_with_insensitive(
"bfd"))
6684 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6688 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6692 case llvm::Triple::PS4:
6693 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6695 case llvm::Triple::PS5:
6696 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6698 case llvm::Triple::Hurd:
6699 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6701 case llvm::Triple::LiteOS:
6702 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6704 case llvm::Triple::ZOS:
6705 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6707 case llvm::Triple::Vulkan:
6708 case llvm::Triple::ShaderModel:
6709 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6714 switch (
Target.getArch()) {
6715 case llvm::Triple::tce:
6716 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6718 case llvm::Triple::tcele:
6719 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6721 case llvm::Triple::hexagon:
6722 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6725 case llvm::Triple::lanai:
6726 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6728 case llvm::Triple::xcore:
6729 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6731 case llvm::Triple::wasm32:
6732 case llvm::Triple::wasm64:
6733 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6735 case llvm::Triple::avr:
6736 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6738 case llvm::Triple::msp430:
6740 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6742 case llvm::Triple::riscv32:
6743 case llvm::Triple::riscv64:
6746 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6748 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6750 case llvm::Triple::ve:
6751 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6753 case llvm::Triple::spirv32:
6754 case llvm::Triple::spirv64:
6755 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6757 case llvm::Triple::csky:
6758 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6762 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6763 else if (
Target.isOSBinFormatELF())
6764 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6765 else if (
Target.isAppleMachO())
6766 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6767 else if (
Target.isOSBinFormatMachO())
6768 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6770 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6778const ToolChain &Driver::getOffloadingDeviceToolChain(
6779 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6788 switch (TargetDeviceOffloadKind) {
6790 if (((
Target.getArch() == llvm::Triple::amdgcn ||
6791 Target.getArch() == llvm::Triple::spirv64) &&
6792 Target.getVendor() == llvm::Triple::AMD &&
6793 Target.getOS() == llvm::Triple::AMDHSA) ||
6794 !Args.hasArgNoClaim(options::OPT_offload_EQ))
6795 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6797 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6798 Target.getVendor() == llvm::Triple::UnknownVendor &&
6799 Target.getOS() == llvm::Triple::UnknownOS)
6800 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6805 if (
Target.isSPIROrSPIRV())
6806 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, HostTC,
6813 assert(TC &&
"Could not create offloading device tool chain.");
6819 if (JA.
size() != 1 ||
6824 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6825 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6826 !isa<ExtractAPIJobAction>(JA))
6834 if (JA.
size() != 1 ||
6839 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6840 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
6848 if (Args.hasArg(options::OPT_emit_static_lib))
6859 unsigned &Micro,
bool &HadExtra) {
6862 Major = Minor = Micro = 0;
6866 if (Str.consumeInteger(10, Major))
6870 if (!Str.consume_front(
"."))
6873 if (Str.consumeInteger(10, Minor))
6877 if (!Str.consume_front(
"."))
6880 if (Str.consumeInteger(10, Micro))
6898 unsigned CurDigit = 0;
6899 while (CurDigit < Digits.size()) {
6901 if (Str.consumeInteger(10, Digit))
6903 Digits[CurDigit] = Digit;
6906 if (!Str.consume_front(
"."))
6915llvm::opt::Visibility
6916Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6929const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6945 llvm_unreachable(
"Unhandled Mode");
6949 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6954 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6955 options::OPT_fno_save_optimization_record,
false))
6959 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6960 options::OPT_fno_save_optimization_record,
false))
6964 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6965 options::OPT_fno_save_optimization_record,
false))
6969 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6970 options::OPT_fno_save_optimization_record,
false))
6977 static StringRef OptName =
6979 llvm::StringRef Opt;
6980 for (StringRef Arg : Args) {
6981 if (!Arg.starts_with(OptName))
6987 return Opt.consume_front(OptName) ? Opt :
"";
6994 llvm::BumpPtrAllocator &Alloc,
6995 llvm::vfs::FileSystem *FS) {
7004 for (
const char *F : Args) {
7005 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7007 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7008 RSPQuoting = Windows;
7016 llvm::cl::TokenizerCallback Tokenizer;
7018 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7020 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7022 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7025 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7026 ECtx.setMarkEOLs(MarkEOLs);
7030 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7034 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7035 [](
const char *A) {
return A !=
nullptr; });
7036 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7039 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7040 Args.resize(newEnd - Args.begin());
7044 return llvm::Error::success();
7048 return SavedStrings.insert(S).first->getKeyData();
7081 llvm::StringSet<> &SavedStrings) {
7084 if (Edit[0] ==
'^') {
7085 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7086 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7087 Args.insert(Args.begin() + 1, Str);
7088 }
else if (Edit[0] ==
'+') {
7089 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7090 OS <<
"### Adding argument " << Str <<
" at end\n";
7091 Args.push_back(Str);
7092 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7093 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7094 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7095 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7096 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7098 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7100 if (Args[i] ==
nullptr)
7102 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7104 if (Repl != Args[i]) {
7105 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7109 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7110 auto Option = Edit.substr(1);
7111 for (
unsigned i = 1; i < Args.size();) {
7112 if (Option == Args[i]) {
7113 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7114 Args.erase(Args.begin() + i);
7115 if (Edit[0] ==
'X') {
7116 if (i < Args.size()) {
7117 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7118 Args.erase(Args.begin() + i);
7120 OS <<
"### Invalid X edit, end of command line!\n";
7125 }
else if (Edit[0] ==
'O') {
7126 for (
unsigned i = 1; i < Args.size();) {
7127 const char *A = Args[i];
7131 if (A[0] ==
'-' && A[1] ==
'O' &&
7132 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7133 (
'0' <= A[2] && A[2] <=
'9'))))) {
7134 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7135 Args.erase(Args.begin() + i);
7139 OS <<
"### Adding argument " << Edit <<
" at end\n";
7140 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7142 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7147 const char *OverrideStr,
7148 llvm::StringSet<> &SavedStrings,
7151 OS = &llvm::nulls();
7153 if (OverrideStr[0] ==
'#') {
7155 OS = &llvm::nulls();
7158 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
7162 const char *S = OverrideStr;
7164 const char *End = ::strchr(S,
' ');
7166 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.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError)
ParseArgStrings - Parse the given list of strings into an ArgList.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
const char * getPhaseName(ID Id)
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
bool isHIP(ID Id)
isHIP - Is this a HIP input.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
const llvm::opt::OptTable & getDriverOptTable()
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
static bool IsAMDOffloadArch(OffloadArch A)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
@ Result
The result type of a method or function.
static bool IsNVIDIAOffloadArch(OffloadArch A)
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
const FunctionProtoType * T
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
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.