55#include "clang/Config/config.h"
67#include "llvm/ADT/ArrayRef.h"
68#include "llvm/ADT/STLExtras.h"
69#include "llvm/ADT/StringExtras.h"
70#include "llvm/ADT/StringRef.h"
71#include "llvm/ADT/StringSet.h"
72#include "llvm/ADT/StringSwitch.h"
73#include "llvm/Config/llvm-config.h"
74#include "llvm/MC/TargetRegistry.h"
75#include "llvm/Option/Arg.h"
76#include "llvm/Option/ArgList.h"
77#include "llvm/Option/OptSpecifier.h"
78#include "llvm/Option/OptTable.h"
79#include "llvm/Option/Option.h"
80#include "llvm/Support/CommandLine.h"
81#include "llvm/Support/ErrorHandling.h"
82#include "llvm/Support/ExitCodes.h"
83#include "llvm/Support/FileSystem.h"
84#include "llvm/Support/FormatVariadic.h"
85#include "llvm/Support/MD5.h"
86#include "llvm/Support/Path.h"
87#include "llvm/Support/PrettyStackTrace.h"
88#include "llvm/Support/Process.h"
89#include "llvm/Support/Program.h"
90#include "llvm/Support/Regex.h"
91#include "llvm/Support/StringSaver.h"
92#include "llvm/Support/VirtualFileSystem.h"
93#include "llvm/Support/raw_ostream.h"
94#include "llvm/TargetParser/Host.h"
95#include "llvm/TargetParser/RISCVISAInfo.h"
107using namespace clang;
111 const ArgList &Args) {
112 auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
116 switch (OffloadTargets.size()) {
118 D.Diag(diag::err_drv_only_one_offload_target_supported);
121 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) <<
"";
126 return llvm::Triple(OffloadTargets[0]);
129static std::optional<llvm::Triple>
131 const llvm::Triple &HostTriple) {
132 if (!Args.hasArg(options::OPT_offload_EQ)) {
133 return llvm::Triple(HostTriple.isArch64Bit() ?
"nvptx64-nvidia-cuda"
134 :
"nvptx-nvidia-cuda");
137 if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
138 TT->getArch() == llvm::Triple::spirv64)) {
139 if (Args.hasArg(options::OPT_emit_llvm))
141 D.Diag(diag::err_drv_cuda_offload_only_emit_bc);
144 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
147static std::optional<llvm::Triple>
149 if (!Args.hasArg(options::OPT_offload_EQ)) {
150 auto OffloadArchs = Args.getAllArgValues(options::OPT_offload_arch_EQ);
151 if (llvm::find(OffloadArchs,
"amdgcnspirv") != OffloadArchs.cend()) {
152 if (OffloadArchs.size() == 1)
153 return llvm::Triple(
"spirv64-amd-amdhsa");
155 D.Diag(diag::err_drv_only_one_offload_target_supported);
158 return llvm::Triple(
"amdgcn-amd-amdhsa");
163 if (TT->getArch() == llvm::Triple::amdgcn &&
164 TT->getVendor() == llvm::Triple::AMD &&
165 TT->getOS() == llvm::Triple::AMDHSA)
167 if (TT->getArch() == llvm::Triple::spirv64)
169 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
175 StringRef CustomResourceDir) {
181 std::string
Dir = std::string(llvm::sys::path::parent_path(BinaryPath));
184 if (CustomResourceDir !=
"") {
185 llvm::sys::path::append(
P, CustomResourceDir);
192 P = llvm::sys::path::parent_path(
Dir);
195 llvm::sys::path::append(
P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
196 CLANG_VERSION_MAJOR_STRING);
199 return std::string(
P);
205 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
206 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
209 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
210 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
211 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
212 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
213 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
214 CheckInputsExist(
true), ProbePrecompiled(
true),
215 SuppressMissingInputWarning(
false) {
218 this->VFS = llvm::vfs::getRealFileSystem();
223 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
226 llvm::sys::path::append(
P,
SysRoot);
230#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
233#if defined(CLANG_CONFIG_FILE_USER_DIR)
236 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
245void Driver::setDriverMode(StringRef
Value) {
246 static StringRef OptName =
247 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
248 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
249 .Case(
"gcc", GCCMode)
250 .Case(
"g++", GXXMode)
251 .Case(
"cpp", CPPMode)
253 .Case(
"flang", FlangMode)
254 .Case(
"dxc", DXCMode)
258 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
262 bool UseDriverMode,
bool &ContainsError) {
263 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
264 ContainsError =
false;
266 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
267 unsigned MissingArgIndex, MissingArgCount;
268 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
269 MissingArgCount, VisibilityMask);
272 if (MissingArgCount) {
273 Diag(diag::err_drv_missing_argument)
274 << Args.getArgString(MissingArgIndex) << MissingArgCount;
281 for (
const Arg *A : Args) {
283 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
291 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
292 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
294 diag::warn_drv_empty_joined_argument,
299 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
301 auto ArgString = A->getAsString(Args);
303 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
305 getOpts().findExact(ArgString, Nearest,
307 DiagID = diag::err_drv_unknown_argument_with_suggestion;
308 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
310 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
311 : diag::err_drv_unknown_argument;
312 Diags.
Report(DiagID) << ArgString;
316 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
317 : diag::err_drv_unknown_argument_with_suggestion;
318 Diags.
Report(DiagID) << ArgString << Nearest;
324 for (
const Arg *A : Args.filtered(options::OPT_o)) {
325 if (ArgStrings[A->getIndex()] == A->getSpelling())
329 std::string ArgString = ArgStrings[A->getIndex()];
331 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
332 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
333 << A->getAsString(Args) << Nearest;
343 Arg **FinalPhaseArg)
const {
344 Arg *PhaseArg =
nullptr;
348 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
349 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
350 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
351 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
358 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
359 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
360 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
361 options::OPT_fmodule_header_EQ))) {
364 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
368 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
369 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
370 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
371 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
372 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
373 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
374 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
378 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
382 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
385 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
393 *FinalPhaseArg = PhaseArg;
399 StringRef
Value,
bool Claim =
true) {
400 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
401 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
402 Args.AddSynthesizedArg(A);
408DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
409 const llvm::opt::OptTable &Opts =
getOpts();
410 DerivedArgList *DAL =
new DerivedArgList(Args);
412 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
413 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
414 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
415 bool IgnoreUnused =
false;
416 for (Arg *A : Args) {
420 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
424 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
425 IgnoreUnused =
false;
435 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
436 A->getOption().matches(options::OPT_Xlinker)) &&
437 A->containsValue(
"--no-demangle")) {
439 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
442 for (StringRef Val : A->getValues())
443 if (Val !=
"--no-demangle")
444 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
452 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
453 (A->getValue(0) == StringRef(
"-MD") ||
454 A->getValue(0) == StringRef(
"-MMD"))) {
456 if (A->getValue(0) == StringRef(
"-MD"))
457 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
459 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
460 if (A->getNumValues() == 2)
461 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
466 if (A->getOption().matches(options::OPT_l)) {
467 StringRef
Value = A->getValue();
470 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
472 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
477 if (
Value ==
"cc_kext") {
478 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
484 if (A->getOption().matches(options::OPT__DASH_DASH)) {
486 for (StringRef Val : A->getValues())
495 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
496 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
499 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
500 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
504#if defined(HOST_LINK_VERSION)
505 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
506 strlen(HOST_LINK_VERSION) > 0) {
507 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
509 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
521 StringRef TargetTriple,
523 StringRef DarwinArchName =
"") {
525 if (
const Arg *A = Args.getLastArg(options::OPT_target))
526 TargetTriple = A->getValue();
528 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
533 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
537 if (
Target.isOSBinFormatMachO()) {
539 if (!DarwinArchName.empty()) {
546 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
547 StringRef ArchName = A->getValue();
554 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
555 options::OPT_mbig_endian)) {
556 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
557 ?
Target.getLittleEndianArchVariant()
558 :
Target.getBigEndianArchVariant();
559 if (
T.getArch() != llvm::Triple::UnknownArch) {
561 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
566 if (
Target.getArch() == llvm::Triple::tce)
571 if (std::optional<std::string> ObjectModeValue =
572 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
573 StringRef ObjectMode = *ObjectModeValue;
574 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
576 if (ObjectMode ==
"64") {
577 AT =
Target.get64BitArchVariant().getArch();
578 }
else if (ObjectMode ==
"32") {
579 AT =
Target.get32BitArchVariant().getArch();
581 D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
584 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
590 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
592 D.Diag(diag::err_drv_unsupported_opt_for_target)
593 << A->getAsString(Args) <<
Target.str();
596 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
597 options::OPT_m32, options::OPT_m16,
598 options::OPT_maix32, options::OPT_maix64);
600 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
602 if (A->getOption().matches(options::OPT_m64) ||
603 A->getOption().matches(options::OPT_maix64)) {
604 AT =
Target.get64BitArchVariant().getArch();
605 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
606 Target.setEnvironment(llvm::Triple::GNU);
607 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
608 Target.setEnvironment(llvm::Triple::Musl);
609 }
else if (A->getOption().matches(options::OPT_mx32) &&
610 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
611 AT = llvm::Triple::x86_64;
612 if (
Target.getEnvironment() == llvm::Triple::Musl)
613 Target.setEnvironment(llvm::Triple::MuslX32);
615 Target.setEnvironment(llvm::Triple::GNUX32);
616 }
else if (A->getOption().matches(options::OPT_m32) ||
617 A->getOption().matches(options::OPT_maix32)) {
618 AT =
Target.get32BitArchVariant().getArch();
619 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
620 Target.setEnvironment(llvm::Triple::GNU);
621 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
622 Target.setEnvironment(llvm::Triple::Musl);
623 }
else if (A->getOption().matches(options::OPT_m16) &&
624 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
625 AT = llvm::Triple::x86;
626 Target.setEnvironment(llvm::Triple::CODE16);
629 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
631 if (
Target.isWindowsGNUEnvironment())
637 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
638 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
639 D.Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
642 if (A && !A->getOption().matches(options::OPT_m32))
643 D.Diag(diag::err_drv_argument_not_allowed_with)
644 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
646 Target.setArch(llvm::Triple::x86);
647 Target.setArchName(
"i586");
648 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
649 Target.setEnvironmentName(
"");
650 Target.setOS(llvm::Triple::ELFIAMCU);
651 Target.setVendor(llvm::Triple::UnknownVendor);
652 Target.setVendorName(
"intel");
658 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
659 StringRef ABIName = A->getValue();
660 if (ABIName ==
"32") {
662 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
663 Target.getEnvironment() == llvm::Triple::GNUABIN32)
664 Target.setEnvironment(llvm::Triple::GNU);
665 }
else if (ABIName ==
"n32") {
667 if (
Target.getEnvironment() == llvm::Triple::GNU ||
668 Target.getEnvironment() == llvm::Triple::GNUABI64)
669 Target.setEnvironment(llvm::Triple::GNUABIN32);
670 }
else if (ABIName ==
"64") {
672 if (
Target.getEnvironment() == llvm::Triple::GNU ||
673 Target.getEnvironment() == llvm::Triple::GNUABIN32)
674 Target.setEnvironment(llvm::Triple::GNUABI64);
682 if (Args.hasArg(options::OPT_march_EQ) ||
683 Args.hasArg(options::OPT_mcpu_EQ)) {
685 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
687 if (!llvm::errorToBool(ISAInfo.takeError())) {
688 unsigned XLen = (*ISAInfo)->getXLen();
690 Target.setArch(llvm::Triple::riscv32);
692 Target.setArch(llvm::Triple::riscv64);
704 OptSpecifier OptEq, OptSpecifier OptNeg) {
705 if (!Args.hasFlag(OptEq, OptNeg,
false))
708 const Arg *A = Args.getLastArg(OptEq);
709 StringRef LTOName = A->getValue();
717 D.Diag(diag::err_drv_unsupported_option_argument)
718 << A->getSpelling() << A->getValue();
725void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
727 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
729 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
730 options::OPT_fno_offload_lto);
733 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
734 options::OPT_fno_openmp_target_jit,
false)) {
735 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
736 options::OPT_fno_offload_lto))
738 Diag(diag::err_drv_incompatible_options)
739 << A->getSpelling() <<
"-fopenmp-target-jit";
746 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
748 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
750 RuntimeName = A->getValue();
752 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
760 Diag(diag::err_drv_unsupported_option_argument)
761 << A->getSpelling() << A->getValue();
764 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
779 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
784 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
787 C.getInputArgs().hasArg(options::OPT_hip_link) ||
788 C.getInputArgs().hasArg(options::OPT_hipstdpar);
789 if (IsCuda && IsHIP) {
790 Diag(clang::diag::err_drv_mix_cuda_hip);
795 const llvm::Triple &HostTriple = HostTC->
getTriple();
803 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
805 CudaTC = std::make_unique<toolchains::CudaToolChain>(
806 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
811 if (CudaInstallation.
isValid())
814 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
816 if (
auto *OMPTargetArg =
817 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
818 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
819 << OMPTargetArg->getSpelling() <<
"HIP";
827 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
829 assert(HIPTC &&
"Could not create offloading device tool chain.");
830 C.addOffloadDeviceToolChain(HIPTC, OFK);
838 bool IsOpenMPOffloading =
839 C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
840 options::OPT_fno_openmp,
false) &&
841 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
842 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ));
843 if (IsOpenMPOffloading) {
849 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
853 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
854 llvm::StringMap<StringRef> FoundNormalizedTriples;
855 std::multiset<StringRef> OpenMPTriples;
860 if (Arg *OpenMPTargets =
861 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
862 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
863 Diag(clang::diag::warn_drv_empty_joined_argument)
864 << OpenMPTargets->getAsString(
C.getInputArgs());
867 for (StringRef
T : OpenMPTargets->getValues())
868 OpenMPTriples.insert(
T);
869 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
882 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
883 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
889 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
890 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
895 if (!AMDTriple && !NVPTXTriple) {
896 for (StringRef Arch :
901 for (StringRef Arch : Archs) {
904 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
905 }
else if (AMDTriple &&
908 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
910 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
917 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
922 for (
const auto &TripleAndArchs : DerivedArchs)
923 OpenMPTriples.insert(TripleAndArchs.first());
926 for (StringRef Val : OpenMPTriples) {
928 std::string NormalizedName = TT.normalize();
931 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
932 if (Duplicate != FoundNormalizedTriples.end()) {
933 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
934 << Val << Duplicate->second;
940 FoundNormalizedTriples[NormalizedName] = Val;
943 if (TT.getArch() == llvm::Triple::UnknownArch)
944 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
949 if (TT.isNVPTX() || TT.isAMDGCN()) {
952 assert(HostTC &&
"Host toolchain should be always defined.");
954 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
957 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
958 *
this, TT, *HostTC,
C.getInputArgs());
959 else if (TT.isAMDGCN())
960 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
961 *
this, TT, *HostTC,
C.getInputArgs());
963 assert(DeviceTC &&
"Device toolchain not defined.");
968 TC = &getToolChain(
C.getInputArgs(), TT);
970 if (DerivedArchs.contains(TT.getTriple()))
971 KnownArchs[TC] = DerivedArchs[TT.getTriple()];
974 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
975 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
985 const Arg *BaseArg) {
989 unsigned Index = Args.MakeIndex(Opt->getSpelling());
990 Arg *
Copy =
new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index),
992 Copy->getValues() = Opt->getValues();
993 if (Opt->isClaimed())
995 Copy->setOwnsValues(Opt->getOwnsValues());
996 Opt->setOwnsValues(
false);
1000bool Driver::readConfigFile(StringRef
FileName,
1001 llvm::cl::ExpansionContext &ExpCtx) {
1005 Diag(diag::err_drv_cannot_open_config_file)
1006 <<
FileName << Status.getError().message();
1009 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1010 Diag(diag::err_drv_cannot_open_config_file)
1011 <<
FileName <<
"not a regular file";
1017 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgArgs)) {
1018 Diag(diag::err_drv_cannot_read_config_file)
1025 llvm::sys::path::native(CfgFileName);
1027 std::unique_ptr<InputArgList> NewOptions = std::make_unique<InputArgList>(
1034 for (Arg *A : *NewOptions)
1038 CfgOptions = std::move(NewOptions);
1041 for (
auto *Opt : *NewOptions) {
1042 const Arg *BaseArg = &Opt->getBaseArg();
1048 ConfigFiles.push_back(std::string(CfgFileName));
1052bool Driver::loadConfigFiles() {
1053 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1054 llvm::cl::tokenizeConfigFile);
1055 ExpCtx.setVFS(&
getVFS());
1059 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1062 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1063 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1068 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1070 llvm::sys::fs::expand_tilde(
1071 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1072 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1081 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1084 if (loadDefaultConfigFiles(ExpCtx))
1090 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1093 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1094 CfgFilePath.assign(CfgFileName);
1095 if (llvm::sys::path::is_relative(CfgFilePath)) {
1096 if (
getVFS().makeAbsolute(CfgFilePath)) {
1097 Diag(diag::err_drv_cannot_open_config_file)
1098 << CfgFilePath <<
"cannot get absolute path";
1102 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1104 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1105 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1106 if (!SearchDir.empty())
1107 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1112 if (readConfigFile(CfgFilePath, ExpCtx))
1121bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1124 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1128 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1131 std::string RealMode = getExecutableForDriverMode(Mode);
1141 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1142 PrefixTriple.isOSUnknown())
1143 Triple = PrefixTriple.str();
1147 if (Triple.empty()) {
1148 llvm::Triple RealTriple =
1150 Triple = RealTriple.str();
1151 assert(!Triple.empty());
1166 std::string CfgFileName = Triple +
'-' + RealMode +
".cfg";
1167 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1168 return readConfigFile(CfgFilePath, ExpCtx);
1172 if (TryModeSuffix) {
1174 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1175 return readConfigFile(CfgFilePath, ExpCtx);
1180 CfgFileName = RealMode +
".cfg";
1181 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1182 if (readConfigFile(CfgFilePath, ExpCtx))
1184 }
else if (TryModeSuffix) {
1186 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1187 readConfigFile(CfgFilePath, ExpCtx))
1192 CfgFileName = Triple +
".cfg";
1193 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath))
1194 return readConfigFile(CfgFilePath, ExpCtx);
1202 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1211 if (!DriverMode.empty())
1212 setDriverMode(DriverMode);
1218 CLOptions = std::make_unique<InputArgList>(
1223 ContainsError = loadConfigFiles();
1224 bool HasConfigFile = !ContainsError && (CfgOptions.get() !=
nullptr);
1227 InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
1228 : std::move(*CLOptions));
1231 for (
auto *Opt : *CLOptions) {
1232 if (Opt->getOption().matches(options::OPT_config))
1234 const Arg *BaseArg = &Opt->getBaseArg();
1241 if (
IsCLMode() && !ContainsError) {
1243 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1245 CLModePassThroughArgList.push_back(A->getValue());
1248 if (!CLModePassThroughArgList.empty()) {
1251 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1256 for (
auto *Opt : *CLModePassThroughOptions) {
1263 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1264 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1265 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1269 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1270 if (!VFS->exists(IncludeDir))
1271 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1276 bool CCCPrintPhases;
1279 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1280 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1283 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1284 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1287 Args.ClaimAllArgs(options::OPT_pipe);
1295 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1297 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1298 CCCGenericGCCName = A->getValue();
1301 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1305 if (Args.hasArg(options::OPT_fproc_stat_report))
1312 llvm::Triple
T(TargetTriple);
1313 T.setOS(llvm::Triple::Win32);
1314 T.setVendor(llvm::Triple::PC);
1315 T.setEnvironment(llvm::Triple::MSVC);
1316 T.setObjectFormat(llvm::Triple::COFF);
1317 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1318 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1319 TargetTriple =
T.str();
1322 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1323 StringRef TargetProfile = A->getValue();
1326 TargetTriple = *Triple;
1328 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1332 if (Args.hasArg(options::OPT_spirv)) {
1333 llvm::Triple
T(TargetTriple);
1334 T.setArch(llvm::Triple::spirv);
1335 T.setOS(llvm::Triple::Vulkan);
1338 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1339 const llvm::StringSet<> ValidValues = {
"vulkan1.2",
"vulkan1.3"};
1340 if (ValidValues.contains(A->getValue())) {
1341 T.setOSName(A->getValue());
1343 Diag(diag::err_drv_invalid_value)
1344 << A->getAsString(Args) << A->getValue();
1349 TargetTriple =
T.str();
1352 Diag(diag::err_drv_dxc_missing_target_profile);
1356 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1357 TargetTriple = A->getValue();
1358 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1359 Dir =
Dir = A->getValue();
1360 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1364 if (std::optional<std::string> CompilerPathValue =
1365 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1366 StringRef CompilerPath = *CompilerPathValue;
1367 while (!CompilerPath.empty()) {
1368 std::pair<StringRef, StringRef> Split =
1369 CompilerPath.split(llvm::sys::EnvPathSeparator);
1370 PrefixDirs.push_back(std::string(Split.first));
1371 CompilerPath = Split.second;
1374 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1376 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1379 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1382 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1383 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1384 .Case(
"cwd", SaveTempsCwd)
1385 .Case(
"obj", SaveTempsObj)
1386 .Default(SaveTempsCwd);
1389 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1390 options::OPT_offload_device_only,
1391 options::OPT_offload_host_device)) {
1392 if (A->getOption().matches(options::OPT_offload_host_only))
1393 Offload = OffloadHost;
1394 else if (A->getOption().matches(options::OPT_offload_device_only))
1395 Offload = OffloadDevice;
1397 Offload = OffloadHostDevice;
1403 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1404 StringRef
Name = A->getValue();
1405 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1406 .Case(
"off", EmbedNone)
1407 .Case(
"all", EmbedBitcode)
1408 .Case(
"bitcode", EmbedBitcode)
1409 .Case(
"marker", EmbedMarker)
1412 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1415 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1419 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1420 llvm::sys::fs::remove(A->getValue());
1426 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1428 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1429 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1430 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1431 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1432 Std->containsValue(
"c++latest"));
1435 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1436 options::OPT_fmodule_header)) {
1438 ModulesModeCXX20 =
true;
1439 if (A->getOption().matches(options::OPT_fmodule_header))
1442 StringRef ArgName = A->getValue();
1443 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1448 Diags.
Report(diag::err_drv_invalid_value)
1449 << A->getAsString(Args) << ArgName;
1455 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1456 std::make_unique<InputArgList>(std::move(Args));
1459 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1467 if (!Triple.isWasm()) {
1468 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1469 StringRef TripleObjectFormat =
1470 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1471 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1472 TripleVersionName != TripleObjectFormat) {
1473 Diags.
Report(diag::err_drv_triple_version_invalid)
1475 ContainsError =
true;
1480 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1481 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1482 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1490 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1491 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1493 case llvm::Triple::arm:
1494 case llvm::Triple::armeb:
1495 case llvm::Triple::thumb:
1496 case llvm::Triple::thumbeb:
1497 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1498 Diag(diag::warn_target_unrecognized_env)
1500 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1503 case llvm::Triple::aarch64:
1504 case llvm::Triple::aarch64_be:
1505 case llvm::Triple::aarch64_32:
1506 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1507 Diag(diag::warn_target_unrecognized_env)
1509 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1526 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1533 if (TC.
getTriple().isOSBinFormatMachO())
1538 if (CCCPrintPhases) {
1549 llvm::opt::ArgStringList ASL;
1550 for (
const auto *A : Args) {
1554 while (A->getAlias())
1556 A->render(Args, ASL);
1559 for (
auto I = ASL.begin(),
E = ASL.end(); I !=
E; ++I) {
1560 if (I != ASL.begin())
1562 llvm::sys::printArg(OS, *I,
true);
1567bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1569 using namespace llvm::sys;
1570 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1571 "Only knows about .crash files on Darwin");
1576 path::home_directory(CrashDiagDir);
1577 if (CrashDiagDir.starts_with(
"/var/root"))
1579 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1587 fs::file_status FileStatus;
1588 TimePoint<> LastAccessTime;
1592 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1593 File != FileEnd && !EC;
File.increment(EC)) {
1597 if (fs::status(
File->path(), FileStatus))
1599 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1600 llvm::MemoryBuffer::getFile(
File->path());
1605 StringRef
Data = CrashFile.get()->getBuffer();
1606 if (!
Data.starts_with(
"Process:"))
1609 size_t ParentProcPos =
Data.find(
"Parent Process:");
1610 if (ParentProcPos == StringRef::npos)
1612 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1613 if (LineEnd == StringRef::npos)
1615 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1616 int OpenBracket = -1, CloseBracket = -1;
1617 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1618 if (ParentProcess[i] ==
'[')
1620 if (ParentProcess[i] ==
']')
1626 if (OpenBracket < 0 || CloseBracket < 0 ||
1627 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1628 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1638 const auto FileAccessTime = FileStatus.getLastModificationTime();
1639 if (FileAccessTime > LastAccessTime) {
1640 CrashFilePath.assign(
File->path());
1641 LastAccessTime = FileAccessTime;
1646 if (!CrashFilePath.empty()) {
1647 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1657 "\n********************\n\n"
1658 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1659 "Preprocessed source(s) and associated run script(s) are located at:";
1667 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1671 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1672 Level = llvm::StringSwitch<unsigned>(A->getValue())
1674 .Case(
"compiler", 1)
1686 ArgStringList SavedTemps;
1688 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1689 if (!IsLLD || Level < 2)
1696 SavedTemps = std::move(
C.getTempFiles());
1697 assert(!
C.getTempFiles().size());
1714 C.initCompilationForDiagnostics();
1720 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1721 StringRef ReproduceOption =
1722 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1725 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1729 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1731 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1732 Diag(clang::diag::note_drv_command_failed_diag_msg)
1733 <<
"\n\n********************";
1743 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1744 bool IgnoreInput =
false;
1750 }
else if (!strcmp(it->second->getValue(),
"-")) {
1751 Diag(clang::diag::note_drv_command_failed_diag_msg)
1752 <<
"Error generating preprocessed source(s) - "
1753 "ignoring input from stdin.";
1758 it = Inputs.erase(it);
1765 if (Inputs.empty()) {
1766 Diag(clang::diag::note_drv_command_failed_diag_msg)
1767 <<
"Error generating preprocessed source(s) - "
1768 "no preprocessable inputs.";
1774 llvm::StringSet<> ArchNames;
1775 for (
const Arg *A :
C.getArgs()) {
1776 if (A->getOption().matches(options::OPT_arch)) {
1777 StringRef ArchName = A->getValue();
1778 ArchNames.insert(ArchName);
1781 if (ArchNames.size() > 1) {
1782 Diag(clang::diag::note_drv_command_failed_diag_msg)
1783 <<
"Error generating preprocessed source(s) - cannot generate "
1784 "preprocessed source with multiple -arch options.";
1790 const ToolChain &TC =
C.getDefaultToolChain();
1791 if (TC.
getTriple().isOSBinFormatMachO())
1800 Diag(clang::diag::note_drv_command_failed_diag_msg)
1801 <<
"Error generating preprocessed source(s).";
1807 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1810 if (!FailingCommands.empty()) {
1811 Diag(clang::diag::note_drv_command_failed_diag_msg)
1812 <<
"Error generating preprocessed source(s).";
1816 const ArgStringList &TempFiles =
C.getTempFiles();
1817 if (TempFiles.empty()) {
1818 Diag(clang::diag::note_drv_command_failed_diag_msg)
1819 <<
"Error generating preprocessed source(s).";
1827 for (
const char *TempFile : TempFiles) {
1828 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
1831 if (ReproCrashFilename.empty()) {
1832 ReproCrashFilename = TempFile;
1833 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
1835 if (StringRef(TempFile).ends_with(
".cache")) {
1838 VFS = llvm::sys::path::filename(TempFile);
1839 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
1843 for (
const char *TempFile : SavedTemps)
1844 C.addTempFile(TempFile);
1850 llvm::sys::path::replace_extension(Script,
"sh");
1852 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
1853 llvm::sys::fs::FA_Write,
1854 llvm::sys::fs::OF_Text);
1856 Diag(clang::diag::note_drv_command_failed_diag_msg)
1857 <<
"Error generating run script: " << Script <<
" " << EC.message();
1860 <<
"# Driver args: ";
1862 ScriptOS <<
"# Original command: ";
1863 Cmd.Print(ScriptOS,
"\n",
true);
1864 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
1865 if (!AdditionalInformation.empty())
1866 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
1870 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
1874 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
1876 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
1877 Diag(clang::diag::note_drv_command_failed_diag_msg)
1878 << ReproCrashFilename.str();
1880 llvm::sys::path::append(CrashDiagDir,
Name);
1881 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
1882 Diag(clang::diag::note_drv_command_failed_diag_msg)
1883 <<
"Crash backtrace is located in";
1884 Diag(clang::diag::note_drv_command_failed_diag_msg)
1885 << CrashDiagDir.str();
1886 Diag(clang::diag::note_drv_command_failed_diag_msg)
1887 <<
"(choose the .crash file that corresponds to your crash)";
1891 Diag(clang::diag::note_drv_command_failed_diag_msg)
1892 <<
"\n\n********************";
1900 if (
Cmd.getResponseFileSupport().ResponseKind ==
1902 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
1903 Cmd.getArguments()))
1907 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
1913 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
1914 if (
C.getArgs().hasArg(options::OPT_v))
1915 C.getJobs().Print(llvm::errs(),
"\n",
true);
1917 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
1927 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
1928 C.getJobs().Print(llvm::errs(),
"\n",
true);
1937 for (
auto &Job :
C.getJobs())
1938 setUpResponseFiles(
C, Job);
1940 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1943 if (FailingCommands.empty())
1949 for (
const auto &CmdPair : FailingCommands) {
1950 int CommandRes = CmdPair.first;
1951 const Command *FailingCommand = CmdPair.second;
1956 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
1960 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
1965 if (CommandRes == EX_IOERR) {
1982 Diag(clang::diag::err_drv_command_signalled)
1985 Diag(clang::diag::err_drv_command_failed)
1993 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
1995 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2009 const ToolChain &TC =
C.getDefaultToolChain();
2013 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2016 OS <<
"Thread model: " << A->getValue();
2022 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2027 if (!llvm::cl::getCompilerBuildConfig().empty())
2028 llvm::cl::printBuildConfig(OS);
2031 for (
auto ConfigFile : ConfigFiles)
2032 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2045 if (PassedFlags ==
"")
2049 std::vector<std::string> SuggestedCompletions;
2050 std::vector<std::string> Flags;
2062 const bool HasSpace = PassedFlags.ends_with(
",");
2066 StringRef TargetFlags = PassedFlags;
2067 while (TargetFlags !=
"") {
2069 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2070 Flags.push_back(std::string(CurFlag));
2075 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2078 const llvm::opt::OptTable &Opts =
getOpts();
2080 Cur = Flags.at(Flags.size() - 1);
2082 if (Flags.size() >= 2) {
2083 Prev = Flags.at(Flags.size() - 2);
2084 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2087 if (SuggestedCompletions.empty())
2088 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2095 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2096 llvm::outs() <<
'\n';
2102 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2106 SuggestedCompletions = Opts.findByPrefix(
2107 Cur, VisibilityMask,
2114 if (S.starts_with(Cur))
2115 SuggestedCompletions.push_back(std::string(S));
2122 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2123 if (
int X = A.compare_insensitive(B))
2125 return A.compare(B) > 0;
2128 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2135 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2136 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2140 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2143 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2147 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2152 if (
C.getArgs().hasArg(options::OPT_help) ||
2153 C.getArgs().hasArg(options::OPT__help_hidden)) {
2154 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2158 if (
C.getArgs().hasArg(options::OPT__version)) {
2164 if (
C.getArgs().hasArg(options::OPT_v) ||
2165 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2166 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2167 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2168 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2170 SuppressMissingInputWarning =
true;
2173 if (
C.getArgs().hasArg(options::OPT_v)) {
2175 llvm::errs() <<
"System configuration file directory: "
2178 llvm::errs() <<
"User configuration file directory: "
2182 const ToolChain &TC =
C.getDefaultToolChain();
2184 if (
C.getArgs().hasArg(options::OPT_v))
2187 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2192 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2193 llvm::outs() <<
"programs: =";
2194 bool separator =
false;
2198 llvm::outs() << llvm::sys::EnvPathSeparator;
2199 llvm::outs() <<
Path;
2204 llvm::outs() << llvm::sys::EnvPathSeparator;
2205 llvm::outs() <<
Path;
2208 llvm::outs() <<
"\n";
2211 StringRef sysroot =
C.getSysRoot();
2215 llvm::outs() << llvm::sys::EnvPathSeparator;
2218 llvm::outs() << sysroot <<
Path.substr(1);
2220 llvm::outs() <<
Path;
2222 llvm::outs() <<
"\n";
2226 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2232 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2233 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2234 llvm::outs() << *RuntimePath <<
'\n';
2240 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2242 for (std::size_t I = 0; I != Flags.size(); I += 2)
2243 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2249 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2250 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2254 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2255 StringRef ProgName = A->getValue();
2258 if (! ProgName.empty())
2261 llvm::outs() <<
"\n";
2265 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2266 StringRef PassedFlags = A->getValue();
2271 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2285 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2288 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2294 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2300 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2303 std::set<llvm::StringRef> SortedFlags;
2304 for (
const auto &FlagEntry : ExpandedFlags)
2305 SortedFlags.insert(FlagEntry.getKey());
2306 for (
auto Flag : SortedFlags)
2307 llvm::outs() << Flag <<
'\n';
2311 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2314 llvm::outs() <<
".\n";
2317 assert(Suffix.front() ==
'/');
2318 llvm::outs() << Suffix.substr(1) <<
"\n";
2324 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2329 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2331 llvm::outs() << Triple.getTriple() <<
"\n";
2335 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2336 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2353 std::map<Action *, unsigned> &Ids,
2359 llvm::raw_string_ostream os(str);
2361 auto getSibIndent = [](
int K) -> Twine {
2365 Twine SibIndent = Indent + getSibIndent(Kind);
2369 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2371 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2372 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2373 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2374 bool IsFirst =
true;
2375 OA->doOnEachDependence(
2377 assert(TC &&
"Unknown host toolchain");
2389 os <<
":" << BoundArch;
2392 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2400 const char *Prefix =
"{";
2401 for (
Action *PreRequisite : *AL) {
2402 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2413 std::string offload_str;
2414 llvm::raw_string_ostream offload_os(offload_str);
2415 if (!isa<OffloadAction>(A)) {
2418 offload_os <<
", (" << S;
2425 auto getSelfIndent = [](
int K) -> Twine {
2429 unsigned Id = Ids.size();
2431 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2440 std::map<Action *, unsigned> Ids;
2441 for (
Action *A :
C.getActions())
2448 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2449 isa<AssembleJobAction>(A))
2457 DerivedArgList &Args =
C.getArgs();
2459 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2462 llvm::StringSet<> ArchNames;
2464 for (Arg *A : Args) {
2465 if (A->getOption().matches(options::OPT_arch)) {
2468 llvm::Triple::ArchType Arch =
2470 if (Arch == llvm::Triple::UnknownArch) {
2471 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2476 if (ArchNames.insert(A->getValue()).second)
2477 Archs.push_back(A->getValue());
2491 for (
Action* Act : SingleActions) {
2499 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2503 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2508 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2509 Actions.append(Inputs.begin(), Inputs.end());
2511 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2514 Arg *A = Args.getLastArg(options::OPT_g_Group);
2515 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2516 !A->getOption().matches(options::OPT_gstabs);
2524 if (Act->getType() == types::TY_Image) {
2526 Inputs.push_back(Actions.back());
2533 if (Args.hasArg(options::OPT_verify_debug_info)) {
2534 Action* LastAction = Actions.back();
2537 LastAction, types::TY_Nothing));
2556 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2557 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2569 std::string Nearest;
2570 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2571 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2572 <<
Value << Nearest;
2611 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2614 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2622 return types::TY_CXXUHeader;
2624 return types::TY_CXXSHeader;
2628 llvm_unreachable(
"should not be called in this case");
2630 return types::TY_CXXHUHeader;
2636 const llvm::opt::OptTable &Opts =
getOpts();
2640 types::ID InputType = types::TY_Nothing;
2641 Arg *InputTypeArg =
nullptr;
2644 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2645 options::OPT__SLASH_TP)) {
2646 InputTypeArg = TCTP;
2647 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2652 bool ShowNote =
false;
2654 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2656 Diag(clang::diag::warn_drv_overriding_option)
2657 <<
Previous->getSpelling() << A->getSpelling();
2663 Diag(clang::diag::note_drv_t_option_is_global);
2668 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2669 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2670 if (LastXArg && LastInputArg &&
2671 LastInputArg->getIndex() < LastXArg->getIndex())
2672 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2675 for (Arg *A : Args) {
2676 if (A->getOption().
getKind() == Option::InputClass) {
2677 const char *
Value = A->getValue();
2681 if (InputType == types::TY_Nothing) {
2684 InputTypeArg->claim();
2687 if (memcmp(
Value,
"-", 2) == 0) {
2689 Ty = types::TY_Fortran;
2691 Ty = types::TY_HLSL;
2700 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2701 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2702 : clang::diag::err_drv_unknown_stdin_type);
2711 if (
const char *Ext = strrchr(
Value,
'.'))
2720 Ty = types::TY_Object;
2731 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2732 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2733 << getTypeName(OldTy) << getTypeName(Ty);
2738 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2739 Ty == types::TY_Object)
2740 Ty = types::TY_LLVM_BC;
2748 if (Ty != types::TY_Object) {
2749 if (Args.hasArg(options::OPT_ObjC))
2750 Ty = types::TY_ObjC;
2751 else if (Args.hasArg(options::OPT_ObjCXX))
2752 Ty = types::TY_ObjCXX;
2759 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
2763 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2764 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2767 const char *Ext = strrchr(
Value,
'.');
2769 Ty = types::TY_Object;
2773 InputTypeArg->claim();
2777 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
2778 Args.hasArgNoClaim(options::OPT_hipstdpar))
2782 Inputs.push_back(std::make_pair(Ty, A));
2784 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2785 StringRef
Value = A->getValue();
2788 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2789 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2792 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2793 StringRef
Value = A->getValue();
2796 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2797 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2803 Inputs.push_back(std::make_pair(types::TY_Object, A));
2805 }
else if (A->getOption().matches(options::OPT_x)) {
2814 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2815 InputType = types::TY_Object;
2822 }
else if (A->getOption().getID() == options::OPT_U) {
2823 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
2824 StringRef Val = A->getValue(0);
2825 if (Val.find_first_of(
"/\\") != StringRef::npos) {
2827 Diag(diag::warn_slash_u_filename) << Val;
2828 Diag(diag::note_use_dashdash);
2832 if (
CCCIsCPP() && Inputs.empty()) {
2836 Inputs.push_back(std::make_pair(types::TY_C, A));
2843class OffloadingActionBuilder final {
2845 bool IsValid =
false;
2851 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
2854 std::map<Action *, const Arg *> HostActionToInputArgMap;
2857 class DeviceActionBuilder {
2861 enum ActionBuilderReturnCode {
2880 DerivedArgList &Args;
2889 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
2892 :
C(
C), Args(Args), Inputs(Inputs),
2893 AssociatedOffloadKind(AssociatedOffloadKind) {}
2894 virtual ~DeviceActionBuilder() {}
2899 virtual ActionBuilderReturnCode
2903 return ABRT_Inactive;
2908 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
2909 return ABRT_Inactive;
2913 virtual void appendTopLevelActions(
ActionList &AL) {}
2916 virtual void appendLinkDeviceActions(
ActionList &AL) {}
2929 virtual bool canUseBundlerUnbundler()
const {
return false; }
2933 bool isValid() {
return !ToolChains.empty(); }
2937 return AssociatedOffloadKind;
2943 class CudaActionBuilderBase :
public DeviceActionBuilder {
2947 bool CompileHostOnly =
false;
2948 bool CompileDeviceOnly =
false;
2950 bool EmitAsm =
false;
2960 TargetID(
const char *
ID) :
ID(
ID) {}
2961 operator const char *() {
return ID; }
2962 operator StringRef() {
return StringRef(
ID); }
2971 Action *CudaFatBinary =
nullptr;
2974 bool IsActive =
false;
2977 bool Relocatable =
false;
2980 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
2984 enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
2985 UseCUIDKind UseCUID = CUID_Hash;
2988 StringRef FixedCUID;
2991 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
2994 : DeviceActionBuilder(
C, Args, Inputs, OFKind) {
2996 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
2997 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
2998 options::OPT_fno_gpu_rdc,
false);
3001 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3008 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3009 assert(!GpuArchList.empty() &&
3010 "We should have at least one GPU architecture.");
3014 if (!(IA->getType() == types::TY_CUDA ||
3015 IA->getType() == types::TY_HIP ||
3016 IA->getType() == types::TY_PP_HIP)) {
3019 return ABRT_Inactive;
3025 if (CompileHostOnly)
3026 return ABRT_Success;
3029 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3030 : types::TY_CUDA_DEVICE;
3031 std::string CUID = FixedCUID.str();
3033 if (UseCUID == CUID_Random)
3034 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
3036 else if (UseCUID == CUID_Hash) {
3038 llvm::MD5::MD5Result Hash;
3040 llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
3042 Hasher.update(RealPath);
3043 for (
auto *A : Args) {
3044 if (A->getOption().matches(options::OPT_INPUT))
3046 Hasher.update(A->getAsString(Args));
3049 CUID = llvm::utohexstr(Hash.low(),
true);
3054 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3055 CudaDeviceActions.push_back(
3056 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3059 return ABRT_Success;
3063 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3067 if (UA->getType() == types::TY_Object && !Relocatable)
3068 return ABRT_Inactive;
3070 CudaDeviceActions.clear();
3071 auto *IA = cast<InputAction>(UA->getInputs().back());
3072 std::string
FileName = IA->getInputArg().getAsString(Args);
3078 const StringRef LibFileExt =
".lib";
3079 if (IA->getType() == types::TY_Object &&
3080 (!llvm::sys::path::has_extension(
FileName) ||
3082 llvm::sys::path::extension(
FileName).drop_front()) !=
3084 llvm::sys::path::extension(
FileName) == LibFileExt))
3085 return ABRT_Inactive;
3087 for (
auto Arch : GpuArchList) {
3088 CudaDeviceActions.push_back(UA);
3089 UA->registerDependentActionInfo(ToolChains[0], Arch,
3090 AssociatedOffloadKind);
3093 return ABRT_Success;
3096 return IsActive ? ABRT_Success : ABRT_Inactive;
3099 void appendTopLevelActions(
ActionList &AL)
override {
3101 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3103 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3108 if (CudaFatBinary) {
3109 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3110 CudaDeviceActions.clear();
3111 CudaFatBinary =
nullptr;
3115 if (CudaDeviceActions.empty())
3121 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3122 "Expecting one action per GPU architecture.");
3123 assert(ToolChains.size() == 1 &&
3124 "Expecting to have a single CUDA toolchain.");
3125 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I)
3126 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3128 CudaDeviceActions.clear();
3133 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3135 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3153 assert(HostTC &&
"No toolchain for host compilation.");
3155 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3159 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3164 ToolChains.push_back(
3169 CompileHostOnly =
C.getDriver().offloadHostOnly();
3170 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3171 EmitAsm = Args.getLastArg(options::OPT_S);
3172 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3173 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3174 StringRef UseCUIDStr = A->getValue();
3175 UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3176 .Case(
"hash", CUID_Hash)
3177 .Case(
"random", CUID_Random)
3178 .Case(
"none", CUID_None)
3179 .Default(CUID_Invalid);
3180 if (UseCUID == CUID_Invalid) {
3181 C.getDriver().Diag(diag::err_drv_invalid_value)
3182 << A->getAsString(Args) << UseCUIDStr;
3183 C.setContainsError();
3189 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3190 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3191 options::OPT_no_offload_arch_EQ)) {
3192 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3197 std::set<StringRef> GpuArchs;
3199 for (Arg *A : Args) {
3200 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3201 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3205 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3206 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3209 }
else if (ArchStr ==
"native") {
3210 const ToolChain &TC = *ToolChains.front();
3211 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3214 << llvm::Triple::getArchTypeName(TC.
getArch())
3215 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3219 for (
auto GPU : *GPUsOrErr) {
3220 GpuArchs.insert(Args.MakeArgString(GPU));
3223 ArchStr = getCanonicalOffloadArch(ArchStr);
3224 if (ArchStr.empty()) {
3226 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3227 GpuArchs.insert(ArchStr);
3228 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3229 GpuArchs.erase(ArchStr);
3231 llvm_unreachable(
"Unexpected option.");
3237 if (ConflictingArchs) {
3238 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3239 << ConflictingArchs->first << ConflictingArchs->second;
3240 C.setContainsError();
3245 for (
auto Arch : GpuArchs)
3246 GpuArchList.push_back(Arch.data());
3251 if (GpuArchList.empty()) {
3252 if (ToolChains.front()->getTriple().isSPIRV()) {
3253 if (ToolChains.front()->getTriple().getVendor() == llvm::Triple::AMD)
3254 GpuArchList.push_back(OffloadArch::AMDGCNSPIRV);
3256 GpuArchList.push_back(OffloadArch::Generic);
3258 GpuArchList.push_back(DefaultOffloadArch);
3268 class CudaActionBuilder final :
public CudaActionBuilderBase {
3270 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3272 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3273 DefaultOffloadArch = OffloadArch::CudaDefault;
3276 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3279 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3285 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3287 const std::set<StringRef> &GpuArchs)
override {
3288 return std::nullopt;
3291 ActionBuilderReturnCode
3294 PhasesTy &Phases)
override {
3296 return ABRT_Inactive;
3300 if (CudaDeviceActions.empty())
3301 return ABRT_Success;
3303 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3304 "Expecting one action per GPU architecture.");
3305 assert(!CompileHostOnly &&
3306 "Not expecting CUDA actions in host-only compilation.");
3316 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3319 for (
auto Ph : Phases) {
3324 if (Ph > FinalPhase)
3327 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3337 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3341 Action *AssembleAction = CudaDeviceActions[I];
3342 assert(AssembleAction->
getType() == types::TY_Object);
3343 assert(AssembleAction->
getInputs().size() == 1);
3351 DeviceActions.push_back(
3357 if (!DeviceActions.empty()) {
3359 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3361 if (!CompileDeviceOnly) {
3362 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3366 CudaFatBinary =
nullptr;
3371 CudaDeviceActions.clear();
3375 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3380 return ABRT_Success;
3384 "instructions should only occur "
3385 "before the backend phase!");
3388 for (
Action *&A : CudaDeviceActions)
3389 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3391 return ABRT_Success;
3396 class HIPActionBuilder final :
public CudaActionBuilderBase {
3404 std::optional<bool> BundleOutput;
3405 std::optional<bool> EmitReloc;
3410 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3412 DefaultOffloadArch = OffloadArch::HIPDefault;
3414 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3415 options::OPT_fno_hip_emit_relocatable)) {
3416 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3417 options::OPT_fno_hip_emit_relocatable,
false);
3421 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3422 <<
"-fhip-emit-relocatable"
3426 if (!CompileDeviceOnly) {
3427 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3428 <<
"-fhip-emit-relocatable"
3429 <<
"--cuda-device-only";
3434 if (Args.hasArg(options::OPT_gpu_bundle_output,
3435 options::OPT_no_gpu_bundle_output))
3436 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3437 options::OPT_no_gpu_bundle_output,
true) &&
3438 (!EmitReloc || !*EmitReloc);
3441 bool canUseBundlerUnbundler()
const override {
return true; }
3443 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3444 llvm::StringMap<bool> Features;
3451 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3452 C.setContainsError();
3456 return Args.MakeArgStringRef(CanId);
3459 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3461 const std::set<StringRef> &GpuArchs)
override {
3465 ActionBuilderReturnCode
3468 PhasesTy &Phases)
override {
3470 return ABRT_Inactive;
3476 if (CudaDeviceActions.empty())
3477 return ABRT_Success;
3480 CudaDeviceActions.size() == GpuArchList.size()) &&
3481 "Expecting one action per GPU architecture.");
3482 assert(!CompileHostOnly &&
3483 "Not expecting HIP actions in host-only compilation.");
3485 bool ShouldLink = !EmitReloc || !*EmitReloc;
3488 !EmitAsm && ShouldLink) {
3494 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3495 if (
C.getDriver().isUsingLTO(
true)) {
3499 AL.push_back(CudaDeviceActions[I]);
3502 CudaDeviceActions[I] =
3509 if (ToolChains.front()->getTriple().isSPIRV()) {
3512 types::ID Output = Args.hasArg(options::OPT_S)
3514 : types::TY_LLVM_BC;
3520 AssociatedOffloadKind);
3521 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3523 AssociatedOffloadKind);
3524 AL.push_back(AssembleAction);
3527 CudaDeviceActions[I] =
3538 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3539 AssociatedOffloadKind);
3541 DDep, CudaDeviceActions[I]->getType());
3544 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3547 types::TY_HIP_FATBIN);
3549 if (!CompileDeviceOnly) {
3550 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3551 AssociatedOffloadKind);
3554 CudaFatBinary =
nullptr;
3559 CudaDeviceActions.clear();
3562 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3565 return ABRT_Success;
3571 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3572 auto LI = DeviceLinkerInputs.begin();
3573 for (
auto *A : CudaDeviceActions) {
3580 CudaDeviceActions.clear();
3581 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3585 for (
Action *&A : CudaDeviceActions)
3586 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3587 AssociatedOffloadKind);
3589 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3591 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3593 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3594 AssociatedOffloadKind);
3596 DDep, CudaDeviceActions[I]->getType());
3600 CudaDeviceActions.clear();
3603 return (CompileDeviceOnly &&
3604 (CurPhase == FinalPhase ||
3610 void appendLinkDeviceActions(
ActionList &AL)
override {
3611 if (DeviceLinkerInputs.size() == 0)
3614 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3615 "Linker inputs and GPU arch list sizes do not match.");
3621 for (
auto &LI : DeviceLinkerInputs) {
3623 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3627 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3631 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3632 GpuArchList[I], AssociatedOffloadKind);
3634 DeviceLinkDeps, DeviceLinkAction->getType()));
3637 DeviceLinkerInputs.clear();
3640 if (Args.hasArg(options::OPT_emit_llvm)) {
3649 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3652 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3653 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3654 AssociatedOffloadKind);
3657 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3663 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3679 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3687 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3690 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3698 unsigned ValidBuilders = 0u;
3699 unsigned ValidBuildersSupportingBundling = 0u;
3700 for (
auto *SB : SpecializedBuilders) {
3701 IsValid = IsValid && !SB->initialize();
3704 if (SB->isValid()) {
3706 if (SB->canUseBundlerUnbundler())
3707 ++ValidBuildersSupportingBundling;
3711 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3714 ~OffloadingActionBuilder() {
3715 for (
auto *SB : SpecializedBuilders)
3720 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3721 assert(HostAction &&
"Invalid host action");
3722 assert(InputArg &&
"Invalid input argument");
3723 auto Loc = HostActionToInputArgMap.find(HostAction);
3724 if (
Loc == HostActionToInputArgMap.end())
3725 HostActionToInputArgMap[HostAction] = InputArg;
3726 assert(HostActionToInputArgMap[HostAction] == InputArg &&
3727 "host action mapped to multiple input arguments");
3735 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3737 DeviceActionBuilder::PhasesTy &Phases) {
3741 if (SpecializedBuilders.empty())
3744 assert(HostAction &&
"Invalid host action!");
3745 recordHostAction(HostAction, InputArg);
3750 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3751 unsigned InactiveBuilders = 0u;
3752 unsigned IgnoringBuilders = 0u;
3753 for (
auto *SB : SpecializedBuilders) {
3754 if (!SB->isValid()) {
3759 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3764 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3769 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3770 OffloadKind |= SB->getAssociatedOffloadKind();
3775 if (IgnoringBuilders &&
3776 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3793 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3794 const Arg *InputArg) {
3798 recordHostAction(HostAction, InputArg);
3806 if (CanUseBundler && isa<InputAction>(HostAction) &&
3807 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3809 HostAction->
getType() == types::TY_PP_HIP)) {
3810 auto UnbundlingHostAction =
3815 HostAction = UnbundlingHostAction;
3816 recordHostAction(HostAction, InputArg);
3819 assert(HostAction &&
"Invalid host action!");
3822 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3823 for (
auto *SB : SpecializedBuilders) {
3827 auto RetCode = SB->addDeviceDependences(HostAction);
3831 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3832 "Host dependence not expected to be ignored.!");
3836 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3837 OffloadKind |= SB->getAssociatedOffloadKind();
3842 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
3852 const Arg *InputArg) {
3854 recordHostAction(HostAction, InputArg);
3858 for (
auto *SB : SpecializedBuilders) {
3861 SB->appendTopLevelActions(OffloadAL);
3868 if (CanUseBundler && HostAction &&
3869 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
3871 OffloadAL.push_back(HostAction);
3875 assert(HostAction == AL.back() &&
"Host action not in the list??");
3877 recordHostAction(HostAction, InputArg);
3878 AL.back() = HostAction;
3880 AL.append(OffloadAL.begin(), OffloadAL.end());
3890 void appendDeviceLinkActions(
ActionList &AL) {
3891 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3894 SB->appendLinkDeviceActions(AL);
3898 Action *makeHostLinkAction() {
3901 appendDeviceLinkActions(DeviceAL);
3902 if (DeviceAL.empty())
3907 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3910 HA = SB->appendLinkHostActions(DeviceAL);
3927 for (
auto *SB : SpecializedBuilders) {
3931 SB->appendLinkDependences(DDeps);
3935 unsigned ActiveOffloadKinds = 0u;
3936 for (
auto &I : InputArgToOffloadKindMap)
3937 ActiveOffloadKinds |= I.second;
3949 for (
auto *A : HostAction->
inputs()) {
3950 auto ArgLoc = HostActionToInputArgMap.find(A);
3951 if (ArgLoc == HostActionToInputArgMap.end())
3953 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
3954 if (OFKLoc == InputArgToOffloadKindMap.end())
3966 nullptr, ActiveOffloadKinds);
3972void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
3973 const InputList &Inputs,
3977 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3978 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3979 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3980 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3981 Args.eraseArg(options::OPT__SLASH_Yc);
3982 Args.eraseArg(options::OPT__SLASH_Yu);
3983 YcArg = YuArg =
nullptr;
3985 if (YcArg && Inputs.size() > 1) {
3986 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3987 Args.eraseArg(options::OPT__SLASH_Yc);
3995 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
3996 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
3997 Args.AddFlagArg(
nullptr,
3998 getOpts().getOption(options::OPT_frtlib_add_rpath));
4001 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4002 Diag(clang::diag::err_drv_emit_llvm_link);
4004 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4005 .equals_insensitive(
"lld"))
4006 Diag(clang::diag::err_drv_lto_without_lld);
4012 if (!Args.hasArg(options::OPT_dumpdir)) {
4013 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4014 Arg *Arg = Args.MakeSeparateArg(
4015 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4017 (FinalOutput ? FinalOutput->getValue()
4029 Args.eraseArg(options::OPT__SLASH_Fp);
4030 Args.eraseArg(options::OPT__SLASH_Yc);
4031 Args.eraseArg(options::OPT__SLASH_Yu);
4032 YcArg = YuArg =
nullptr;
4035 unsigned LastPLSize = 0;
4036 for (
auto &I : Inputs) {
4038 const Arg *InputArg = I.second;
4041 LastPLSize = PL.size();
4046 if (InitialPhase > FinalPhase) {
4047 if (InputArg->isClaimed())
4054 if (Args.hasArg(options::OPT_Qunused_arguments))
4060 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4061 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4065 (Args.getLastArg(options::OPT__SLASH_EP,
4066 options::OPT__SLASH_P) ||
4067 Args.getLastArg(options::OPT_E) ||
4068 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4070 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4071 << InputArg->getAsString(Args) << !!FinalPhaseArg
4072 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4074 Diag(clang::diag::warn_drv_input_file_unused)
4075 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4077 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4090 Actions.push_back(ClangClPch);
4104 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4105 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4111 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4113 if (!SuppressMissingInputWarning && Inputs.empty()) {
4114 Diag(clang::diag::err_drv_no_input_files);
4119 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4120 StringRef
V = A->getValue();
4121 if (Inputs.size() > 1 && !
V.empty() &&
4122 !llvm::sys::path::is_separator(
V.back())) {
4124 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4125 << A->getSpelling() <<
V;
4126 Args.eraseArg(options::OPT__SLASH_Fo);
4131 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4132 StringRef
V = A->getValue();
4133 if (Inputs.size() > 1 && !
V.empty() &&
4134 !llvm::sys::path::is_separator(
V.back())) {
4136 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4137 << A->getSpelling() <<
V;
4138 Args.eraseArg(options::OPT__SLASH_Fa);
4143 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4144 if (A->getValue()[0] ==
'\0') {
4146 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4147 Args.eraseArg(options::OPT__SLASH_o);
4151 handleArguments(
C, Args, Inputs, Actions);
4153 bool UseNewOffloadingDriver =
4155 Args.hasFlag(options::OPT_offload_new_driver,
4156 options::OPT_no_offload_new_driver,
false);
4159 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4160 !UseNewOffloadingDriver
4161 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4169 for (
auto &I : Inputs) {
4171 const Arg *InputArg = I.second;
4184 if (!UseNewOffloadingDriver)
4185 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4191 if (!UseNewOffloadingDriver)
4192 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4193 Current, InputArg, Phase, PL.back(), FullPL);
4199 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4202 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4203 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4205 LinkerInputs.push_back(Current);
4215 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4216 MergerInputs.push_back(Current);
4234 if (NewCurrent == Current)
4237 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4240 Current = NewCurrent;
4244 if (UseNewOffloadingDriver)
4248 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4252 if (Current->getType() == types::TY_Nothing)
4258 Actions.push_back(Current);
4261 if (!UseNewOffloadingDriver)
4262 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4264 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4270 if (LinkerInputs.empty()) {
4273 if (!UseNewOffloadingDriver)
4274 OffloadBuilder->appendDeviceLinkActions(Actions);
4277 if (!LinkerInputs.empty()) {
4278 if (!UseNewOffloadingDriver)
4279 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4280 LinkerInputs.push_back(Wrapper);
4285 }
else if (UseNewOffloadingDriver ||
4286 Args.hasArg(options::OPT_offload_link)) {
4293 if (!UseNewOffloadingDriver)
4294 LA = OffloadBuilder->processHostLinkAction(LA);
4295 Actions.push_back(LA);
4299 if (!MergerInputs.empty())
4303 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4310 for (
auto &I : Inputs) {
4312 const Arg *InputArg = I.second;
4317 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4318 InputType == types::TY_Asm)
4323 for (
auto Phase : PhaseList) {
4327 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4332 if (InputType == types::TY_Object)
4339 assert(Phase == PhaseList.back() &&
4340 "merging must be final compilation step.");
4341 MergerInputs.push_back(Current);
4350 Actions.push_back(Current);
4354 if (!MergerInputs.empty())
4359 for (
auto Opt : {options::OPT_print_supported_cpus,
4360 options::OPT_print_supported_extensions,
4361 options::OPT_print_enabled_extensions}) {
4368 if (Arg *A = Args.getLastArg(Opt)) {
4369 if (Opt == options::OPT_print_supported_extensions &&
4370 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4371 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4372 !
C.getDefaultToolChain().getTriple().isARM()) {
4373 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4374 <<
"--print-supported-extensions";
4377 if (Opt == options::OPT_print_enabled_extensions &&
4378 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4379 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4380 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4381 <<
"--print-enabled-extensions";
4390 for (
auto &I : Inputs)
4396 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4400 if (TC.requiresValidation(Args)) {
4401 Action *LastAction = Actions.back();
4403 LastAction, types::TY_DX_CONTAINER));
4408 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4414 const llvm::opt::DerivedArgList &Args,
4416 const llvm::Triple &Triple,
4417 bool SuppressError =
false) {
4422 if (!SuppressError && Triple.isNVPTX() &&
4424 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4425 <<
"CUDA" << ArchStr;
4427 }
else if (!SuppressError && Triple.isAMDGPU() &&
4429 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4430 <<
"HIP" << ArchStr;
4438 llvm::StringMap<bool> Features;
4444 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4445 C.setContainsError();
4457static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4459 llvm::Triple Triple) {
4460 if (!Triple.isAMDGPU())
4461 return std::nullopt;
4463 std::set<StringRef> ArchSet;
4464 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4471 bool SuppressError)
const {
4473 TC = &
C.getDefaultToolChain();
4476 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4477 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4478 options::OPT_no_offload_arch_EQ)) {
4479 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4481 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4483 :
"--no-offload-arch");
4486 if (KnownArchs.contains(TC))
4487 return KnownArchs.lookup(TC);
4490 for (
auto *Arg : Args) {
4492 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4493 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4496 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4497 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4498 Arg = ExtractedArg.get();
4503 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4504 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4505 if (Arch ==
"native" || Arch.empty()) {
4509 llvm::consumeError(GPUsOrErr.takeError());
4512 << llvm::Triple::getArchTypeName(TC->
getArch())
4513 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4517 for (
auto ArchStr : *GPUsOrErr) {
4524 C, Args, Arch, TC->
getTriple(), SuppressError);
4525 if (ArchStr.empty())
4527 Archs.insert(ArchStr);
4530 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4531 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4532 if (Arch ==
"all") {
4536 C, Args, Arch, TC->
getTriple(), SuppressError);
4537 if (ArchStr.empty())
4539 Archs.erase(ArchStr);
4545 if (
auto ConflictingArchs =
4547 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4548 << ConflictingArchs->first << ConflictingArchs->second;
4549 C.setContainsError();
4556 if (Archs.empty()) {
4562 Archs.insert(StringRef());
4564 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4565 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4572 llvm::opt::DerivedArgList &Args,
4574 Action *HostAction)
const {
4579 !(isa<CompileJobAction>(HostAction) ||
4593 auto TCRange =
C.getOffloadToolChains(Kind);
4594 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4595 ToolChains.push_back(TI->second);
4597 if (ToolChains.empty())
4601 const Arg *InputArg = Input.second;
4610 for (
const ToolChain *TC : ToolChains) {
4614 for (StringRef Arch : Sorted)
4615 TCAndArchs.push_back(std::make_pair(TC, Arch));
4618 for (
unsigned I = 0,
E = TCAndArchs.size(); I !=
E; ++I)
4619 DeviceActions.push_back(
C.MakeAction<
InputAction>(*InputArg, InputType));
4621 if (DeviceActions.empty())
4628 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4632 auto TCAndArch = TCAndArchs.begin();
4633 for (
Action *&A : DeviceActions) {
4634 if (A->
getType() == types::TY_Nothing)
4642 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4644 HostAction->
getType() != types::TY_Nothing) {
4651 TCAndArch->second.data(), Kind);
4653 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4662 for (
Action *&A : DeviceActions) {
4663 if ((A->
getType() != types::TY_Object &&
4664 A->
getType() != types::TY_LTO_BC) ||
4666 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4672 auto TCAndArch = TCAndArchs.begin();
4673 for (
Action *A : DeviceActions) {
4674 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4676 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4681 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4683 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4691 bool ShouldBundleHIP =
4693 Args.hasFlag(options::OPT_gpu_bundle_output,
4694 options::OPT_no_gpu_bundle_output,
true) &&
4695 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4696 !llvm::any_of(OffloadActions,
4703 if (OffloadActions.empty())
4708 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4712 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4716 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4721 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4730 nullptr,
C.getActiveOffloadKinds());
4739 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4740 return A->
getType() == types::TY_Nothing;
4741 }) && isa<CompileJobAction>(HostAction);
4744 nullptr, SingleDeviceOutput ? DDep : DDeps);
4745 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4751 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4762 llvm_unreachable(
"link action invalid here.");
4764 llvm_unreachable(
"ifsmerge action invalid here.");
4769 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4770 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4771 OutputTy = types::TY_Dependencies;
4776 if (!Args.hasFlag(options::OPT_frewrite_includes,
4777 options::OPT_fno_rewrite_includes,
false) &&
4778 !Args.hasFlag(options::OPT_frewrite_imports,
4779 options::OPT_fno_rewrite_imports,
false) &&
4780 !Args.hasFlag(options::OPT_fdirectives_only,
4781 options::OPT_fno_directives_only,
false) &&
4785 "Cannot preprocess this input type!");
4791 if (Args.hasArg(options::OPT_extract_api))
4798 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
4799 !Args.getLastArg(options::OPT__precompile))
4804 "Cannot precompile this input type!");
4808 const char *ModName =
nullptr;
4809 if (OutputTy == types::TY_PCH) {
4810 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4811 ModName = A->getValue();
4813 OutputTy = types::TY_ModuleFile;
4816 if (Args.hasArg(options::OPT_fsyntax_only)) {
4818 OutputTy = types::TY_Nothing;
4824 if (Args.hasArg(options::OPT_fsyntax_only))
4826 if (Args.hasArg(options::OPT_rewrite_objc))
4828 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
4830 types::TY_RewrittenLegacyObjC);
4831 if (Args.hasArg(options::OPT__analyze))
4833 if (Args.hasArg(options::OPT__migrate))
4835 if (Args.hasArg(options::OPT_emit_ast))
4837 if (Args.hasArg(options::OPT_emit_cir))
4839 if (Args.hasArg(options::OPT_module_file_info))
4841 if (Args.hasArg(options::OPT_verify_pch))
4843 if (Args.hasArg(options::OPT_extract_api))
4850 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
4851 !Args.hasArg(options::OPT_emit_llvm))
4852 Output = types::TY_PP_Asm;
4853 else if (Args.hasArg(options::OPT_S))
4854 Output = types::TY_LTO_IR;
4856 Output = types::TY_LTO_BC;
4862 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
4865 if (Args.hasArg(options::OPT_emit_llvm) ||
4869 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4873 Args.hasArg(options::OPT_S) &&
4877 !Args.hasFlag(options::OPT_offload_new_driver,
4878 options::OPT_no_offload_new_driver,
false)))
4880 : types::TY_LLVM_BC;
4889 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4893 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4895 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
4915 unsigned NumOutputs = 0;
4916 unsigned NumIfsOutputs = 0;
4917 for (
const Action *A :
C.getActions()) {
4918 if (A->
getType() != types::TY_Nothing &&
4919 A->
getType() != types::TY_DX_CONTAINER &&
4921 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
4923 0 == NumIfsOutputs++) ||
4928 A->
getType() == types::TY_Nothing &&
4929 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
4930 NumOutputs += A->
size();
4933 if (NumOutputs > 1) {
4934 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
4935 FinalOutput =
nullptr;
4939 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
4942 llvm::StringSet<> ArchNames;
4943 if (RawTriple.isOSBinFormatMachO())
4944 for (
const Arg *A :
C.getArgs())
4945 if (A->getOption().matches(options::OPT_arch))
4946 ArchNames.insert(A->getValue());
4949 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
4950 for (
Action *A :
C.getActions()) {
4957 const char *LinkingOutput =
nullptr;
4958 if (isa<LipoJobAction>(A)) {
4960 LinkingOutput = FinalOutput->getValue();
4968 ArchNames.size() > 1,
4969 LinkingOutput, CachedResults,
4976 for (
auto &J :
C.getJobs())
4977 J.InProcess =
false;
4980 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
4981 std::optional<llvm::sys::ProcessStatistics> ProcStat =
4982 Cmd.getProcessStatistics();
4986 const char *LinkingOutput =
nullptr;
4988 LinkingOutput = FinalOutput->getValue();
4989 else if (!
Cmd.getOutputFilenames().empty())
4990 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
4995 using namespace llvm;
4997 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
4998 <<
"output=" << LinkingOutput;
4999 outs() <<
", total="
5000 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5002 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5003 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5007 llvm::raw_string_ostream Out(Buffer);
5008 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
5011 llvm::sys::printArg(Out, LinkingOutput, true);
5012 Out <<
',' << ProcStat->TotalTime.count() <<
','
5013 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5017 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5018 llvm::sys::fs::OF_Append |
5019 llvm::sys::fs::OF_Text);
5024 llvm::errs() <<
"ERROR: Cannot lock file "
5025 << CCPrintStatReportFilename <<
": "
5026 << toString(L.takeError()) <<
"\n";
5037 if (Diags.hasErrorOccurred() ||
5038 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5042 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5044 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5047 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5048 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5050 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5054 return strstr(J.getCreator().getShortName(),
"assembler");
5056 for (Arg *A :
C.getArgs()) {
5060 if (!A->isClaimed()) {
5066 const Option &Opt = A->getOption();
5067 if (Opt.getKind() == Option::FlagClass) {
5068 bool DuplicateClaimed =
false;
5070 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5071 if (AA->isClaimed()) {
5072 DuplicateClaimed =
true;
5077 if (DuplicateClaimed)
5083 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5085 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5090 !
C.getActions().empty()) {
5091 Diag(diag::err_drv_unsupported_opt_for_target)
5092 << A->getSpelling() << getTargetTriple();
5094 Diag(clang::diag::warn_drv_unused_argument)
5095 << A->getAsString(
C.getArgs());
5105class ToolSelector final {
5116 bool IsHostSelector;
5127 bool CanBeCollapsed =
true) {
5129 if (Inputs.size() != 1)
5132 Action *CurAction = *Inputs.begin();
5133 if (CanBeCollapsed &&
5139 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5143 if (!IsHostSelector) {
5144 if (OA->hasSingleDeviceDependence(
true)) {
5146 OA->getSingleDeviceDependence(
true);
5147 if (CanBeCollapsed &&
5150 SavedOffloadAction.push_back(OA);
5151 return dyn_cast<JobAction>(CurAction);
5153 }
else if (OA->hasHostDependence()) {
5154 CurAction = OA->getHostDependence();
5155 if (CanBeCollapsed &&
5158 SavedOffloadAction.push_back(OA);
5159 return dyn_cast<JobAction>(CurAction);
5164 return dyn_cast<JobAction>(CurAction);
5168 bool canCollapseAssembleAction()
const {
5169 return TC.useIntegratedAs() && !SaveTemps &&
5170 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5171 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5172 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5173 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5177 bool canCollapsePreprocessorAction()
const {
5178 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5179 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5180 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5185 struct JobActionInfo final {
5195 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5197 unsigned ElementNum) {
5198 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5199 for (
unsigned I = 0; I < ElementNum; ++I)
5200 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5201 ActionInfo[I].SavedOffloadAction.end());
5217 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5219 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5220 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5221 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5222 if (!AJ || !BJ || !CJ)
5226 const Tool *
T = TC.SelectTool(*CJ);
5233 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5239 const Tool *BT = TC.SelectTool(*BJ);
5244 if (!
T->hasIntegratedAssembler())
5247 Inputs = CJ->getInputs();
5248 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5255 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5257 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5258 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5263 const Tool *
T = TC.SelectTool(*BJ);
5267 if (!
T->hasIntegratedAssembler())
5270 Inputs = BJ->getInputs();
5271 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5278 if (ActionInfo.size() < 2)
5280 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5281 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5290 bool InputIsBitcode =
true;
5291 for (
size_t i = 1; i < ActionInfo.size(); i++)
5292 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5293 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5294 InputIsBitcode =
false;
5297 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5301 const Tool *
T = TC.SelectTool(*CJ);
5308 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5311 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5314 Inputs = CJ->getInputs();
5315 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5326 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5332 for (
Action *A : Inputs) {
5333 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5334 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5335 NewInputs.push_back(A);
5341 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5342 PreprocessJobOffloadActions.end());
5343 NewInputs.append(PJ->input_begin(), PJ->input_end());
5351 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5353 assert(BaseAction &&
"Invalid base action.");
5370 ActionChain.back().JA = BaseAction;
5371 while (ActionChain.back().JA) {
5372 const Action *CurAction = ActionChain.back().JA;
5375 ActionChain.resize(ActionChain.size() + 1);
5376 JobActionInfo &AI = ActionChain.back();
5380 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5384 ActionChain.pop_back();
5392 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5393 CollapsedOffloadAction);
5395 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5397 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5403 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5415 StringRef BoundArch,
5417 std::string TriplePlusArch = TC->
getTriple().normalize();
5418 if (!BoundArch.empty()) {
5419 TriplePlusArch +=
"-";
5420 TriplePlusArch += BoundArch;
5422 TriplePlusArch +=
"-";
5424 return TriplePlusArch;
5429 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5430 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5433 std::pair<const Action *, std::string> ActionTC = {
5435 auto CachedResult = CachedResults.find(ActionTC);
5436 if (CachedResult != CachedResults.end()) {
5437 return CachedResult->second;
5440 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5441 CachedResults, TargetDeviceOffloadKind);
5442 CachedResults[ActionTC] =
Result;
5447 const JobAction *JA,
const char *BaseInput,
5450 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5454 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5455 Path = A->getValue();
5456 if (llvm::sys::fs::is_directory(
Path)) {
5458 llvm::sys::path::replace_extension(Tmp,
"json");
5459 llvm::sys::path::append(
Path, llvm::sys::path::filename(Tmp));
5462 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5465 Path = DumpDir->getValue();
5466 Path += llvm::sys::path::filename(BaseInput);
5470 llvm::sys::path::replace_extension(
Path,
"json");
5472 const char *ResultFile =
C.getArgs().MakeArgString(
Path);
5473 C.addTimeTraceFile(ResultFile, JA);
5474 C.addResultFile(ResultFile, JA);
5479 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5480 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5483 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5486 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5519 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5521 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5522 const char *DepBoundArch) {
5525 LinkingOutput, CachedResults,
5535 OA->doOnEachDependence(
5536 BuildingForOffloadDevice,
5539 C, DepA, DepTC, DepBoundArch,
false,
5540 !!DepBoundArch, LinkingOutput, CachedResults,
5544 A = BuildingForOffloadDevice
5545 ? OA->getSingleDeviceDependence(
true)
5546 : OA->getHostDependence();
5550 std::pair<const Action *, std::string> ActionTC = {
5551 OA->getHostDependence(),
5553 if (CachedResults.find(ActionTC) != CachedResults.end()) {
5555 Inputs.append(OffloadDependencesInputInfo);
5560 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5563 const Arg &Input = IA->getInputArg();
5565 if (Input.getOption().matches(options::OPT_INPUT)) {
5566 const char *
Name = Input.getValue();
5576 if (!ArchName.empty())
5577 TC = &getToolChain(
C.getArgs(),
5579 C.getArgs(), ArchName));
5581 TC = &
C.getDefaultToolChain();
5584 MultipleArchs, LinkingOutput, CachedResults,
5585 TargetDeviceOffloadKind);
5591 const JobAction *JA = cast<JobAction>(A);
5596 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5603 for (
const auto *OA : CollapsedOffloadActions)
5604 cast<OffloadAction>(OA)->doOnEachDependence(
5605 BuildingForOffloadDevice,
5608 C, DepA, DepTC, DepBoundArch,
false,
5609 !!DepBoundArch, LinkingOutput, CachedResults,
5615 for (
const Action *Input : Inputs) {
5619 bool SubJobAtTopLevel =
5620 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5622 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5627 const char *BaseInput = InputInfos[0].getBaseInput();
5628 for (
auto &Info : InputInfos) {
5629 if (Info.isFilename()) {
5630 BaseInput = Info.getBaseInput();
5637 if (JA->
getType() == types::TY_dSYM)
5638 BaseInput = InputInfos[0].getFilename();
5641 if (!OffloadDependencesInputInfo.empty())
5642 InputInfos.append(OffloadDependencesInputInfo.begin(),
5643 OffloadDependencesInputInfo.end());
5646 llvm::Triple EffectiveTriple;
5648 const ArgList &Args =
5650 if (InputInfos.size() != 1) {
5654 EffectiveTriple = llvm::Triple(
5662 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5666 for (
auto &UI : UA->getDependentActionsInfo()) {
5668 "Unbundling with no offloading??");
5675 UI.DependentOffloadKind,
5676 UI.DependentToolChain->getTriple().normalize(),
5687 UnbundlingResults.push_back(CurI);
5696 Arch = UI.DependentBoundArch;
5701 UI.DependentOffloadKind)}] = {
5707 std::pair<const Action *, std::string> ActionTC = {
5709 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5710 "Result does not exist??");
5711 Result = CachedResults[ActionTC].front();
5712 }
else if (JA->
getType() == types::TY_Nothing)
5719 isa<OffloadPackagerJobAction>(A) ||
5723 AtTopLevel, MultipleArchs,
5726 if (
T->canEmitIR() && OffloadingPrefix.empty())
5731 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5732 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5733 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5734 llvm::errs() << InputInfos[i].getAsString();
5736 llvm::errs() <<
", ";
5738 if (UnbundlingResults.empty())
5739 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5741 llvm::errs() <<
"], outputs: [";
5742 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5743 llvm::errs() << UnbundlingResults[i].getAsString();
5745 llvm::errs() <<
", ";
5747 llvm::errs() <<
"] \n";
5750 if (UnbundlingResults.empty())
5756 T->ConstructJobMultipleOutputs(
5757 C, *JA, UnbundlingResults, InputInfos,
5765 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5766 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5778 if (ArgValue.empty()) {
5781 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
5783 llvm::sys::path::append(
Filename, BaseName);
5786 if (!llvm::sys::path::has_extension(ArgValue)) {
5791 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5796 llvm::sys::path::replace_extension(
Filename, Extension);
5799 return Args.MakeArgString(
Filename.c_str());
5803 if (isa<PreprocessJobAction>(JA))
5805 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
5807 if (isa<OffloadBundlingJobAction>(JA) &&
5814 StringRef Suffix,
bool MultipleArchs,
5815 StringRef BoundArch,
5816 bool NeedUniqueDirectory)
const {
5818 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
5819 std::optional<std::string> CrashDirectory =
5821 ? std::string(A->getValue())
5822 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
5823 if (CrashDirectory) {
5824 if (!
getVFS().exists(*CrashDirectory))
5825 llvm::sys::fs::create_directories(*CrashDirectory);
5827 llvm::sys::path::append(
Path, Prefix);
5828 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
5829 if (std::error_code EC =
5830 llvm::sys::fs::createUniqueFile(
Path + Middle + Suffix, TmpName)) {
5831 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
5835 if (MultipleArchs && !BoundArch.empty()) {
5836 if (NeedUniqueDirectory) {
5838 llvm::sys::path::append(TmpName,
5839 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
5849 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5864 const char *BaseInput) {
5865 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
5866 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
5867 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
5872 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
5876 const char *BaseInput,
5877 StringRef OrigBoundArch,
bool AtTopLevel,
5879 StringRef OffloadingPrefix)
const {
5880 std::string BoundArch = OrigBoundArch.str();
5881 if (is_style_windows(llvm::sys::path::Style::native)) {
5884 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
5887 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
5889 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
5890 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
5891 return C.addResultFile(FinalOutput->getValue(), &JA);
5895 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
5896 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
5897 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5899 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
5900 NameArg = A->getValue();
5901 return C.addResultFile(
5911 if (JA.
getType() == types::TY_ModuleFile &&
5912 C.getArgs().getLastArg(options::OPT_module_file_info)) {
5916 if (JA.
getType() == types::TY_PP_Asm &&
5917 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
5918 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
5921 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
5924 if (JA.
getType() == types::TY_Object &&
5925 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
5926 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
5929 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
5933 if (JA.
getType() == types::TY_PP_Asm &&
5934 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
5935 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
5937 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5938 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
5939 return C.addResultFile(
5944 if (JA.
getType() == types::TY_API_INFO &&
5945 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
5946 C.getArgs().hasArg(options::OPT_o))
5947 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
5948 <<
C.getArgs().getLastArgValue(options::OPT_o);
5955 bool SpecifiedModuleOutput =
5956 C.getArgs().hasArg(options::OPT_fmodule_output) ||
5957 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
5958 if (MultipleArchs && SpecifiedModuleOutput)
5959 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
5963 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
5964 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
5965 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
5971 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
5973 StringRef
Name = llvm::sys::path::filename(BaseInput);
5974 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
5975 const char *Suffix =
5980 llvm::Triple Triple(
C.getDriver().getTargetTriple());
5981 bool NeedUniqueDirectory =
5984 Triple.isOSDarwin();
5985 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
5986 NeedUniqueDirectory);
5994 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
5995 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6000 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6001 llvm::sys::path::filename(BasePath));
6002 BaseName = ExternalPath;
6003 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
6004 BaseName = BasePath;
6006 BaseName = llvm::sys::path::filename(BasePath);
6009 const char *NamedOutput;
6011 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6012 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6016 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6020 }
else if (JA.
getType() == types::TY_Image &&
6021 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6022 options::OPT__SLASH_o)) {
6026 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6030 }
else if (JA.
getType() == types::TY_Image) {
6040 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6041 options::OPT_fno_gpu_rdc,
false);
6042 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6043 if (UseOutExtension) {
6045 llvm::sys::path::replace_extension(Output,
"");
6047 Output += OffloadingPrefix;
6048 if (MultipleArchs && !BoundArch.empty()) {
6050 Output.append(BoundArch);
6052 if (UseOutExtension)
6054 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6057 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6058 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6059 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6062 .getLastArg(options::OPT__SLASH_o)
6067 const char *Suffix =
6069 assert(Suffix &&
"All types used for output should have a suffix.");
6071 std::string::size_type End = std::string::npos;
6073 End = BaseName.rfind(
'.');
6075 Suffixed += OffloadingPrefix;
6076 if (MultipleArchs && !BoundArch.empty()) {
6078 Suffixed.append(BoundArch);
6083 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6084 const llvm::opt::DerivedArgList &Args) {
6089 return isa<CompileJobAction>(JA) &&
6091 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6096 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6097 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6098 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6102 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6106 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6107 JA.
getType() != types::TY_PCH) {
6108 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6110 llvm::sys::path::remove_filename(TempPath);
6111 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6112 llvm::sys::path::append(TempPath, OutputFileName);
6113 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6119 bool SameFile =
false;
6121 llvm::sys::fs::current_path(
Result);
6122 llvm::sys::path::append(
Result, BaseName);
6123 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6126 StringRef
Name = llvm::sys::path::filename(BaseInput);
6127 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6131 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6137 llvm::sys::path::remove_filename(BasePath);
6138 if (BasePath.empty())
6139 BasePath = NamedOutput;
6141 llvm::sys::path::append(BasePath, NamedOutput);
6142 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6145 return C.addResultFile(NamedOutput, &JA);
6151 -> std::optional<std::string> {
6154 for (
const auto &
Dir :
P) {
6158 llvm::sys::path::append(
P,
Name);
6159 if (llvm::sys::fs::exists(Twine(
P)))
6160 return std::string(
P);
6162 return std::nullopt;
6169 llvm::sys::path::append(R,
Name);
6170 if (llvm::sys::fs::exists(Twine(R)))
6171 return std::string(R);
6174 llvm::sys::path::append(
P,
Name);
6175 if (llvm::sys::fs::exists(Twine(
P)))
6176 return std::string(
P);
6179 llvm::sys::path::append(
D,
"..",
Name);
6180 if (llvm::sys::fs::exists(Twine(
D)))
6181 return std::string(
D);
6189 return std::string(
Name);
6192void Driver::generatePrefixedToolNames(
6196 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6197 Names.emplace_back(
Tool);
6201 llvm::sys::path::append(Dir, Name);
6202 if (llvm::sys::fs::can_execute(Twine(Dir)))
6204 llvm::sys::path::remove_filename(Dir);
6210 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6215 if (llvm::sys::fs::is_directory(PrefixDir)) {
6218 return std::string(
P);
6221 if (llvm::sys::fs::can_execute(Twine(
P)))
6222 return std::string(
P);
6227 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6235 for (
const auto &
Path : List) {
6238 return std::string(
P);
6242 if (llvm::ErrorOr<std::string>
P =
6243 llvm::sys::findProgramByName(TargetSpecificExecutable))
6247 return std::string(
Name);
6252 std::string error =
"<NOT PRESENT>";
6256 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6273 llvm::sys::path::remove_filename(path);
6274 llvm::sys::path::append(path,
"libc++.modules.json");
6275 if (TC.
getVFS().exists(path))
6276 return static_cast<std::string
>(path);
6281 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6284 return evaluate(
"libc++.a").value_or(error);
6297 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix,
Path);
6299 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6303 return std::string(
Path);
6308 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix,
Path);
6310 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6314 return std::string(
Path);
6319 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6323 Output = FpArg->getValue();
6327 if (!llvm::sys::path::has_extension(Output))
6330 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6331 Output = YcArg->getValue();
6334 llvm::sys::path::replace_extension(Output,
".pch");
6336 return std::string(Output);
6339const ToolChain &Driver::getToolChain(
const ArgList &Args,
6340 const llvm::Triple &
Target)
const {
6342 auto &TC = ToolChains[
Target.str()];
6344 switch (
Target.getOS()) {
6345 case llvm::Triple::AIX:
6346 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6348 case llvm::Triple::Haiku:
6349 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6351 case llvm::Triple::Darwin:
6352 case llvm::Triple::MacOSX:
6353 case llvm::Triple::IOS:
6354 case llvm::Triple::TvOS:
6355 case llvm::Triple::WatchOS:
6356 case llvm::Triple::XROS:
6357 case llvm::Triple::DriverKit:
6358 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6360 case llvm::Triple::DragonFly:
6361 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6363 case llvm::Triple::OpenBSD:
6364 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6366 case llvm::Triple::NetBSD:
6367 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6369 case llvm::Triple::FreeBSD:
6371 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6374 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6376 case llvm::Triple::Linux:
6377 case llvm::Triple::ELFIAMCU:
6378 if (
Target.getArch() == llvm::Triple::hexagon)
6379 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6381 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6382 !
Target.hasEnvironment())
6383 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6386 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6388 else if (
Target.getArch() == llvm::Triple::ve)
6389 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6390 else if (
Target.isOHOSFamily())
6391 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6393 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6395 case llvm::Triple::NaCl:
6396 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6398 case llvm::Triple::Fuchsia:
6399 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6401 case llvm::Triple::Solaris:
6402 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6404 case llvm::Triple::CUDA:
6405 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6407 case llvm::Triple::AMDHSA:
6408 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6410 case llvm::Triple::AMDPAL:
6411 case llvm::Triple::Mesa3D:
6412 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6414 case llvm::Triple::Win32:
6415 switch (
Target.getEnvironment()) {
6417 if (
Target.isOSBinFormatELF())
6418 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6419 else if (
Target.isOSBinFormatMachO())
6420 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6422 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6424 case llvm::Triple::GNU:
6425 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6427 case llvm::Triple::Itanium:
6428 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6431 case llvm::Triple::MSVC:
6432 case llvm::Triple::UnknownEnvironment:
6433 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6434 .starts_with_insensitive(
"bfd"))
6435 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6439 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6443 case llvm::Triple::PS4:
6444 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6446 case llvm::Triple::PS5:
6447 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6449 case llvm::Triple::Hurd:
6450 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6452 case llvm::Triple::LiteOS:
6453 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6455 case llvm::Triple::ZOS:
6456 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6458 case llvm::Triple::ShaderModel:
6459 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6464 switch (
Target.getArch()) {
6465 case llvm::Triple::tce:
6466 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6468 case llvm::Triple::tcele:
6469 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6471 case llvm::Triple::hexagon:
6472 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6475 case llvm::Triple::lanai:
6476 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6478 case llvm::Triple::xcore:
6479 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6481 case llvm::Triple::wasm32:
6482 case llvm::Triple::wasm64:
6483 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6485 case llvm::Triple::avr:
6486 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6488 case llvm::Triple::msp430:
6490 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6492 case llvm::Triple::riscv32:
6493 case llvm::Triple::riscv64:
6496 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6498 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6500 case llvm::Triple::ve:
6501 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6503 case llvm::Triple::spirv32:
6504 case llvm::Triple::spirv64:
6505 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6507 case llvm::Triple::csky:
6508 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6512 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6513 else if (
Target.isOSBinFormatELF())
6514 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6515 else if (
Target.isOSBinFormatMachO())
6516 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6518 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6526const ToolChain &Driver::getOffloadingDeviceToolChain(
6527 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6536 switch (TargetDeviceOffloadKind) {
6538 if (((
Target.getArch() == llvm::Triple::amdgcn ||
6539 Target.getArch() == llvm::Triple::spirv64) &&
6540 Target.getVendor() == llvm::Triple::AMD &&
6541 Target.getOS() == llvm::Triple::AMDHSA) ||
6542 !Args.hasArgNoClaim(options::OPT_offload_EQ))
6543 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6545 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6546 Target.getVendor() == llvm::Triple::UnknownVendor &&
6547 Target.getOS() == llvm::Triple::UnknownOS)
6548 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6562 if (JA.
size() != 1 ||
6567 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6568 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6569 !isa<ExtractAPIJobAction>(JA))
6577 if (JA.
size() != 1 ||
6582 if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) &&
6583 !isa<BackendJobAction>(JA))
6591 if (Args.hasArg(options::OPT_emit_static_lib))
6602 unsigned &Micro,
bool &HadExtra) {
6605 Major = Minor = Micro = 0;
6609 if (Str.consumeInteger(10, Major))
6613 if (!Str.consume_front(
"."))
6616 if (Str.consumeInteger(10, Minor))
6620 if (!Str.consume_front(
"."))
6623 if (Str.consumeInteger(10, Micro))
6641 unsigned CurDigit = 0;
6642 while (CurDigit < Digits.size()) {
6644 if (Str.consumeInteger(10, Digit))
6646 Digits[CurDigit] = Digit;
6649 if (!Str.consume_front(
"."))
6658llvm::opt::Visibility
6659Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6672const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6688 llvm_unreachable(
"Unhandled Mode");
6692 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6697 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6698 options::OPT_fno_save_optimization_record,
false))
6702 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6703 options::OPT_fno_save_optimization_record,
false))
6707 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6708 options::OPT_fno_save_optimization_record,
false))
6712 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6713 options::OPT_fno_save_optimization_record,
false))
6720 static StringRef OptName =
6722 llvm::StringRef Opt;
6723 for (StringRef Arg : Args) {
6724 if (!Arg.starts_with(OptName))
6730 return Opt.consume_front(OptName) ? Opt :
"";
6737 llvm::BumpPtrAllocator &Alloc,
6738 llvm::vfs::FileSystem *FS) {
6747 for (
const char *F : Args) {
6748 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6750 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6751 RSPQuoting = Windows;
6759 llvm::cl::TokenizerCallback Tokenizer;
6761 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6763 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6765 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6768 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6769 ECtx.setMarkEOLs(MarkEOLs);
6773 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
6777 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
6778 [](
const char *A) {
return A !=
nullptr; });
6779 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
6782 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
6783 Args.resize(newEnd - Args.begin());
6787 return llvm::Error::success();
6791 return SavedStrings.insert(S).first->getKeyData();
6824 llvm::StringSet<> &SavedStrings) {
6827 if (Edit[0] ==
'^') {
6828 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6829 OS <<
"### Adding argument " << Str <<
" at beginning\n";
6830 Args.insert(Args.begin() + 1, Str);
6831 }
else if (Edit[0] ==
'+') {
6832 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6833 OS <<
"### Adding argument " << Str <<
" at end\n";
6834 Args.push_back(Str);
6835 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
6836 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
6837 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
6838 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
6839 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
6841 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
6843 if (Args[i] ==
nullptr)
6845 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
6847 if (Repl != Args[i]) {
6848 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
6852 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
6853 auto Option = Edit.substr(1);
6854 for (
unsigned i = 1; i < Args.size();) {
6855 if (Option == Args[i]) {
6856 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6857 Args.erase(Args.begin() + i);
6858 if (Edit[0] ==
'X') {
6859 if (i < Args.size()) {
6860 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6861 Args.erase(Args.begin() + i);
6863 OS <<
"### Invalid X edit, end of command line!\n";
6868 }
else if (Edit[0] ==
'O') {
6869 for (
unsigned i = 1; i < Args.size();) {
6870 const char *A = Args[i];
6874 if (A[0] ==
'-' && A[1] ==
'O' &&
6875 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
6876 (
'0' <= A[2] && A[2] <=
'9'))))) {
6877 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6878 Args.erase(Args.begin() + i);
6882 OS <<
"### Adding argument " << Edit <<
" at end\n";
6883 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
6885 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
6890 const char *OverrideStr,
6891 llvm::StringSet<> &SavedStrings,
6894 OS = &llvm::nulls();
6896 if (OverrideStr[0] ==
'#') {
6898 OS = &llvm::nulls();
6901 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
6905 const char *S = OverrideStr;
6907 const char *End = ::strchr(S,
' ');
6909 End = S + strlen(S);
static std::optional< llvm::Triple > getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args)
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 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 void appendOneArg(InputArgList &Args, const Arg *Opt, const Arg *BaseArg)
static const char BugReporMsg[]
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static std::optional< llvm::Triple > getOffloadTargetTriple(const Driver &D, const ArgList &Args)
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.
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.
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.
bool isUsingLTO(bool IsOffload=false) const
Returns true if we are performing any kind of LTO.
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.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
static std::string GetResourcesPath(StringRef BinaryPath, StringRef CustomResourceDir="")
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
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.
llvm::SmallVector< std::string, 4 > TemporaryFiles
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.