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);
203 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
204 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
207 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
208 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
209 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
210 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
211 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
212 CheckInputsExist(
true), ProbePrecompiled(
true),
213 SuppressMissingInputWarning(
false) {
216 this->VFS = llvm::vfs::getRealFileSystem();
221 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
224 llvm::sys::path::append(
P,
SysRoot);
228#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
229 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
233 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
234 llvm::sys::path::remove_dots(configFileDir,
true);
238#if defined(CLANG_CONFIG_FILE_USER_DIR)
241 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
250void Driver::setDriverMode(StringRef
Value) {
251 static StringRef OptName =
252 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
253 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
254 .Case(
"gcc", GCCMode)
255 .Case(
"g++", GXXMode)
256 .Case(
"cpp", CPPMode)
258 .Case(
"flang", FlangMode)
259 .Case(
"dxc", DXCMode)
263 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
267 bool UseDriverMode,
bool &ContainsError) {
268 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
269 ContainsError =
false;
271 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
272 unsigned MissingArgIndex, MissingArgCount;
273 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
274 MissingArgCount, VisibilityMask);
277 if (MissingArgCount) {
278 Diag(diag::err_drv_missing_argument)
279 << Args.getArgString(MissingArgIndex) << MissingArgCount;
286 for (
const Arg *A : Args) {
288 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
296 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
297 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
299 diag::warn_drv_empty_joined_argument,
304 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
306 auto ArgString = A->getAsString(Args);
308 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
310 getOpts().findExact(ArgString, Nearest,
312 DiagID = diag::err_drv_unknown_argument_with_suggestion;
313 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
315 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
316 : diag::err_drv_unknown_argument;
317 Diags.
Report(DiagID) << ArgString;
321 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
322 : diag::err_drv_unknown_argument_with_suggestion;
323 Diags.
Report(DiagID) << ArgString << Nearest;
329 for (
const Arg *A : Args.filtered(options::OPT_o)) {
330 if (ArgStrings[A->getIndex()] == A->getSpelling())
334 std::string ArgString = ArgStrings[A->getIndex()];
336 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
337 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
338 << A->getAsString(Args) << Nearest;
348 Arg **FinalPhaseArg)
const {
349 Arg *PhaseArg =
nullptr;
353 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
354 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
355 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
356 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
363 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
366 options::OPT_fmodule_header_EQ))) {
369 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
370 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
371 (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
372 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
373 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
374 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
375 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
376 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
377 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
378 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
379 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
383 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
387 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
390 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
398 *FinalPhaseArg = PhaseArg;
404 StringRef
Value,
bool Claim =
true) {
405 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
406 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
407 Args.AddSynthesizedArg(A);
413DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
414 const llvm::opt::OptTable &Opts =
getOpts();
415 DerivedArgList *DAL =
new DerivedArgList(Args);
417 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
418 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
419 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
420 bool IgnoreUnused =
false;
421 for (Arg *A : Args) {
425 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
429 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
430 IgnoreUnused =
false;
440 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
441 A->getOption().matches(options::OPT_Xlinker)) &&
442 A->containsValue(
"--no-demangle")) {
444 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
447 for (StringRef Val : A->getValues())
448 if (Val !=
"--no-demangle")
449 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
457 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
458 A->getNumValues() > 0 &&
459 (A->getValue(0) == StringRef(
"-MD") ||
460 A->getValue(0) == StringRef(
"-MMD"))) {
462 if (A->getValue(0) == StringRef(
"-MD"))
463 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
465 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
466 if (A->getNumValues() == 2)
467 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
472 if (A->getOption().matches(options::OPT_l)) {
473 StringRef
Value = A->getValue();
476 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
478 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
483 if (
Value ==
"cc_kext") {
484 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
490 if (A->getOption().matches(options::OPT__DASH_DASH)) {
492 for (StringRef Val : A->getValues())
501 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
502 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
505 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
506 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
510#if defined(HOST_LINK_VERSION)
511 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
512 strlen(HOST_LINK_VERSION) > 0) {
513 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
515 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
527 StringRef TargetTriple,
529 StringRef DarwinArchName =
"") {
531 if (
const Arg *A = Args.getLastArg(options::OPT_target))
532 TargetTriple = A->getValue();
534 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
539 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
543 if (
Target.isOSBinFormatMachO()) {
545 if (!DarwinArchName.empty()) {
552 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
553 StringRef ArchName = A->getValue();
560 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
561 options::OPT_mbig_endian)) {
562 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
563 ?
Target.getLittleEndianArchVariant()
564 :
Target.getBigEndianArchVariant();
565 if (
T.getArch() != llvm::Triple::UnknownArch) {
567 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
572 if (
Target.getArch() == llvm::Triple::tce)
577 if (std::optional<std::string> ObjectModeValue =
578 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
579 StringRef ObjectMode = *ObjectModeValue;
580 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
582 if (ObjectMode ==
"64") {
583 AT =
Target.get64BitArchVariant().getArch();
584 }
else if (ObjectMode ==
"32") {
585 AT =
Target.get32BitArchVariant().getArch();
587 D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
590 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
596 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
598 D.Diag(diag::err_drv_unsupported_opt_for_target)
599 << A->getAsString(Args) <<
Target.str();
602 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
603 options::OPT_m32, options::OPT_m16,
604 options::OPT_maix32, options::OPT_maix64);
606 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
608 if (A->getOption().matches(options::OPT_m64) ||
609 A->getOption().matches(options::OPT_maix64)) {
610 AT =
Target.get64BitArchVariant().getArch();
611 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
612 Target.getEnvironment() == llvm::Triple::GNUT64)
613 Target.setEnvironment(llvm::Triple::GNU);
614 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
615 Target.setEnvironment(llvm::Triple::Musl);
616 }
else if (A->getOption().matches(options::OPT_mx32) &&
617 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
618 AT = llvm::Triple::x86_64;
619 if (
Target.getEnvironment() == llvm::Triple::Musl)
620 Target.setEnvironment(llvm::Triple::MuslX32);
622 Target.setEnvironment(llvm::Triple::GNUX32);
623 }
else if (A->getOption().matches(options::OPT_m32) ||
624 A->getOption().matches(options::OPT_maix32)) {
625 AT =
Target.get32BitArchVariant().getArch();
626 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
627 Target.setEnvironment(llvm::Triple::GNU);
628 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
629 Target.setEnvironment(llvm::Triple::Musl);
630 }
else if (A->getOption().matches(options::OPT_m16) &&
631 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
632 AT = llvm::Triple::x86;
633 Target.setEnvironment(llvm::Triple::CODE16);
636 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
638 if (
Target.isWindowsGNUEnvironment())
644 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
645 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
646 D.Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
649 if (A && !A->getOption().matches(options::OPT_m32))
650 D.Diag(diag::err_drv_argument_not_allowed_with)
651 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
653 Target.setArch(llvm::Triple::x86);
654 Target.setArchName(
"i586");
655 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
656 Target.setEnvironmentName(
"");
657 Target.setOS(llvm::Triple::ELFIAMCU);
658 Target.setVendor(llvm::Triple::UnknownVendor);
659 Target.setVendorName(
"intel");
665 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
666 StringRef ABIName = A->getValue();
667 if (ABIName ==
"32") {
669 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
670 Target.getEnvironment() == llvm::Triple::GNUABIN32)
671 Target.setEnvironment(llvm::Triple::GNU);
672 }
else if (ABIName ==
"n32") {
674 if (
Target.getEnvironment() == llvm::Triple::GNU ||
675 Target.getEnvironment() == llvm::Triple::GNUT64 ||
676 Target.getEnvironment() == llvm::Triple::GNUABI64)
677 Target.setEnvironment(llvm::Triple::GNUABIN32);
678 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
679 Target.getEnvironment() == llvm::Triple::MuslABI64)
680 Target.setEnvironment(llvm::Triple::MuslABIN32);
681 }
else if (ABIName ==
"64") {
683 if (
Target.getEnvironment() == llvm::Triple::GNU ||
684 Target.getEnvironment() == llvm::Triple::GNUT64 ||
685 Target.getEnvironment() == llvm::Triple::GNUABIN32)
686 Target.setEnvironment(llvm::Triple::GNUABI64);
687 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
688 Target.getEnvironment() == llvm::Triple::MuslABIN32)
689 Target.setEnvironment(llvm::Triple::MuslABI64);
697 if (Args.hasArg(options::OPT_march_EQ) ||
698 Args.hasArg(options::OPT_mcpu_EQ)) {
700 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
702 if (!llvm::errorToBool(ISAInfo.takeError())) {
703 unsigned XLen = (*ISAInfo)->getXLen();
705 Target.setArch(llvm::Triple::riscv32);
707 Target.setArch(llvm::Triple::riscv64);
719 OptSpecifier OptEq, OptSpecifier OptNeg) {
720 if (!Args.hasFlag(OptEq, OptNeg,
false))
723 const Arg *A = Args.getLastArg(OptEq);
724 StringRef LTOName = A->getValue();
732 D.Diag(diag::err_drv_unsupported_option_argument)
733 << A->getSpelling() << A->getValue();
740void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
742 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
744 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
745 options::OPT_fno_offload_lto);
748 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
749 options::OPT_fno_openmp_target_jit,
false)) {
750 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
751 options::OPT_fno_offload_lto))
753 Diag(diag::err_drv_incompatible_options)
754 << A->getSpelling() <<
"-fopenmp-target-jit";
761 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
763 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
765 RuntimeName = A->getValue();
767 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
775 Diag(diag::err_drv_unsupported_option_argument)
776 << A->getSpelling() << A->getValue();
779 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
788 if (llvm::is_contained(SYCLAlias, TargetArch)) {
789 llvm::Triple TargetTriple;
790 TargetTriple.setArchName(TargetArch);
791 TargetTriple.setVendor(llvm::Triple::UnknownVendor);
792 TargetTriple.setOS(llvm::Triple::UnknownOS);
795 return llvm::Triple(TargetArch);
801 for (
const auto &SYCLTriple : SYCLTriples) {
802 if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
803 SYCLTriple.isSPIROrSPIRV())
808 C.getDefaultToolChain().getTriple().isArch32Bit() ?
"spirv32"
810 SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple);
823 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
828 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
831 C.getInputArgs().hasArg(options::OPT_hip_link) ||
832 C.getInputArgs().hasArg(options::OPT_hipstdpar);
833 bool UseLLVMOffload =
C.getInputArgs().hasArg(
834 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
835 if (IsCuda && IsHIP) {
836 Diag(clang::diag::err_drv_mix_cuda_hip);
839 if (IsCuda && !UseLLVMOffload) {
841 const llvm::Triple &HostTriple = HostTC->
getTriple();
849 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
851 CudaTC = std::make_unique<toolchains::CudaToolChain>(
852 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
857 if (CudaInstallation.
isValid())
860 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
861 }
else if (IsHIP && !UseLLVMOffload) {
862 if (
auto *OMPTargetArg =
863 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
864 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
865 << OMPTargetArg->getSpelling() <<
"HIP";
873 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
875 C.addOffloadDeviceToolChain(HIPTC, OFK);
883 bool IsOpenMPOffloading =
884 ((IsCuda || IsHIP) && UseLLVMOffload) ||
885 (
C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
886 options::OPT_fno_openmp,
false) &&
887 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
888 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ)));
889 if (IsOpenMPOffloading) {
895 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
899 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
900 llvm::StringMap<StringRef> FoundNormalizedTriples;
901 std::multiset<StringRef> OpenMPTriples;
906 if (Arg *OpenMPTargets =
907 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
908 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
909 Diag(clang::diag::warn_drv_empty_joined_argument)
910 << OpenMPTargets->getAsString(
C.getInputArgs());
913 for (StringRef
T : OpenMPTargets->getValues())
914 OpenMPTriples.insert(
T);
915 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
916 ((!IsHIP && !IsCuda) || UseLLVMOffload)) {
926 llvm::DenseSet<StringRef> Archs;
928 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
929 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
935 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
936 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
941 if (!AMDTriple && !NVPTXTriple) {
942 for (StringRef Arch :
947 for (StringRef Arch : Archs) {
950 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
951 }
else if (AMDTriple &&
954 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
956 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
963 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
968 for (
const auto &TripleAndArchs : DerivedArchs)
969 OpenMPTriples.insert(TripleAndArchs.first());
972 for (StringRef Val : OpenMPTriples) {
974 std::string NormalizedName = TT.normalize();
977 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
978 if (Duplicate != FoundNormalizedTriples.end()) {
979 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
980 << Val << Duplicate->second;
986 FoundNormalizedTriples[NormalizedName] = Val;
989 if (TT.getArch() == llvm::Triple::UnknownArch)
990 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
995 if (TT.isNVPTX() || TT.isAMDGCN() || TT.isSPIRV()) {
998 assert(HostTC &&
"Host toolchain should be always defined.");
1000 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
1003 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
1004 *
this, TT, *HostTC,
C.getInputArgs());
1005 else if (TT.isAMDGCN())
1006 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
1007 *
this, TT, *HostTC,
C.getInputArgs());
1008 else if (TT.isSPIRV())
1009 DeviceTC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(
1010 *
this, TT, *HostTC,
C.getInputArgs());
1012 assert(DeviceTC &&
"Device toolchain not defined.");
1015 TC = DeviceTC.get();
1017 TC = &getToolChain(
C.getInputArgs(), TT);
1019 auto It = DerivedArchs.find(TT.getTriple());
1020 if (It != DerivedArchs.end())
1021 KnownArchs[TC] = It->second;
1024 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
1025 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1030 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1031 options::OPT_fno_sycl,
false);
1033 auto argSYCLIncompatible = [&](OptSpecifier OptId) {
1036 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(OptId))
1037 Diag(clang::diag::err_drv_argument_not_allowed_with)
1038 << IncompatArg->getSpelling() <<
"-fsycl";
1041 argSYCLIncompatible(options::OPT_static_libstdcxx);
1043 argSYCLIncompatible(options::OPT_ffreestanding);
1054 for (
const auto &TargetTriple : UniqueSYCLTriplesVec) {
1055 auto SYCLTC = &getOffloadingDeviceToolChain(
1070 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1071 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1072 Copy->getValues() = Opt->getValues();
1073 if (Opt->isClaimed())
1075 Copy->setOwnsValues(Opt->getOwnsValues());
1076 Opt->setOwnsValues(
false);
1078 if (Opt->getAlias()) {
1079 const Arg *Alias = Opt->getAlias();
1080 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1081 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1082 Args.getArgString(Index), Index);
1083 AliasCopy->getValues() = Alias->getValues();
1084 AliasCopy->setOwnsValues(
false);
1085 if (Alias->isClaimed())
1087 Copy->setAlias(std::move(AliasCopy));
1091bool Driver::readConfigFile(StringRef
FileName,
1092 llvm::cl::ExpansionContext &ExpCtx) {
1096 Diag(diag::err_drv_cannot_open_config_file)
1097 <<
FileName << Status.getError().message();
1100 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1101 Diag(diag::err_drv_cannot_open_config_file)
1102 <<
FileName <<
"not a regular file";
1108 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1109 Diag(diag::err_drv_cannot_read_config_file)
1116 for (
const char *Opt : NewCfgFileArgs) {
1118 if (Opt[0] ==
'$' && Opt[1])
1119 NewCfgTailArgs.push_back(Opt + 1);
1121 NewCfgHeadArgs.push_back(Opt);
1126 llvm::sys::path::native(CfgFileName);
1127 bool ContainErrors =
false;
1128 auto NewHeadOptions = std::make_unique<InputArgList>(
1132 auto NewTailOptions = std::make_unique<InputArgList>(
1139 for (Arg *A : *NewHeadOptions)
1141 for (Arg *A : *NewTailOptions)
1144 if (!CfgOptionsHead)
1145 CfgOptionsHead = std::move(NewHeadOptions);
1148 for (
auto *Opt : *NewHeadOptions)
1152 if (!CfgOptionsTail)
1153 CfgOptionsTail = std::move(NewTailOptions);
1156 for (
auto *Opt : *NewTailOptions)
1160 ConfigFiles.push_back(std::string(CfgFileName));
1164bool Driver::loadConfigFiles() {
1165 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1166 llvm::cl::tokenizeConfigFile);
1167 ExpCtx.setVFS(&
getVFS());
1171 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1174 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1175 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1180 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1182 llvm::sys::fs::expand_tilde(
1183 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1184 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1193 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1196 if (loadDefaultConfigFiles(ExpCtx))
1202 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1205 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1206 CfgFilePath.assign(CfgFileName);
1207 if (llvm::sys::path::is_relative(CfgFilePath)) {
1208 if (
getVFS().makeAbsolute(CfgFilePath)) {
1209 Diag(diag::err_drv_cannot_open_config_file)
1210 << CfgFilePath <<
"cannot get absolute path";
1214 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1216 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1217 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1218 if (!SearchDir.empty())
1219 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1224 if (readConfigFile(CfgFilePath, ExpCtx))
1235 llvm::Triple Triple, std::string Suffix) {
1237 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1241 VersionTuple OSVersion = Triple.getOSVersion();
1242 if (!OSVersion.getMinor().has_value())
1245 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1249 if (OSVersion.getMajor() != 0) {
1250 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1251 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1257 Triple.setOSName(BaseOSName);
1258 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1261bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1264 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1268 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1271 std::string RealMode = getExecutableForDriverMode(Mode);
1272 llvm::Triple Triple;
1281 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1282 PrefixTriple.isOSUnknown())
1283 Triple = PrefixTriple;
1287 if (Triple.str().empty()) {
1289 assert(!Triple.str().empty());
1305 "-" + RealMode +
".cfg"))
1306 return readConfigFile(CfgFilePath, ExpCtx);
1310 if (TryModeSuffix) {
1313 return readConfigFile(CfgFilePath, ExpCtx);
1318 std::string CfgFileName = RealMode +
".cfg";
1319 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1320 if (readConfigFile(CfgFilePath, ExpCtx))
1322 }
else if (TryModeSuffix) {
1324 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1325 readConfigFile(CfgFilePath, ExpCtx))
1331 return readConfigFile(CfgFilePath, ExpCtx);
1339 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1348 if (!DriverMode.empty())
1349 setDriverMode(DriverMode);
1355 CLOptions = std::make_unique<InputArgList>(
1360 ContainsError = loadConfigFiles();
1361 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1362 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1366 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1368 if (HasConfigFileHead)
1369 for (
auto *Opt : *CLOptions)
1370 if (!Opt->getOption().matches(options::OPT_config))
1374 if (
IsCLMode() && !ContainsError) {
1376 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1378 CLModePassThroughArgList.push_back(A->getValue());
1381 if (!CLModePassThroughArgList.empty()) {
1384 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1389 for (
auto *Opt : *CLModePassThroughOptions)
1395 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1396 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1397 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1401 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1402 if (!VFS->exists(IncludeDir))
1403 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1408 bool CCCPrintPhases;
1411 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1412 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1415 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1416 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1419 Args.ClaimAllArgs(options::OPT_pipe);
1427 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1429 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1430 CCCGenericGCCName = A->getValue();
1433 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1437 if (Args.hasArg(options::OPT_fproc_stat_report))
1444 llvm::Triple
T(TargetTriple);
1445 T.setOS(llvm::Triple::Win32);
1446 T.setVendor(llvm::Triple::PC);
1447 T.setEnvironment(llvm::Triple::MSVC);
1448 T.setObjectFormat(llvm::Triple::COFF);
1449 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1450 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1451 TargetTriple =
T.str();
1454 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1455 StringRef TargetProfile = A->getValue();
1458 TargetTriple = *Triple;
1460 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1464 if (Args.hasArg(options::OPT_spirv)) {
1465 llvm::Triple
T(TargetTriple);
1466 T.setArch(llvm::Triple::spirv);
1467 T.setOS(llvm::Triple::Vulkan);
1470 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1471 const llvm::StringSet<> ValidValues = {
"vulkan1.2",
"vulkan1.3"};
1472 if (ValidValues.contains(A->getValue())) {
1473 T.setOSName(A->getValue());
1475 Diag(diag::err_drv_invalid_value)
1476 << A->getAsString(Args) << A->getValue();
1481 TargetTriple =
T.str();
1484 Diag(diag::err_drv_dxc_missing_target_profile);
1488 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1489 TargetTriple = A->getValue();
1490 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1491 Dir =
Dir = A->getValue();
1492 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1496 if (std::optional<std::string> CompilerPathValue =
1497 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1498 StringRef CompilerPath = *CompilerPathValue;
1499 while (!CompilerPath.empty()) {
1500 std::pair<StringRef, StringRef> Split =
1501 CompilerPath.split(llvm::sys::EnvPathSeparator);
1502 PrefixDirs.push_back(std::string(Split.first));
1503 CompilerPath = Split.second;
1506 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1508 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1511 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1514 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1515 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1516 .Case(
"cwd", SaveTempsCwd)
1517 .Case(
"obj", SaveTempsObj)
1518 .Default(SaveTempsCwd);
1521 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1522 options::OPT_offload_device_only,
1523 options::OPT_offload_host_device)) {
1524 if (A->getOption().matches(options::OPT_offload_host_only))
1525 Offload = OffloadHost;
1526 else if (A->getOption().matches(options::OPT_offload_device_only))
1527 Offload = OffloadDevice;
1529 Offload = OffloadHostDevice;
1535 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1536 StringRef
Name = A->getValue();
1537 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1538 .Case(
"off", EmbedNone)
1539 .Case(
"all", EmbedBitcode)
1540 .Case(
"bitcode", EmbedBitcode)
1541 .Case(
"marker", EmbedMarker)
1544 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1547 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1551 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1552 llvm::sys::fs::remove(A->getValue());
1558 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1560 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1561 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1562 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1563 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1564 Std->containsValue(
"c++latest"));
1567 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1568 options::OPT_fmodule_header)) {
1570 ModulesModeCXX20 =
true;
1571 if (A->getOption().matches(options::OPT_fmodule_header))
1574 StringRef ArgName = A->getValue();
1575 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1580 Diags.
Report(diag::err_drv_invalid_value)
1581 << A->getAsString(Args) << ArgName;
1587 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1588 std::make_unique<InputArgList>(std::move(Args));
1591 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1599 if (!Triple.isWasm()) {
1600 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1601 StringRef TripleObjectFormat =
1602 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1603 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1604 TripleVersionName != TripleObjectFormat) {
1605 Diags.
Report(diag::err_drv_triple_version_invalid)
1607 ContainsError =
true;
1612 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1613 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1614 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1622 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1623 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1625 case llvm::Triple::arm:
1626 case llvm::Triple::armeb:
1627 case llvm::Triple::thumb:
1628 case llvm::Triple::thumbeb:
1629 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1630 Diag(diag::warn_target_unrecognized_env)
1632 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1635 case llvm::Triple::aarch64:
1636 case llvm::Triple::aarch64_be:
1637 case llvm::Triple::aarch64_32:
1638 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1639 Diag(diag::warn_target_unrecognized_env)
1641 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1658 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1659 if (HasConfigFileTail && Inputs.size()) {
1662 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1663 for (Arg *A : *CfgOptionsTail)
1664 TranslatedLinkerIns.append(A);
1665 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1674 if (TC.
getTriple().isOSBinFormatMachO())
1679 if (CCCPrintPhases) {
1690 llvm::opt::ArgStringList ASL;
1691 for (
const auto *A : Args) {
1695 while (A->getAlias())
1697 A->render(Args, ASL);
1700 for (
auto I = ASL.begin(),
E = ASL.end(); I !=
E; ++I) {
1701 if (I != ASL.begin())
1703 llvm::sys::printArg(OS, *I,
true);
1708bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1710 using namespace llvm::sys;
1711 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1712 "Only knows about .crash files on Darwin");
1717 path::home_directory(CrashDiagDir);
1718 if (CrashDiagDir.starts_with(
"/var/root"))
1720 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1728 fs::file_status FileStatus;
1729 TimePoint<> LastAccessTime;
1733 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1734 File != FileEnd && !EC;
File.increment(EC)) {
1738 if (fs::status(
File->path(), FileStatus))
1740 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1741 llvm::MemoryBuffer::getFile(
File->path());
1746 StringRef
Data = CrashFile.get()->getBuffer();
1747 if (!
Data.starts_with(
"Process:"))
1750 size_t ParentProcPos =
Data.find(
"Parent Process:");
1751 if (ParentProcPos == StringRef::npos)
1753 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1754 if (LineEnd == StringRef::npos)
1756 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1757 int OpenBracket = -1, CloseBracket = -1;
1758 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1759 if (ParentProcess[i] ==
'[')
1761 if (ParentProcess[i] ==
']')
1767 if (OpenBracket < 0 || CloseBracket < 0 ||
1768 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1769 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1779 const auto FileAccessTime = FileStatus.getLastModificationTime();
1780 if (FileAccessTime > LastAccessTime) {
1781 CrashFilePath.assign(
File->path());
1782 LastAccessTime = FileAccessTime;
1787 if (!CrashFilePath.empty()) {
1788 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1798 "\n********************\n\n"
1799 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1800 "Preprocessed source(s) and associated run script(s) are located at:";
1808 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1812 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1813 Level = llvm::StringSwitch<unsigned>(A->getValue())
1815 .Case(
"compiler", 1)
1827 ArgStringList SavedTemps;
1829 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1830 if (!IsLLD || Level < 2)
1837 SavedTemps = std::move(
C.getTempFiles());
1838 assert(!
C.getTempFiles().size());
1855 C.initCompilationForDiagnostics();
1861 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1862 StringRef ReproduceOption =
1863 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1866 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1870 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1872 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1873 Diag(clang::diag::note_drv_command_failed_diag_msg)
1874 <<
"\n\n********************";
1876 Report->TemporaryFiles.push_back(TmpName);
1884 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1885 bool IgnoreInput =
false;
1891 }
else if (!strcmp(it->second->getValue(),
"-")) {
1892 Diag(clang::diag::note_drv_command_failed_diag_msg)
1893 <<
"Error generating preprocessed source(s) - "
1894 "ignoring input from stdin.";
1899 it = Inputs.erase(it);
1906 if (Inputs.empty()) {
1907 Diag(clang::diag::note_drv_command_failed_diag_msg)
1908 <<
"Error generating preprocessed source(s) - "
1909 "no preprocessable inputs.";
1915 llvm::StringSet<> ArchNames;
1916 for (
const Arg *A :
C.getArgs()) {
1917 if (A->getOption().matches(options::OPT_arch)) {
1918 StringRef ArchName = A->getValue();
1919 ArchNames.insert(ArchName);
1922 if (ArchNames.size() > 1) {
1923 Diag(clang::diag::note_drv_command_failed_diag_msg)
1924 <<
"Error generating preprocessed source(s) - cannot generate "
1925 "preprocessed source with multiple -arch options.";
1931 const ToolChain &TC =
C.getDefaultToolChain();
1932 if (TC.
getTriple().isOSBinFormatMachO())
1941 Diag(clang::diag::note_drv_command_failed_diag_msg)
1942 <<
"Error generating preprocessed source(s).";
1948 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1951 if (!FailingCommands.empty()) {
1952 Diag(clang::diag::note_drv_command_failed_diag_msg)
1953 <<
"Error generating preprocessed source(s).";
1957 const ArgStringList &TempFiles =
C.getTempFiles();
1958 if (TempFiles.empty()) {
1959 Diag(clang::diag::note_drv_command_failed_diag_msg)
1960 <<
"Error generating preprocessed source(s).";
1968 for (
const char *TempFile : TempFiles) {
1969 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
1971 Report->TemporaryFiles.push_back(TempFile);
1972 if (ReproCrashFilename.empty()) {
1973 ReproCrashFilename = TempFile;
1974 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
1976 if (StringRef(TempFile).ends_with(
".cache")) {
1979 VFS = llvm::sys::path::filename(TempFile);
1980 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
1984 for (
const char *TempFile : SavedTemps)
1985 C.addTempFile(TempFile);
1991 llvm::sys::path::replace_extension(Script,
"sh");
1993 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
1994 llvm::sys::fs::FA_Write,
1995 llvm::sys::fs::OF_Text);
1997 Diag(clang::diag::note_drv_command_failed_diag_msg)
1998 <<
"Error generating run script: " << Script <<
" " << EC.message();
2001 <<
"# Driver args: ";
2003 ScriptOS <<
"# Original command: ";
2004 Cmd.Print(ScriptOS,
"\n",
true);
2005 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
2006 if (!AdditionalInformation.empty())
2007 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2010 Report->TemporaryFiles.push_back(std::string(Script));
2011 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2015 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2017 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2018 Diag(clang::diag::note_drv_command_failed_diag_msg)
2019 << ReproCrashFilename.str();
2021 llvm::sys::path::append(CrashDiagDir,
Name);
2022 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2023 Diag(clang::diag::note_drv_command_failed_diag_msg)
2024 <<
"Crash backtrace is located in";
2025 Diag(clang::diag::note_drv_command_failed_diag_msg)
2026 << CrashDiagDir.str();
2027 Diag(clang::diag::note_drv_command_failed_diag_msg)
2028 <<
"(choose the .crash file that corresponds to your crash)";
2032 Diag(clang::diag::note_drv_command_failed_diag_msg)
2033 <<
"\n\n********************";
2041 if (
Cmd.getResponseFileSupport().ResponseKind ==
2043 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
2044 Cmd.getArguments()))
2048 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
2054 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2055 if (
C.getArgs().hasArg(options::OPT_v))
2056 C.getJobs().Print(llvm::errs(),
"\n",
true);
2058 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2068 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2069 C.getJobs().Print(llvm::errs(),
"\n",
true);
2078 for (
auto &Job :
C.getJobs())
2079 setUpResponseFiles(
C, Job);
2081 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2084 if (FailingCommands.empty())
2090 for (
const auto &CmdPair : FailingCommands) {
2091 int CommandRes = CmdPair.first;
2092 const Command *FailingCommand = CmdPair.second;
2097 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2101 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2106 if (CommandRes == EX_IOERR) {
2123 Diag(clang::diag::err_drv_command_signalled)
2126 Diag(clang::diag::err_drv_command_failed)
2134 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2136 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2150 const ToolChain &TC =
C.getDefaultToolChain();
2154 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2157 OS <<
"Thread model: " << A->getValue();
2163 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2168 if (!llvm::cl::getCompilerBuildConfig().empty())
2169 llvm::cl::printBuildConfig(OS);
2172 for (
auto ConfigFile : ConfigFiles)
2173 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2186 if (PassedFlags ==
"")
2190 std::vector<std::string> SuggestedCompletions;
2191 std::vector<std::string> Flags;
2203 const bool HasSpace = PassedFlags.ends_with(
",");
2207 StringRef TargetFlags = PassedFlags;
2208 while (TargetFlags !=
"") {
2210 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2211 Flags.push_back(std::string(CurFlag));
2216 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2219 const llvm::opt::OptTable &Opts =
getOpts();
2221 Cur = Flags.at(Flags.size() - 1);
2223 if (Flags.size() >= 2) {
2224 Prev = Flags.at(Flags.size() - 2);
2225 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2228 if (SuggestedCompletions.empty())
2229 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2236 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2237 llvm::outs() <<
'\n';
2243 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2247 SuggestedCompletions = Opts.findByPrefix(
2248 Cur, VisibilityMask,
2255 if (S.starts_with(Cur))
2256 SuggestedCompletions.push_back(std::string(S));
2263 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2264 if (
int X = A.compare_insensitive(B))
2266 return A.compare(B) > 0;
2269 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2276 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2277 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2281 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2284 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2288 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2293 if (
C.getArgs().hasArg(options::OPT_help) ||
2294 C.getArgs().hasArg(options::OPT__help_hidden)) {
2295 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2299 if (
C.getArgs().hasArg(options::OPT__version)) {
2305 if (
C.getArgs().hasArg(options::OPT_v) ||
2306 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2307 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2308 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2309 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2311 SuppressMissingInputWarning =
true;
2314 if (
C.getArgs().hasArg(options::OPT_v)) {
2316 llvm::errs() <<
"System configuration file directory: "
2319 llvm::errs() <<
"User configuration file directory: "
2323 const ToolChain &TC =
C.getDefaultToolChain();
2325 if (
C.getArgs().hasArg(options::OPT_v))
2328 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2333 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2334 llvm::outs() <<
"programs: =";
2335 bool separator =
false;
2339 llvm::outs() << llvm::sys::EnvPathSeparator;
2340 llvm::outs() <<
Path;
2345 llvm::outs() << llvm::sys::EnvPathSeparator;
2346 llvm::outs() <<
Path;
2349 llvm::outs() <<
"\n";
2352 StringRef sysroot =
C.getSysRoot();
2356 llvm::outs() << llvm::sys::EnvPathSeparator;
2359 llvm::outs() << sysroot <<
Path.substr(1);
2361 llvm::outs() <<
Path;
2363 llvm::outs() <<
"\n";
2367 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2373 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2374 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2375 llvm::outs() << *RuntimePath <<
'\n';
2381 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2383 for (std::size_t I = 0; I != Flags.size(); I += 2)
2384 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2390 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2391 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2395 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2396 StringRef ProgName = A->getValue();
2399 if (! ProgName.empty())
2402 llvm::outs() <<
"\n";
2406 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2407 StringRef PassedFlags = A->getValue();
2412 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2426 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2429 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2435 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2442 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2445 std::set<llvm::StringRef> SortedFlags;
2446 for (
const auto &FlagEntry : ExpandedFlags)
2447 SortedFlags.insert(FlagEntry.getKey());
2448 for (
auto Flag : SortedFlags)
2449 llvm::outs() << Flag <<
'\n';
2453 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2456 llvm::outs() <<
".\n";
2459 assert(Suffix.front() ==
'/');
2460 llvm::outs() << Suffix.substr(1) <<
"\n";
2466 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2471 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2473 llvm::outs() << Triple.getTriple() <<
"\n";
2477 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2478 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2495 std::map<Action *, unsigned> &Ids,
2501 llvm::raw_string_ostream os(str);
2503 auto getSibIndent = [](
int K) -> Twine {
2507 Twine SibIndent = Indent + getSibIndent(Kind);
2511 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2513 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2514 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2515 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2516 bool IsFirst =
true;
2517 OA->doOnEachDependence(
2519 assert(TC &&
"Unknown host toolchain");
2531 os <<
":" << BoundArch;
2534 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2542 const char *Prefix =
"{";
2543 for (
Action *PreRequisite : *AL) {
2544 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2555 std::string offload_str;
2556 llvm::raw_string_ostream offload_os(offload_str);
2557 if (!isa<OffloadAction>(A)) {
2560 offload_os <<
", (" << S;
2567 auto getSelfIndent = [](
int K) -> Twine {
2571 unsigned Id = Ids.size();
2573 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2582 std::map<Action *, unsigned> Ids;
2583 for (
Action *A :
C.getActions())
2590 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2591 isa<AssembleJobAction>(A))
2599 DerivedArgList &Args =
C.getArgs();
2601 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2604 llvm::StringSet<> ArchNames;
2606 for (Arg *A : Args) {
2607 if (A->getOption().matches(options::OPT_arch)) {
2610 llvm::Triple::ArchType Arch =
2612 if (Arch == llvm::Triple::UnknownArch) {
2613 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2618 if (ArchNames.insert(A->getValue()).second)
2619 Archs.push_back(A->getValue());
2633 for (
Action* Act : SingleActions) {
2641 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2645 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2650 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2651 Actions.append(Inputs.begin(), Inputs.end());
2653 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2656 Arg *A = Args.getLastArg(options::OPT_g_Group);
2657 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2658 !A->getOption().matches(options::OPT_gstabs);
2666 if (Act->getType() == types::TY_Image) {
2668 Inputs.push_back(Actions.back());
2675 if (Args.hasArg(options::OPT_verify_debug_info)) {
2676 Action* LastAction = Actions.back();
2679 LastAction, types::TY_Nothing));
2698 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2699 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2711 std::string Nearest;
2712 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2713 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2714 <<
Value << Nearest;
2753 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2756 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2764 return types::TY_CXXUHeader;
2766 return types::TY_CXXSHeader;
2770 llvm_unreachable(
"should not be called in this case");
2772 return types::TY_CXXHUHeader;
2778 const llvm::opt::OptTable &Opts =
getOpts();
2782 types::ID InputType = types::TY_Nothing;
2783 Arg *InputTypeArg =
nullptr;
2786 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2787 options::OPT__SLASH_TP)) {
2788 InputTypeArg = TCTP;
2789 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2794 bool ShowNote =
false;
2796 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2798 Diag(clang::diag::warn_drv_overriding_option)
2799 <<
Previous->getSpelling() << A->getSpelling();
2805 Diag(clang::diag::note_drv_t_option_is_global);
2810 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2811 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2812 if (LastXArg && LastInputArg &&
2813 LastInputArg->getIndex() < LastXArg->getIndex())
2814 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2817 for (Arg *A : Args) {
2818 if (A->getOption().
getKind() == Option::InputClass) {
2819 const char *
Value = A->getValue();
2823 if (InputType == types::TY_Nothing) {
2826 InputTypeArg->claim();
2829 if (memcmp(
Value,
"-", 2) == 0) {
2831 Ty = types::TY_Fortran;
2833 Ty = types::TY_HLSL;
2842 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2843 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2844 : clang::diag::err_drv_unknown_stdin_type);
2853 if (
const char *Ext = strrchr(
Value,
'.'))
2862 Ty = types::TY_Object;
2873 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2874 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2875 << getTypeName(OldTy) << getTypeName(Ty);
2880 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2881 Ty == types::TY_Object)
2882 Ty = types::TY_LLVM_BC;
2890 if (Ty != types::TY_Object) {
2891 if (Args.hasArg(options::OPT_ObjC))
2892 Ty = types::TY_ObjC;
2893 else if (Args.hasArg(options::OPT_ObjCXX))
2894 Ty = types::TY_ObjCXX;
2901 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
2905 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2906 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2909 const char *Ext = strrchr(
Value,
'.');
2911 Ty = types::TY_Object;
2915 InputTypeArg->claim();
2919 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
2920 Args.hasArgNoClaim(options::OPT_hipstdpar))
2924 Inputs.push_back(std::make_pair(Ty, A));
2926 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2927 StringRef
Value = A->getValue();
2930 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2931 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2934 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2935 StringRef
Value = A->getValue();
2938 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2939 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2945 Inputs.push_back(std::make_pair(types::TY_Object, A));
2947 }
else if (A->getOption().matches(options::OPT_x)) {
2956 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2957 InputType = types::TY_Object;
2964 }
else if (A->getOption().getID() == options::OPT_U) {
2965 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
2966 StringRef Val = A->getValue(0);
2967 if (Val.find_first_of(
"/\\") != StringRef::npos) {
2969 Diag(diag::warn_slash_u_filename) << Val;
2970 Diag(diag::note_use_dashdash);
2974 if (
CCCIsCPP() && Inputs.empty()) {
2978 Inputs.push_back(std::make_pair(types::TY_C, A));
2985class OffloadingActionBuilder final {
2987 bool IsValid =
false;
2993 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
2996 std::map<Action *, const Arg *> HostActionToInputArgMap;
2999 class DeviceActionBuilder {
3003 enum ActionBuilderReturnCode {
3022 DerivedArgList &Args;
3031 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3034 :
C(
C), Args(Args), Inputs(Inputs),
3035 AssociatedOffloadKind(AssociatedOffloadKind) {}
3036 virtual ~DeviceActionBuilder() {}
3041 virtual ActionBuilderReturnCode
3045 return ABRT_Inactive;
3050 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
3051 return ABRT_Inactive;
3055 virtual void appendTopLevelActions(
ActionList &AL) {}
3058 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3071 virtual bool canUseBundlerUnbundler()
const {
return false; }
3075 bool isValid() {
return !ToolChains.empty(); }
3079 return AssociatedOffloadKind;
3085 class CudaActionBuilderBase :
public DeviceActionBuilder {
3089 bool CompileHostOnly =
false;
3090 bool CompileDeviceOnly =
false;
3092 bool EmitAsm =
false;
3102 TargetID(
const char *
ID) :
ID(
ID) {}
3103 operator const char *() {
return ID; }
3104 operator StringRef() {
return StringRef(
ID); }
3113 Action *CudaFatBinary =
nullptr;
3116 bool IsActive =
false;
3119 bool Relocatable =
false;
3122 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3126 enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
3127 UseCUIDKind UseCUID = CUID_Hash;
3130 StringRef FixedCUID;
3133 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
3136 : DeviceActionBuilder(
C, Args, Inputs, OFKind) {
3138 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3139 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3140 options::OPT_fno_gpu_rdc,
false);
3143 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3150 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3151 assert(!GpuArchList.empty() &&
3152 "We should have at least one GPU architecture.");
3156 if (!(IA->getType() == types::TY_CUDA ||
3157 IA->getType() == types::TY_HIP ||
3158 IA->getType() == types::TY_PP_HIP)) {
3161 return ABRT_Inactive;
3167 std::string CUID = FixedCUID.str();
3169 if (UseCUID == CUID_Random)
3170 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
3172 else if (UseCUID == CUID_Hash) {
3174 llvm::MD5::MD5Result Hash;
3176 llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
3178 Hasher.update(RealPath);
3179 for (
auto *A : Args) {
3180 if (A->getOption().matches(options::OPT_INPUT))
3182 Hasher.update(A->getAsString(Args));
3185 CUID = llvm::utohexstr(Hash.low(),
true);
3190 if (CompileHostOnly)
3191 return ABRT_Success;
3194 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3195 : types::TY_CUDA_DEVICE;
3196 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3197 CudaDeviceActions.push_back(
3198 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3201 return ABRT_Success;
3205 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3209 if (UA->getType() == types::TY_Object && !Relocatable)
3210 return ABRT_Inactive;
3212 CudaDeviceActions.clear();
3213 auto *IA = cast<InputAction>(UA->getInputs().back());
3214 std::string
FileName = IA->getInputArg().getAsString(Args);
3220 const StringRef LibFileExt =
".lib";
3221 if (IA->getType() == types::TY_Object &&
3222 (!llvm::sys::path::has_extension(
FileName) ||
3224 llvm::sys::path::extension(
FileName).drop_front()) !=
3226 llvm::sys::path::extension(
FileName) == LibFileExt))
3227 return ABRT_Inactive;
3229 for (
auto Arch : GpuArchList) {
3230 CudaDeviceActions.push_back(UA);
3231 UA->registerDependentActionInfo(ToolChains[0], Arch,
3232 AssociatedOffloadKind);
3235 return ABRT_Success;
3238 return IsActive ? ABRT_Success : ABRT_Inactive;
3241 void appendTopLevelActions(
ActionList &AL)
override {
3243 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3245 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3250 if (CudaFatBinary) {
3251 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3252 CudaDeviceActions.clear();
3253 CudaFatBinary =
nullptr;
3257 if (CudaDeviceActions.empty())
3263 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3264 "Expecting one action per GPU architecture.");
3265 assert(ToolChains.size() == 1 &&
3266 "Expecting to have a single CUDA toolchain.");
3267 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I)
3268 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3270 CudaDeviceActions.clear();
3275 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3277 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3295 assert(HostTC &&
"No toolchain for host compilation.");
3297 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3301 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3306 ToolChains.push_back(
3311 CompileHostOnly =
C.getDriver().offloadHostOnly();
3312 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3313 EmitAsm = Args.getLastArg(options::OPT_S);
3314 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3315 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3316 StringRef UseCUIDStr = A->getValue();
3317 UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3318 .Case(
"hash", CUID_Hash)
3319 .Case(
"random", CUID_Random)
3320 .Case(
"none", CUID_None)
3321 .Default(CUID_Invalid);
3322 if (UseCUID == CUID_Invalid) {
3323 C.getDriver().Diag(diag::err_drv_invalid_value)
3324 << A->getAsString(Args) << UseCUIDStr;
3325 C.setContainsError();
3331 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3332 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3333 options::OPT_no_offload_arch_EQ)) {
3334 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3339 std::set<StringRef> GpuArchs;
3341 for (Arg *A : Args) {
3342 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3343 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3347 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3348 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3351 }
else if (ArchStr ==
"native") {
3352 const ToolChain &TC = *ToolChains.front();
3353 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3356 << llvm::Triple::getArchTypeName(TC.
getArch())
3357 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3361 for (
auto GPU : *GPUsOrErr) {
3362 GpuArchs.insert(Args.MakeArgString(GPU));
3365 ArchStr = getCanonicalOffloadArch(ArchStr);
3366 if (ArchStr.empty()) {
3368 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3369 GpuArchs.insert(ArchStr);
3370 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3371 GpuArchs.erase(ArchStr);
3373 llvm_unreachable(
"Unexpected option.");
3379 if (ConflictingArchs) {
3380 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3381 << ConflictingArchs->first << ConflictingArchs->second;
3382 C.setContainsError();
3387 for (
auto Arch : GpuArchs)
3388 GpuArchList.push_back(Arch.data());
3393 if (GpuArchList.empty()) {
3394 if (ToolChains.front()->getTriple().isSPIRV()) {
3395 if (ToolChains.front()->getTriple().getVendor() == llvm::Triple::AMD)
3396 GpuArchList.push_back(OffloadArch::AMDGCNSPIRV);
3398 GpuArchList.push_back(OffloadArch::Generic);
3400 GpuArchList.push_back(DefaultOffloadArch);
3410 class CudaActionBuilder final :
public CudaActionBuilderBase {
3412 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3414 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3415 DefaultOffloadArch = OffloadArch::CudaDefault;
3418 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3421 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3427 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3429 const std::set<StringRef> &GpuArchs)
override {
3430 return std::nullopt;
3433 ActionBuilderReturnCode
3436 PhasesTy &Phases)
override {
3438 return ABRT_Inactive;
3442 if (CudaDeviceActions.empty())
3443 return ABRT_Success;
3445 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3446 "Expecting one action per GPU architecture.");
3447 assert(!CompileHostOnly &&
3448 "Not expecting CUDA actions in host-only compilation.");
3458 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3461 for (
auto Ph : Phases) {
3466 if (Ph > FinalPhase)
3469 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3479 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3483 Action *AssembleAction = CudaDeviceActions[I];
3484 assert(AssembleAction->
getType() == types::TY_Object);
3485 assert(AssembleAction->
getInputs().size() == 1);
3493 DeviceActions.push_back(
3499 if (!DeviceActions.empty()) {
3501 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3503 if (!CompileDeviceOnly) {
3504 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3508 CudaFatBinary =
nullptr;
3513 CudaDeviceActions.clear();
3517 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3522 return ABRT_Success;
3526 "instructions should only occur "
3527 "before the backend phase!");
3530 for (
Action *&A : CudaDeviceActions)
3531 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3533 return ABRT_Success;
3538 class HIPActionBuilder final :
public CudaActionBuilderBase {
3546 std::optional<bool> BundleOutput;
3547 std::optional<bool> EmitReloc;
3552 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3554 DefaultOffloadArch = OffloadArch::HIPDefault;
3556 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3557 options::OPT_fno_hip_emit_relocatable)) {
3558 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3559 options::OPT_fno_hip_emit_relocatable,
false);
3563 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3564 <<
"-fhip-emit-relocatable"
3568 if (!CompileDeviceOnly) {
3569 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3570 <<
"-fhip-emit-relocatable"
3571 <<
"--cuda-device-only";
3576 if (Args.hasArg(options::OPT_gpu_bundle_output,
3577 options::OPT_no_gpu_bundle_output))
3578 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3579 options::OPT_no_gpu_bundle_output,
true) &&
3580 (!EmitReloc || !*EmitReloc);
3583 bool canUseBundlerUnbundler()
const override {
return true; }
3585 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3586 llvm::StringMap<bool> Features;
3590 (IdStr ==
"amdgcnspirv")
3591 ? llvm::Triple(
"spirv64-amd-amdhsa")
3595 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3596 C.setContainsError();
3600 return Args.MakeArgStringRef(CanId);
3603 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3605 const std::set<StringRef> &GpuArchs)
override {
3609 ActionBuilderReturnCode
3612 PhasesTy &Phases)
override {
3614 return ABRT_Inactive;
3620 if (CudaDeviceActions.empty())
3621 return ABRT_Success;
3624 CudaDeviceActions.size() == GpuArchList.size()) &&
3625 "Expecting one action per GPU architecture.");
3626 assert(!CompileHostOnly &&
3627 "Not expecting HIP actions in host-only compilation.");
3629 bool ShouldLink = !EmitReloc || !*EmitReloc;
3632 !EmitAsm && ShouldLink) {
3638 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3639 if (
C.getDriver().isUsingOffloadLTO()) {
3643 AL.push_back(CudaDeviceActions[I]);
3646 CudaDeviceActions[I] =
3653 if (ToolChains.front()->getTriple().isSPIRV()) {
3656 types::ID Output = Args.hasArg(options::OPT_S)
3658 : types::TY_LLVM_BC;
3664 AssociatedOffloadKind);
3665 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3667 AssociatedOffloadKind);
3668 AL.push_back(AssembleAction);
3671 CudaDeviceActions[I] =
3682 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3683 AssociatedOffloadKind);
3685 DDep, CudaDeviceActions[I]->getType());
3688 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3691 types::TY_HIP_FATBIN);
3693 if (!CompileDeviceOnly) {
3694 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3695 AssociatedOffloadKind);
3698 CudaFatBinary =
nullptr;
3703 CudaDeviceActions.clear();
3706 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3709 return ABRT_Success;
3715 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3716 auto LI = DeviceLinkerInputs.begin();
3717 for (
auto *A : CudaDeviceActions) {
3724 CudaDeviceActions.clear();
3725 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3729 for (
Action *&A : CudaDeviceActions)
3730 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3731 AssociatedOffloadKind);
3733 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3735 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3737 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3738 AssociatedOffloadKind);
3740 DDep, CudaDeviceActions[I]->getType());
3744 CudaDeviceActions.clear();
3747 return (CompileDeviceOnly &&
3748 (CurPhase == FinalPhase ||
3754 void appendLinkDeviceActions(
ActionList &AL)
override {
3755 if (DeviceLinkerInputs.size() == 0)
3758 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3759 "Linker inputs and GPU arch list sizes do not match.");
3765 for (
auto &LI : DeviceLinkerInputs) {
3767 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3771 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3775 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3776 GpuArchList[I], AssociatedOffloadKind);
3778 DeviceLinkDeps, DeviceLinkAction->getType()));
3781 DeviceLinkerInputs.clear();
3784 if (Args.hasArg(options::OPT_emit_llvm)) {
3793 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3796 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3797 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3798 AssociatedOffloadKind);
3801 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3807 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3823 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3831 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3834 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3842 unsigned ValidBuilders = 0u;
3843 unsigned ValidBuildersSupportingBundling = 0u;
3844 for (
auto *SB : SpecializedBuilders) {
3845 IsValid = IsValid && !SB->initialize();
3848 if (SB->isValid()) {
3850 if (SB->canUseBundlerUnbundler())
3851 ++ValidBuildersSupportingBundling;
3855 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3858 ~OffloadingActionBuilder() {
3859 for (
auto *SB : SpecializedBuilders)
3864 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3865 assert(HostAction &&
"Invalid host action");
3866 assert(InputArg &&
"Invalid input argument");
3867 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3868 assert(
Loc->second == InputArg &&
3869 "host action mapped to multiple input arguments");
3878 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3880 DeviceActionBuilder::PhasesTy &Phases) {
3884 if (SpecializedBuilders.empty())
3887 assert(HostAction &&
"Invalid host action!");
3888 recordHostAction(HostAction, InputArg);
3893 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3894 unsigned InactiveBuilders = 0u;
3895 unsigned IgnoringBuilders = 0u;
3896 for (
auto *SB : SpecializedBuilders) {
3897 if (!SB->isValid()) {
3902 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3907 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3912 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3913 OffloadKind |= SB->getAssociatedOffloadKind();
3918 if (IgnoringBuilders &&
3919 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3936 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3937 const Arg *InputArg) {
3941 recordHostAction(HostAction, InputArg);
3949 if (CanUseBundler && isa<InputAction>(HostAction) &&
3950 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3952 HostAction->
getType() == types::TY_PP_HIP)) {
3953 auto UnbundlingHostAction =
3958 HostAction = UnbundlingHostAction;
3959 recordHostAction(HostAction, InputArg);
3962 assert(HostAction &&
"Invalid host action!");
3965 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3966 for (
auto *SB : SpecializedBuilders) {
3970 auto RetCode = SB->addDeviceDependences(HostAction);
3974 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3975 "Host dependence not expected to be ignored.!");
3979 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3980 OffloadKind |= SB->getAssociatedOffloadKind();
3985 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
3995 const Arg *InputArg) {
3997 recordHostAction(HostAction, InputArg);
4001 for (
auto *SB : SpecializedBuilders) {
4004 SB->appendTopLevelActions(OffloadAL);
4011 if (CanUseBundler && HostAction &&
4012 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4014 OffloadAL.push_back(HostAction);
4018 assert(HostAction == AL.back() &&
"Host action not in the list??");
4020 recordHostAction(HostAction, InputArg);
4021 AL.back() = HostAction;
4023 AL.append(OffloadAL.begin(), OffloadAL.end());
4033 void appendDeviceLinkActions(
ActionList &AL) {
4034 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4037 SB->appendLinkDeviceActions(AL);
4041 Action *makeHostLinkAction() {
4044 appendDeviceLinkActions(DeviceAL);
4045 if (DeviceAL.empty())
4050 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4053 HA = SB->appendLinkHostActions(DeviceAL);
4070 for (
auto *SB : SpecializedBuilders) {
4074 SB->appendLinkDependences(DDeps);
4078 unsigned ActiveOffloadKinds = 0u;
4079 for (
auto &I : InputArgToOffloadKindMap)
4080 ActiveOffloadKinds |= I.second;
4092 for (
auto *A : HostAction->
inputs()) {
4093 auto ArgLoc = HostActionToInputArgMap.find(A);
4094 if (ArgLoc == HostActionToInputArgMap.end())
4096 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4097 if (OFKLoc == InputArgToOffloadKindMap.end())
4109 nullptr, ActiveOffloadKinds);
4115void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4116 const InputList &Inputs,
4120 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4121 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4122 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4123 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4124 Args.eraseArg(options::OPT__SLASH_Yc);
4125 Args.eraseArg(options::OPT__SLASH_Yu);
4126 YcArg = YuArg =
nullptr;
4128 if (YcArg && Inputs.size() > 1) {
4129 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4130 Args.eraseArg(options::OPT__SLASH_Yc);
4138 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4139 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4140 Args.AddFlagArg(
nullptr,
4141 getOpts().getOption(options::OPT_frtlib_add_rpath));
4144 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4145 Diag(clang::diag::err_drv_emit_llvm_link);
4146 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4148 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4149 .starts_with_insensitive(
"lld"))
4150 Diag(clang::diag::err_drv_lto_without_lld);
4156 if (!Args.hasArg(options::OPT_dumpdir)) {
4157 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4158 Arg *Arg = Args.MakeSeparateArg(
4159 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4161 (FinalOutput ? FinalOutput->getValue()
4173 Args.eraseArg(options::OPT__SLASH_Fp);
4174 Args.eraseArg(options::OPT__SLASH_Yc);
4175 Args.eraseArg(options::OPT__SLASH_Yu);
4176 YcArg = YuArg =
nullptr;
4179 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4180 for (
auto &I : Inputs) {
4182 const Arg *InputArg = I.second;
4187 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4191 if (InitialPhase > FinalPhase) {
4192 if (InputArg->isClaimed())
4199 if (Args.hasArg(options::OPT_Qunused_arguments))
4205 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4206 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4210 (Args.getLastArg(options::OPT__SLASH_EP,
4211 options::OPT__SLASH_P) ||
4212 Args.getLastArg(options::OPT_E) ||
4213 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4215 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4216 << InputArg->getAsString(Args) << !!FinalPhaseArg
4217 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4219 Diag(clang::diag::warn_drv_input_file_unused)
4220 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4222 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4235 Actions.push_back(ClangClPch);
4247 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4248 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4254 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4256 if (!SuppressMissingInputWarning && Inputs.empty()) {
4257 Diag(clang::diag::err_drv_no_input_files);
4262 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4263 StringRef
V = A->getValue();
4264 if (Inputs.size() > 1 && !
V.empty() &&
4265 !llvm::sys::path::is_separator(
V.back())) {
4267 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4268 << A->getSpelling() <<
V;
4269 Args.eraseArg(options::OPT__SLASH_Fo);
4274 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4275 StringRef
V = A->getValue();
4276 if (Inputs.size() > 1 && !
V.empty() &&
4277 !llvm::sys::path::is_separator(
V.back())) {
4279 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4280 << A->getSpelling() <<
V;
4281 Args.eraseArg(options::OPT__SLASH_Fa);
4286 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4287 if (A->getValue()[0] ==
'\0') {
4289 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4290 Args.eraseArg(options::OPT__SLASH_o);
4294 handleArguments(
C, Args, Inputs, Actions);
4296 bool UseNewOffloadingDriver =
4299 Args.hasFlag(options::OPT_foffload_via_llvm,
4300 options::OPT_fno_offload_via_llvm,
false) ||
4301 Args.hasFlag(options::OPT_offload_new_driver,
4302 options::OPT_no_offload_new_driver,
false);
4305 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4306 !UseNewOffloadingDriver
4307 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4315 for (
auto &I : Inputs) {
4317 const Arg *InputArg = I.second;
4330 if (!UseNewOffloadingDriver)
4331 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4337 if (!UseNewOffloadingDriver)
4338 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4339 Current, InputArg, Phase, PL.back(), FullPL);
4345 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4348 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4349 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4351 LinkerInputs.push_back(Current);
4361 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4362 MergerInputs.push_back(Current);
4380 if (NewCurrent == Current)
4383 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4386 Current = NewCurrent;
4390 if (UseNewOffloadingDriver)
4394 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4398 if (Current->getType() == types::TY_Nothing)
4404 Actions.push_back(Current);
4407 if (!UseNewOffloadingDriver)
4408 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4410 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4416 if (LinkerInputs.empty()) {
4419 if (!UseNewOffloadingDriver)
4420 OffloadBuilder->appendDeviceLinkActions(Actions);
4423 if (!LinkerInputs.empty()) {
4424 if (!UseNewOffloadingDriver)
4425 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4426 LinkerInputs.push_back(Wrapper);
4431 }
else if (UseNewOffloadingDriver ||
4432 Args.hasArg(options::OPT_offload_link)) {
4439 if (!UseNewOffloadingDriver)
4440 LA = OffloadBuilder->processHostLinkAction(LA);
4441 Actions.push_back(LA);
4445 if (!MergerInputs.empty())
4449 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4456 for (
auto &I : Inputs) {
4458 const Arg *InputArg = I.second;
4463 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4464 InputType == types::TY_Asm)
4469 for (
auto Phase : PhaseList) {
4473 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4478 if (InputType == types::TY_Object)
4485 assert(Phase == PhaseList.back() &&
4486 "merging must be final compilation step.");
4487 MergerInputs.push_back(Current);
4496 Actions.push_back(Current);
4500 if (!MergerInputs.empty())
4505 for (
auto Opt : {options::OPT_print_supported_cpus,
4506 options::OPT_print_supported_extensions,
4507 options::OPT_print_enabled_extensions}) {
4514 if (Arg *A = Args.getLastArg(Opt)) {
4515 if (Opt == options::OPT_print_supported_extensions &&
4516 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4517 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4518 !
C.getDefaultToolChain().getTriple().isARM()) {
4519 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4520 <<
"--print-supported-extensions";
4523 if (Opt == options::OPT_print_enabled_extensions &&
4524 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4525 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4526 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4527 <<
"--print-enabled-extensions";
4534 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4537 for (
auto &I : Inputs)
4543 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4547 if (TC.requiresValidation(Args)) {
4548 Action *LastAction = Actions.back();
4550 LastAction, types::TY_DX_CONTAINER));
4555 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4561 const llvm::opt::DerivedArgList &Args,
4563 const llvm::Triple &Triple,
4564 bool SuppressError =
false) {
4569 if (!SuppressError && Triple.isNVPTX() &&
4571 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4572 <<
"CUDA" << ArchStr;
4574 }
else if (!SuppressError && Triple.isAMDGPU() &&
4576 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4577 <<
"HIP" << ArchStr;
4585 llvm::StringMap<bool> Features;
4591 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4592 C.setContainsError();
4604static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4606 llvm::Triple Triple) {
4607 if (!Triple.isAMDGPU())
4608 return std::nullopt;
4610 std::set<StringRef> ArchSet;
4611 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4615llvm::DenseSet<StringRef>
4618 bool SuppressError)
const {
4620 TC = &
C.getDefaultToolChain();
4623 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4624 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4625 options::OPT_no_offload_arch_EQ)) {
4626 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4628 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4630 :
"--no-offload-arch");
4633 if (KnownArchs.contains(TC))
4634 return KnownArchs.lookup(TC);
4636 llvm::DenseSet<StringRef> Archs;
4637 for (
auto *Arg : Args) {
4639 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4640 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4643 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4644 unsigned Prev = Index;
4645 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4646 if (!ExtractedArg || Index > Prev + 1) {
4647 TC->
getDriver().
Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
4648 << Arg->getAsString(Args);
4651 Arg = ExtractedArg.get();
4656 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4657 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4658 if (Arch ==
"native" || Arch.empty()) {
4662 llvm::consumeError(GPUsOrErr.takeError());
4665 << llvm::Triple::getArchTypeName(TC->
getArch())
4666 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4670 for (
auto ArchStr : *GPUsOrErr) {
4677 C, Args, Arch, TC->
getTriple(), SuppressError);
4678 if (ArchStr.empty())
4680 Archs.insert(ArchStr);
4683 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4684 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4685 if (Arch ==
"all") {
4689 C, Args, Arch, TC->
getTriple(), SuppressError);
4690 if (ArchStr.empty())
4692 Archs.erase(ArchStr);
4698 if (
auto ConflictingArchs =
4700 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4701 << ConflictingArchs->first << ConflictingArchs->second;
4702 C.setContainsError();
4709 if (Archs.empty()) {
4715 Archs.insert(StringRef());
4717 Archs.insert(StringRef());
4719 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4720 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4727 llvm::opt::DerivedArgList &Args,
4729 Action *HostAction)
const {
4734 !(isa<CompileJobAction>(HostAction) ||
4748 auto TCRange =
C.getOffloadToolChains(Kind);
4749 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4750 ToolChains.push_back(TI->second);
4752 if (ToolChains.empty())
4756 const Arg *InputArg = Input.second;
4765 for (
const ToolChain *TC : ToolChains) {
4769 for (StringRef Arch : Sorted)
4770 TCAndArchs.push_back(std::make_pair(TC, Arch));
4773 for (
unsigned I = 0,
E = TCAndArchs.size(); I !=
E; ++I)
4774 DeviceActions.push_back(
C.MakeAction<
InputAction>(*InputArg, InputType));
4776 if (DeviceActions.empty())
4782 HostAction->
getType() != types::TY_Nothing &&
4792 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4801 auto TCAndArch = TCAndArchs.begin();
4802 for (
Action *&A : DeviceActions) {
4803 if (A->
getType() == types::TY_Nothing)
4811 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4813 HostAction->
getType() != types::TY_Nothing) {
4820 TCAndArch->second.data(), Kind);
4822 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4831 for (
Action *&A : DeviceActions) {
4832 if ((A->
getType() != types::TY_Object &&
4833 A->
getType() != types::TY_LTO_BC) ||
4835 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4841 auto TCAndArch = TCAndArchs.begin();
4842 for (
Action *A : DeviceActions) {
4843 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4845 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4850 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4852 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4860 bool ShouldBundleHIP =
4862 Args.hasFlag(options::OPT_gpu_bundle_output,
4863 options::OPT_no_gpu_bundle_output,
true) &&
4864 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4865 !llvm::any_of(OffloadActions,
4872 if (OffloadActions.empty())
4877 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4881 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4885 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4890 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4899 nullptr,
C.getActiveOffloadKinds());
4908 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4909 return A->
getType() == types::TY_Nothing;
4910 }) && isa<CompileJobAction>(HostAction);
4913 nullptr, SingleDeviceOutput ? DDep : DDeps);
4914 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4920 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4930 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
4936 llvm_unreachable(
"link action invalid here.");
4938 llvm_unreachable(
"ifsmerge action invalid here.");
4943 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4944 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4945 OutputTy = types::TY_Dependencies;
4950 if (!Args.hasFlag(options::OPT_frewrite_includes,
4951 options::OPT_fno_rewrite_includes,
false) &&
4952 !Args.hasFlag(options::OPT_frewrite_imports,
4953 options::OPT_fno_rewrite_imports,
false) &&
4954 !Args.hasFlag(options::OPT_fdirectives_only,
4955 options::OPT_fno_directives_only,
false) &&
4959 "Cannot preprocess this input type!");
4965 if (Args.hasArg(options::OPT_extract_api))
4972 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
4973 !Args.getLastArg(options::OPT__precompile))
4978 "Cannot precompile this input type!");
4982 const char *ModName =
nullptr;
4983 if (OutputTy == types::TY_PCH) {
4984 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4985 ModName = A->getValue();
4987 OutputTy = types::TY_ModuleFile;
4990 if (Args.hasArg(options::OPT_fsyntax_only)) {
4992 OutputTy = types::TY_Nothing;
4998 if (Args.hasArg(options::OPT_fsyntax_only))
5000 if (Args.hasArg(options::OPT_rewrite_objc))
5002 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5004 types::TY_RewrittenLegacyObjC);
5005 if (Args.hasArg(options::OPT__analyze))
5007 if (Args.hasArg(options::OPT__migrate))
5009 if (Args.hasArg(options::OPT_emit_ast))
5011 if (Args.hasArg(options::OPT_emit_cir))
5013 if (Args.hasArg(options::OPT_module_file_info))
5015 if (Args.hasArg(options::OPT_verify_pch))
5017 if (Args.hasArg(options::OPT_extract_api))
5024 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5025 !Args.hasArg(options::OPT_emit_llvm))
5026 Output = types::TY_PP_Asm;
5027 else if (Args.hasArg(options::OPT_S))
5028 Output = types::TY_LTO_IR;
5030 Output = types::TY_LTO_BC;
5035 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5038 if (Args.hasArg(options::OPT_emit_llvm) ||
5043 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5047 Args.hasArg(options::OPT_S) &&
5051 !Args.hasFlag(options::OPT_offload_new_driver,
5052 options::OPT_no_offload_new_driver,
false)))
5054 : types::TY_LLVM_BC;
5063 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5067 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5069 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5089 unsigned NumOutputs = 0;
5090 unsigned NumIfsOutputs = 0;
5091 for (
const Action *A :
C.getActions()) {
5092 if (A->
getType() != types::TY_Nothing &&
5093 A->
getType() != types::TY_DX_CONTAINER &&
5095 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5097 0 == NumIfsOutputs++) ||
5102 A->
getType() == types::TY_Nothing &&
5103 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5104 NumOutputs += A->
size();
5107 if (NumOutputs > 1) {
5108 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5109 FinalOutput =
nullptr;
5113 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5116 llvm::StringSet<> ArchNames;
5117 if (RawTriple.isOSBinFormatMachO())
5118 for (
const Arg *A :
C.getArgs())
5119 if (A->getOption().matches(options::OPT_arch))
5120 ArchNames.insert(A->getValue());
5123 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5124 for (
Action *A :
C.getActions()) {
5131 const char *LinkingOutput =
nullptr;
5132 if (isa<LipoJobAction>(A)) {
5134 LinkingOutput = FinalOutput->getValue();
5142 ArchNames.size() > 1,
5143 LinkingOutput, CachedResults,
5150 for (
auto &J :
C.getJobs())
5151 J.InProcess =
false;
5154 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
5155 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5156 Cmd.getProcessStatistics();
5160 const char *LinkingOutput =
nullptr;
5162 LinkingOutput = FinalOutput->getValue();
5163 else if (!
Cmd.getOutputFilenames().empty())
5164 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
5169 using namespace llvm;
5171 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
5172 <<
"output=" << LinkingOutput;
5173 outs() <<
", total="
5174 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5176 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5177 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5181 llvm::raw_string_ostream Out(Buffer);
5182 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
5185 llvm::sys::printArg(Out, LinkingOutput, true);
5186 Out <<
',' << ProcStat->TotalTime.count() <<
','
5187 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5191 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5192 llvm::sys::fs::OF_Append |
5193 llvm::sys::fs::OF_Text);
5198 llvm::errs() <<
"ERROR: Cannot lock file "
5199 << CCPrintStatReportFilename <<
": "
5200 << toString(L.takeError()) <<
"\n";
5211 if (Diags.hasErrorOccurred() ||
5212 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5216 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5218 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5221 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5222 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5224 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5228 return strstr(J.getCreator().getShortName(),
"assembler");
5230 for (Arg *A :
C.getArgs()) {
5234 if (!A->isClaimed()) {
5240 const Option &Opt = A->getOption();
5241 if (Opt.getKind() == Option::FlagClass) {
5242 bool DuplicateClaimed =
false;
5244 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5245 if (AA->isClaimed()) {
5246 DuplicateClaimed =
true;
5251 if (DuplicateClaimed)
5257 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5259 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5264 !
C.getActions().empty()) {
5265 Diag(diag::err_drv_unsupported_opt_for_target)
5266 << A->getSpelling() << getTargetTriple();
5268 Diag(clang::diag::warn_drv_unused_argument)
5269 << A->getAsString(
C.getArgs());
5279class ToolSelector final {
5290 bool IsHostSelector;
5301 bool CanBeCollapsed =
true) {
5303 if (Inputs.size() != 1)
5306 Action *CurAction = *Inputs.begin();
5307 if (CanBeCollapsed &&
5313 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5317 if (!IsHostSelector) {
5318 if (OA->hasSingleDeviceDependence(
true)) {
5320 OA->getSingleDeviceDependence(
true);
5321 if (CanBeCollapsed &&
5324 SavedOffloadAction.push_back(OA);
5325 return dyn_cast<JobAction>(CurAction);
5327 }
else if (OA->hasHostDependence()) {
5328 CurAction = OA->getHostDependence();
5329 if (CanBeCollapsed &&
5332 SavedOffloadAction.push_back(OA);
5333 return dyn_cast<JobAction>(CurAction);
5338 return dyn_cast<JobAction>(CurAction);
5342 bool canCollapseAssembleAction()
const {
5343 return TC.useIntegratedAs() && !SaveTemps &&
5344 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5345 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5346 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5347 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5351 bool canCollapsePreprocessorAction()
const {
5352 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5353 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5354 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5359 struct JobActionInfo final {
5369 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5371 unsigned ElementNum) {
5372 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5373 for (
unsigned I = 0; I < ElementNum; ++I)
5374 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5375 ActionInfo[I].SavedOffloadAction.end());
5391 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5393 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5394 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5395 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5396 if (!AJ || !BJ || !CJ)
5400 const Tool *
T = TC.SelectTool(*CJ);
5407 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5413 const Tool *BT = TC.SelectTool(*BJ);
5418 if (!
T->hasIntegratedAssembler())
5421 Inputs = CJ->getInputs();
5422 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5429 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5431 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5432 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5437 const Tool *
T = TC.SelectTool(*BJ);
5441 if (!
T->hasIntegratedAssembler())
5444 Inputs = BJ->getInputs();
5445 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5452 if (ActionInfo.size() < 2)
5454 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5455 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5464 bool InputIsBitcode =
true;
5465 for (
size_t i = 1; i < ActionInfo.size(); i++)
5466 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5467 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5468 InputIsBitcode =
false;
5471 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5475 const Tool *
T = TC.SelectTool(*CJ);
5482 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5485 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5488 Inputs = CJ->getInputs();
5489 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5500 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5506 for (
Action *A : Inputs) {
5507 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5508 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5509 NewInputs.push_back(A);
5515 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5516 PreprocessJobOffloadActions.end());
5517 NewInputs.append(PJ->input_begin(), PJ->input_end());
5525 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5527 assert(BaseAction &&
"Invalid base action.");
5544 ActionChain.back().JA = BaseAction;
5545 while (ActionChain.back().JA) {
5546 const Action *CurAction = ActionChain.back().JA;
5549 ActionChain.resize(ActionChain.size() + 1);
5550 JobActionInfo &AI = ActionChain.back();
5554 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5558 ActionChain.pop_back();
5566 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5567 CollapsedOffloadAction);
5569 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5571 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5577 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5589 StringRef BoundArch,
5591 std::string TriplePlusArch = TC->
getTriple().normalize();
5592 if (!BoundArch.empty()) {
5593 TriplePlusArch +=
"-";
5594 TriplePlusArch += BoundArch;
5596 TriplePlusArch +=
"-";
5598 return TriplePlusArch;
5603 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5604 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5607 std::pair<const Action *, std::string> ActionTC = {
5609 auto CachedResult = CachedResults.find(ActionTC);
5610 if (CachedResult != CachedResults.end()) {
5611 return CachedResult->second;
5614 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5615 CachedResults, TargetDeviceOffloadKind);
5616 CachedResults[ActionTC] =
Result;
5621 const JobAction *JA,
const char *BaseInput,
5624 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5628 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5629 Path = A->getValue();
5630 if (llvm::sys::fs::is_directory(
Path)) {
5632 llvm::sys::path::replace_extension(Tmp,
"json");
5633 llvm::sys::path::append(
Path, llvm::sys::path::filename(Tmp));
5636 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5639 Path = DumpDir->getValue();
5640 Path += llvm::sys::path::filename(BaseInput);
5644 llvm::sys::path::replace_extension(
Path,
"json");
5646 const char *ResultFile =
C.getArgs().MakeArgString(
Path);
5647 C.addTimeTraceFile(ResultFile, JA);
5648 C.addResultFile(ResultFile, JA);
5653 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5654 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5657 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5660 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5693 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5695 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5696 const char *DepBoundArch) {
5699 LinkingOutput, CachedResults,
5709 OA->doOnEachDependence(
5710 BuildingForOffloadDevice,
5713 C, DepA, DepTC, DepBoundArch,
false,
5714 !!DepBoundArch, LinkingOutput, CachedResults,
5718 A = BuildingForOffloadDevice
5719 ? OA->getSingleDeviceDependence(
true)
5720 : OA->getHostDependence();
5724 std::pair<const Action *, std::string> ActionTC = {
5725 OA->getHostDependence(),
5727 auto It = CachedResults.find(ActionTC);
5728 if (It != CachedResults.end()) {
5730 Inputs.append(OffloadDependencesInputInfo);
5735 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5738 const Arg &Input = IA->getInputArg();
5740 if (Input.getOption().matches(options::OPT_INPUT)) {
5741 const char *
Name = Input.getValue();
5751 if (!ArchName.empty())
5752 TC = &getToolChain(
C.getArgs(),
5754 C.getArgs(), ArchName));
5756 TC = &
C.getDefaultToolChain();
5759 MultipleArchs, LinkingOutput, CachedResults,
5760 TargetDeviceOffloadKind);
5766 const JobAction *JA = cast<JobAction>(A);
5771 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5778 for (
const auto *OA : CollapsedOffloadActions)
5779 cast<OffloadAction>(OA)->doOnEachDependence(
5780 BuildingForOffloadDevice,
5783 C, DepA, DepTC, DepBoundArch,
false,
5784 !!DepBoundArch, LinkingOutput, CachedResults,
5790 for (
const Action *Input : Inputs) {
5794 bool SubJobAtTopLevel =
5795 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5797 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5802 const char *BaseInput = InputInfos[0].getBaseInput();
5803 for (
auto &Info : InputInfos) {
5804 if (Info.isFilename()) {
5805 BaseInput = Info.getBaseInput();
5812 if (JA->
getType() == types::TY_dSYM)
5813 BaseInput = InputInfos[0].getFilename();
5816 if (!OffloadDependencesInputInfo.empty())
5817 InputInfos.append(OffloadDependencesInputInfo.begin(),
5818 OffloadDependencesInputInfo.end());
5821 llvm::Triple EffectiveTriple;
5823 const ArgList &Args =
5825 if (InputInfos.size() != 1) {
5829 EffectiveTriple = llvm::Triple(
5837 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5841 for (
auto &UI : UA->getDependentActionsInfo()) {
5843 "Unbundling with no offloading??");
5850 UI.DependentOffloadKind,
5851 UI.DependentToolChain->getTriple().normalize(),
5862 UnbundlingResults.push_back(CurI);
5871 Arch = UI.DependentBoundArch;
5876 UI.DependentOffloadKind)}] = {
5882 std::pair<const Action *, std::string> ActionTC = {
5884 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5885 "Result does not exist??");
5886 Result = CachedResults[ActionTC].front();
5887 }
else if (JA->
getType() == types::TY_Nothing)
5894 isa<OffloadPackagerJobAction>(A) ||
5898 AtTopLevel, MultipleArchs,
5901 if (
T->canEmitIR() && OffloadingPrefix.empty())
5906 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5907 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5908 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5909 llvm::errs() << InputInfos[i].getAsString();
5911 llvm::errs() <<
", ";
5913 if (UnbundlingResults.empty())
5914 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5916 llvm::errs() <<
"], outputs: [";
5917 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5918 llvm::errs() << UnbundlingResults[i].getAsString();
5920 llvm::errs() <<
", ";
5922 llvm::errs() <<
"] \n";
5925 if (UnbundlingResults.empty())
5926 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
5928 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
5929 Args, LinkingOutput);
5935 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5936 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5948 if (ArgValue.empty()) {
5951 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
5953 llvm::sys::path::append(
Filename, BaseName);
5956 if (!llvm::sys::path::has_extension(ArgValue)) {
5961 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5966 llvm::sys::path::replace_extension(
Filename, Extension);
5969 return Args.MakeArgString(
Filename.c_str());
5973 if (isa<PreprocessJobAction>(JA))
5975 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
5977 if (isa<OffloadBundlingJobAction>(JA) &&
5984 StringRef Suffix,
bool MultipleArchs,
5985 StringRef BoundArch,
5986 bool NeedUniqueDirectory)
const {
5988 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
5989 std::optional<std::string> CrashDirectory =
5991 ? std::string(A->getValue())
5992 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
5993 if (CrashDirectory) {
5994 if (!
getVFS().exists(*CrashDirectory))
5995 llvm::sys::fs::create_directories(*CrashDirectory);
5997 llvm::sys::path::append(
Path, Prefix);
5998 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
5999 if (std::error_code EC =
6000 llvm::sys::fs::createUniqueFile(
Path + Middle + Suffix, TmpName)) {
6001 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6005 if (MultipleArchs && !BoundArch.empty()) {
6006 if (NeedUniqueDirectory) {
6008 llvm::sys::path::append(TmpName,
6009 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6019 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6034 const char *BaseInput) {
6035 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
6036 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6037 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6042 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6046 const char *BaseInput,
6047 StringRef OrigBoundArch,
bool AtTopLevel,
6049 StringRef OffloadingPrefix)
const {
6050 std::string BoundArch = OrigBoundArch.str();
6051 if (is_style_windows(llvm::sys::path::Style::native)) {
6054 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
6057 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6059 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
6060 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6061 return C.addResultFile(FinalOutput->getValue(), &JA);
6065 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6066 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
6067 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6069 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6070 NameArg = A->getValue();
6071 return C.addResultFile(
6081 if (JA.
getType() == types::TY_ModuleFile &&
6082 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6086 if (JA.
getType() == types::TY_PP_Asm &&
6087 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6088 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6091 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6094 if (JA.
getType() == types::TY_Object &&
6095 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
6096 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6099 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6103 if (JA.
getType() == types::TY_PP_Asm &&
6104 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6105 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6107 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6108 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6109 return C.addResultFile(
6114 if (JA.
getType() == types::TY_API_INFO &&
6115 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6116 C.getArgs().hasArg(options::OPT_o))
6117 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6118 <<
C.getArgs().getLastArgValue(options::OPT_o);
6125 bool SpecifiedModuleOutput =
6126 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6127 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6128 if (MultipleArchs && SpecifiedModuleOutput)
6129 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6133 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
6134 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6135 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
6141 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6143 StringRef
Name = llvm::sys::path::filename(BaseInput);
6144 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6145 const char *Suffix =
6150 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6151 bool NeedUniqueDirectory =
6154 Triple.isOSDarwin();
6155 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6156 NeedUniqueDirectory);
6164 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
6165 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6170 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6171 llvm::sys::path::filename(BasePath));
6172 BaseName = ExternalPath;
6173 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
6174 BaseName = BasePath;
6176 BaseName = llvm::sys::path::filename(BasePath);
6179 const char *NamedOutput;
6181 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6182 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6186 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6190 }
else if (JA.
getType() == types::TY_Image &&
6191 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6192 options::OPT__SLASH_o)) {
6196 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6200 }
else if (JA.
getType() == types::TY_Image) {
6210 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6211 options::OPT_fno_gpu_rdc,
false);
6212 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6213 if (UseOutExtension) {
6215 llvm::sys::path::replace_extension(Output,
"");
6217 Output += OffloadingPrefix;
6218 if (MultipleArchs && !BoundArch.empty()) {
6220 Output.append(BoundArch);
6222 if (UseOutExtension)
6224 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6227 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6228 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6229 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6232 .getLastArg(options::OPT__SLASH_o)
6237 const char *Suffix =
6239 assert(Suffix &&
"All types used for output should have a suffix.");
6241 std::string::size_type End = std::string::npos;
6243 End = BaseName.rfind(
'.');
6245 Suffixed += OffloadingPrefix;
6246 if (MultipleArchs && !BoundArch.empty()) {
6248 Suffixed.append(BoundArch);
6253 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6254 const llvm::opt::DerivedArgList &Args) {
6259 return isa<CompileJobAction>(JA) &&
6261 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6266 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6267 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6268 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6272 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6276 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6277 JA.
getType() != types::TY_PCH) {
6278 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6280 llvm::sys::path::remove_filename(TempPath);
6281 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6282 llvm::sys::path::append(TempPath, OutputFileName);
6283 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6289 bool SameFile =
false;
6291 llvm::sys::fs::current_path(
Result);
6292 llvm::sys::path::append(
Result, BaseName);
6293 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6296 StringRef
Name = llvm::sys::path::filename(BaseInput);
6297 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6301 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6307 llvm::sys::path::remove_filename(BasePath);
6308 if (BasePath.empty())
6309 BasePath = NamedOutput;
6311 llvm::sys::path::append(BasePath, NamedOutput);
6312 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6315 return C.addResultFile(NamedOutput, &JA);
6321 -> std::optional<std::string> {
6324 for (
const auto &
Dir :
P) {
6328 llvm::sys::path::append(
P,
Name);
6329 if (llvm::sys::fs::exists(Twine(
P)))
6330 return std::string(
P);
6332 return std::nullopt;
6339 llvm::sys::path::append(R,
Name);
6340 if (llvm::sys::fs::exists(Twine(R)))
6341 return std::string(R);
6344 llvm::sys::path::append(
P,
Name);
6345 if (llvm::sys::fs::exists(Twine(
P)))
6346 return std::string(
P);
6349 llvm::sys::path::append(
D,
"..",
Name);
6350 if (llvm::sys::fs::exists(Twine(
D)))
6351 return std::string(
D);
6359 return std::string(
Name);
6362void Driver::generatePrefixedToolNames(
6366 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6367 Names.emplace_back(
Tool);
6371 llvm::sys::path::append(Dir, Name);
6372 if (llvm::sys::fs::can_execute(Twine(Dir)))
6374 llvm::sys::path::remove_filename(Dir);
6380 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6385 if (llvm::sys::fs::is_directory(PrefixDir)) {
6388 return std::string(
P);
6391 if (llvm::sys::fs::can_execute(Twine(
P)))
6392 return std::string(
P);
6397 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6405 for (
const auto &
Path : List) {
6408 return std::string(
P);
6412 if (llvm::ErrorOr<std::string>
P =
6413 llvm::sys::findProgramByName(TargetSpecificExecutable))
6417 return std::string(
Name);
6422 std::string error =
"<NOT PRESENT>";
6426 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6443 llvm::sys::path::remove_filename(path);
6444 llvm::sys::path::append(path,
"libc++.modules.json");
6445 if (TC.
getVFS().exists(path))
6446 return static_cast<std::string
>(path);
6451 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6454 return evaluate(
"libc++.a").value_or(error);
6467 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix,
Path);
6469 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6473 return std::string(
Path);
6478 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix,
Path);
6480 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6484 return std::string(
Path);
6489 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6493 Output = FpArg->getValue();
6497 if (!llvm::sys::path::has_extension(Output))
6500 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6501 Output = YcArg->getValue();
6504 llvm::sys::path::replace_extension(Output,
".pch");
6506 return std::string(Output);
6509const ToolChain &Driver::getToolChain(
const ArgList &Args,
6510 const llvm::Triple &
Target)
const {
6512 auto &TC = ToolChains[
Target.str()];
6514 switch (
Target.getOS()) {
6515 case llvm::Triple::AIX:
6516 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6518 case llvm::Triple::Haiku:
6519 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6521 case llvm::Triple::Darwin:
6522 case llvm::Triple::MacOSX:
6523 case llvm::Triple::IOS:
6524 case llvm::Triple::TvOS:
6525 case llvm::Triple::WatchOS:
6526 case llvm::Triple::XROS:
6527 case llvm::Triple::DriverKit:
6528 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6530 case llvm::Triple::DragonFly:
6531 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6533 case llvm::Triple::OpenBSD:
6534 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6536 case llvm::Triple::NetBSD:
6537 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6539 case llvm::Triple::FreeBSD:
6541 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6544 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6546 case llvm::Triple::Linux:
6547 case llvm::Triple::ELFIAMCU:
6548 if (
Target.getArch() == llvm::Triple::hexagon)
6549 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6551 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6552 !
Target.hasEnvironment())
6553 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6556 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6558 else if (
Target.getArch() == llvm::Triple::ve)
6559 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6560 else if (
Target.isOHOSFamily())
6561 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6563 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6565 case llvm::Triple::NaCl:
6566 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6568 case llvm::Triple::Fuchsia:
6569 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6571 case llvm::Triple::Solaris:
6572 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6574 case llvm::Triple::CUDA:
6575 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6577 case llvm::Triple::AMDHSA:
6578 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6580 case llvm::Triple::AMDPAL:
6581 case llvm::Triple::Mesa3D:
6582 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6584 case llvm::Triple::UEFI:
6585 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6587 case llvm::Triple::Win32:
6588 switch (
Target.getEnvironment()) {
6590 if (
Target.isOSBinFormatELF())
6591 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6592 else if (
Target.isOSBinFormatMachO())
6593 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6595 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6597 case llvm::Triple::GNU:
6598 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6600 case llvm::Triple::Itanium:
6601 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6604 case llvm::Triple::MSVC:
6605 case llvm::Triple::UnknownEnvironment:
6606 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6607 .starts_with_insensitive(
"bfd"))
6608 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6612 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6616 case llvm::Triple::PS4:
6617 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6619 case llvm::Triple::PS5:
6620 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6622 case llvm::Triple::Hurd:
6623 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6625 case llvm::Triple::LiteOS:
6626 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6628 case llvm::Triple::ZOS:
6629 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6631 case llvm::Triple::Vulkan:
6632 case llvm::Triple::ShaderModel:
6633 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6638 switch (
Target.getArch()) {
6639 case llvm::Triple::tce:
6640 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6642 case llvm::Triple::tcele:
6643 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6645 case llvm::Triple::hexagon:
6646 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6649 case llvm::Triple::lanai:
6650 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6652 case llvm::Triple::xcore:
6653 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6655 case llvm::Triple::wasm32:
6656 case llvm::Triple::wasm64:
6657 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6659 case llvm::Triple::avr:
6660 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6662 case llvm::Triple::msp430:
6664 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6666 case llvm::Triple::riscv32:
6667 case llvm::Triple::riscv64:
6670 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6672 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6674 case llvm::Triple::ve:
6675 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6677 case llvm::Triple::spirv32:
6678 case llvm::Triple::spirv64:
6679 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6681 case llvm::Triple::csky:
6682 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6686 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6687 else if (
Target.isOSBinFormatELF())
6688 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6689 else if (
Target.isOSBinFormatMachO())
6690 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6692 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6700const ToolChain &Driver::getOffloadingDeviceToolChain(
6701 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6710 switch (TargetDeviceOffloadKind) {
6712 if (((
Target.getArch() == llvm::Triple::amdgcn ||
6713 Target.getArch() == llvm::Triple::spirv64) &&
6714 Target.getVendor() == llvm::Triple::AMD &&
6715 Target.getOS() == llvm::Triple::AMDHSA) ||
6716 !Args.hasArgNoClaim(options::OPT_offload_EQ))
6717 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6719 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6720 Target.getVendor() == llvm::Triple::UnknownVendor &&
6721 Target.getOS() == llvm::Triple::UnknownOS)
6722 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6727 if (
Target.isSPIROrSPIRV())
6728 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, HostTC,
6735 assert(TC &&
"Could not create offloading device tool chain.");
6741 if (JA.
size() != 1 ||
6746 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6747 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6748 !isa<ExtractAPIJobAction>(JA))
6756 if (JA.
size() != 1 ||
6761 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6762 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
6770 if (Args.hasArg(options::OPT_emit_static_lib))
6781 unsigned &Micro,
bool &HadExtra) {
6784 Major = Minor = Micro = 0;
6788 if (Str.consumeInteger(10, Major))
6792 if (!Str.consume_front(
"."))
6795 if (Str.consumeInteger(10, Minor))
6799 if (!Str.consume_front(
"."))
6802 if (Str.consumeInteger(10, Micro))
6820 unsigned CurDigit = 0;
6821 while (CurDigit < Digits.size()) {
6823 if (Str.consumeInteger(10, Digit))
6825 Digits[CurDigit] = Digit;
6828 if (!Str.consume_front(
"."))
6837llvm::opt::Visibility
6838Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6851const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6867 llvm_unreachable(
"Unhandled Mode");
6871 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6876 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6877 options::OPT_fno_save_optimization_record,
false))
6881 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6882 options::OPT_fno_save_optimization_record,
false))
6886 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6887 options::OPT_fno_save_optimization_record,
false))
6891 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6892 options::OPT_fno_save_optimization_record,
false))
6899 static StringRef OptName =
6901 llvm::StringRef Opt;
6902 for (StringRef Arg : Args) {
6903 if (!Arg.starts_with(OptName))
6909 return Opt.consume_front(OptName) ? Opt :
"";
6916 llvm::BumpPtrAllocator &Alloc,
6917 llvm::vfs::FileSystem *FS) {
6926 for (
const char *F : Args) {
6927 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6929 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6930 RSPQuoting = Windows;
6938 llvm::cl::TokenizerCallback Tokenizer;
6940 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6942 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6944 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6947 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6948 ECtx.setMarkEOLs(MarkEOLs);
6952 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
6956 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
6957 [](
const char *A) {
return A !=
nullptr; });
6958 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
6961 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
6962 Args.resize(newEnd - Args.begin());
6966 return llvm::Error::success();
6970 return SavedStrings.insert(S).first->getKeyData();
7003 llvm::StringSet<> &SavedStrings) {
7006 if (Edit[0] ==
'^') {
7007 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7008 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7009 Args.insert(Args.begin() + 1, Str);
7010 }
else if (Edit[0] ==
'+') {
7011 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7012 OS <<
"### Adding argument " << Str <<
" at end\n";
7013 Args.push_back(Str);
7014 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7015 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7016 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7017 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7018 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7020 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7022 if (Args[i] ==
nullptr)
7024 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7026 if (Repl != Args[i]) {
7027 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7031 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7032 auto Option = Edit.substr(1);
7033 for (
unsigned i = 1; i < Args.size();) {
7034 if (Option == Args[i]) {
7035 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7036 Args.erase(Args.begin() + i);
7037 if (Edit[0] ==
'X') {
7038 if (i < Args.size()) {
7039 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7040 Args.erase(Args.begin() + i);
7042 OS <<
"### Invalid X edit, end of command line!\n";
7047 }
else if (Edit[0] ==
'O') {
7048 for (
unsigned i = 1; i < Args.size();) {
7049 const char *A = Args[i];
7053 if (A[0] ==
'-' && A[1] ==
'O' &&
7054 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7055 (
'0' <= A[2] && A[2] <=
'9'))))) {
7056 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7057 Args.erase(Args.begin() + i);
7061 OS <<
"### Adding argument " << Edit <<
" at end\n";
7062 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7064 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7069 const char *OverrideStr,
7070 llvm::StringSet<> &SavedStrings,
7073 OS = &llvm::nulls();
7075 if (OverrideStr[0] ==
'#') {
7077 OS = &llvm::nulls();
7080 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
7084 const char *S = OverrideStr;
7086 const char *End = ::strchr(S,
' ');
7088 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.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
unsigned getOffloadingHostActiveKinds() const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
A class to find a viable CUDA installation.
void WarnIfUnsupportedVersion()
bool isValid() const
Check whether we detected a valid Cuda install.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, Action *HostAction) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
llvm::DenseSet< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain *TC, bool SuppressError=false) const
Returns the set of bound architectures active for this offload kind.
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
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.
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.