56#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::is_contained(OffloadArchs,
"amdgcnspirv") &&
152 OffloadArchs.size() == 1)
153 return llvm::Triple(
"spirv64-amd-amdhsa");
154 return llvm::Triple(
"amdgcn-amd-amdhsa");
159 if (TT->getArch() == llvm::Triple::amdgcn &&
160 TT->getVendor() == llvm::Triple::AMD &&
161 TT->getOS() == llvm::Triple::AMDHSA)
163 if (TT->getArch() == llvm::Triple::spirv64)
165 D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
176 StringRef
Dir = llvm::sys::path::parent_path(BinaryPath);
179 StringRef ConfiguredResourceDir(CLANG_RESOURCE_DIR);
180 if (!ConfiguredResourceDir.empty()) {
181 llvm::sys::path::append(
P, ConfiguredResourceDir);
188 P = llvm::sys::path::parent_path(
Dir);
191 llvm::sys::path::append(
P, CLANG_INSTALL_LIBDIR_BASENAME,
"clang",
192 CLANG_VERSION_MAJOR_STRING);
195 return std::string(
P);
201 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
202 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
205 ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
206 DriverTitle(Title), CCCPrintBindings(
false), CCPrintOptions(
false),
207 CCLogDiagnostics(
false), CCGenDiagnostics(
false),
208 CCPrintProcessStats(
false), CCPrintInternalStats(
false),
209 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
210 CheckInputsExist(
true), ProbePrecompiled(
true),
211 SuppressMissingInputWarning(
false) {
214 this->VFS = llvm::vfs::getRealFileSystem();
219 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
222 llvm::sys::path::append(
P,
SysRoot);
226#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
227 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
231 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
232 llvm::sys::path::remove_dots(configFileDir,
true);
236#if defined(CLANG_CONFIG_FILE_USER_DIR)
239 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR,
P);
248void Driver::setDriverMode(StringRef
Value) {
249 static StringRef OptName =
250 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
251 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
252 .Case(
"gcc", GCCMode)
253 .Case(
"g++", GXXMode)
254 .Case(
"cpp", CPPMode)
256 .Case(
"flang", FlangMode)
257 .Case(
"dxc", DXCMode)
261 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
265 bool UseDriverMode,
bool &ContainsError) {
266 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
267 ContainsError =
false;
269 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
270 unsigned MissingArgIndex, MissingArgCount;
271 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
272 MissingArgCount, VisibilityMask);
275 if (MissingArgCount) {
276 Diag(diag::err_drv_missing_argument)
277 << Args.getArgString(MissingArgIndex) << MissingArgCount;
284 for (
const Arg *A : Args) {
286 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
294 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
295 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
297 diag::warn_drv_empty_joined_argument,
302 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
304 auto ArgString = A->getAsString(Args);
306 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
308 getOpts().findExact(ArgString, Nearest,
310 DiagID = diag::err_drv_unknown_argument_with_suggestion;
311 Diags.
Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
313 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
314 : diag::err_drv_unknown_argument;
315 Diags.
Report(DiagID) << ArgString;
319 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
320 : diag::err_drv_unknown_argument_with_suggestion;
321 Diags.
Report(DiagID) << ArgString << Nearest;
327 for (
const Arg *A : Args.filtered(options::OPT_o)) {
328 if (ArgStrings[A->getIndex()] == A->getSpelling())
332 std::string ArgString = ArgStrings[A->getIndex()];
334 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
335 Diags.
Report(diag::warn_drv_potentially_misspelled_joined_argument)
336 << A->getAsString(Args) << Nearest;
346 Arg **FinalPhaseArg)
const {
347 Arg *PhaseArg =
nullptr;
351 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
352 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
353 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
354 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
361 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
362 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
363 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
364 options::OPT_fmodule_header_EQ))) {
367 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
368 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
369 (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
370 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
371 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
372 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
373 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
374 (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
375 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
376 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
377 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
381 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
385 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
388 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
396 *FinalPhaseArg = PhaseArg;
402 StringRef
Value,
bool Claim =
true) {
403 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
404 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
405 Args.AddSynthesizedArg(A);
411DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
412 const llvm::opt::OptTable &Opts =
getOpts();
413 DerivedArgList *DAL =
new DerivedArgList(Args);
415 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
416 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
417 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
418 bool IgnoreUnused =
false;
419 for (Arg *A : Args) {
423 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
427 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
428 IgnoreUnused =
false;
438 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
439 A->getOption().matches(options::OPT_Xlinker)) &&
440 A->containsValue(
"--no-demangle")) {
442 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
445 for (StringRef Val : A->getValues())
446 if (Val !=
"--no-demangle")
447 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
455 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
456 A->getNumValues() > 0 &&
457 (A->getValue(0) == StringRef(
"-MD") ||
458 A->getValue(0) == StringRef(
"-MMD"))) {
460 if (A->getValue(0) == StringRef(
"-MD"))
461 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
463 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
464 if (A->getNumValues() == 2)
465 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
470 if (A->getOption().matches(options::OPT_l)) {
471 StringRef
Value = A->getValue();
474 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
476 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
481 if (
Value ==
"cc_kext") {
482 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
488 if (A->getOption().matches(options::OPT__DASH_DASH)) {
490 for (StringRef Val : A->getValues())
499 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
500 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
503 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
504 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
508#if defined(HOST_LINK_VERSION)
509 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
510 strlen(HOST_LINK_VERSION) > 0) {
511 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
513 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
525 StringRef TargetTriple,
527 StringRef DarwinArchName =
"") {
529 if (
const Arg *A = Args.getLastArg(options::OPT_target))
530 TargetTriple = A->getValue();
532 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
537 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
541 if (
Target.isOSBinFormatMachO()) {
543 if (!DarwinArchName.empty()) {
550 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
551 StringRef ArchName = A->getValue();
558 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
559 options::OPT_mbig_endian)) {
560 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
561 ?
Target.getLittleEndianArchVariant()
562 :
Target.getBigEndianArchVariant();
563 if (
T.getArch() != llvm::Triple::UnknownArch) {
565 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
570 if (
Target.getArch() == llvm::Triple::tce)
575 if (std::optional<std::string> ObjectModeValue =
576 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
577 StringRef ObjectMode = *ObjectModeValue;
578 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
580 if (ObjectMode ==
"64") {
581 AT =
Target.get64BitArchVariant().getArch();
582 }
else if (ObjectMode ==
"32") {
583 AT =
Target.get32BitArchVariant().getArch();
585 D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
588 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
594 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
596 D.Diag(diag::err_drv_unsupported_opt_for_target)
597 << A->getAsString(Args) <<
Target.str();
600 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
601 options::OPT_m32, options::OPT_m16,
602 options::OPT_maix32, options::OPT_maix64);
604 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
606 if (A->getOption().matches(options::OPT_m64) ||
607 A->getOption().matches(options::OPT_maix64)) {
608 AT =
Target.get64BitArchVariant().getArch();
609 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
610 Target.getEnvironment() == llvm::Triple::GNUT64)
611 Target.setEnvironment(llvm::Triple::GNU);
612 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
613 Target.setEnvironment(llvm::Triple::Musl);
614 }
else if (A->getOption().matches(options::OPT_mx32) &&
615 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
616 AT = llvm::Triple::x86_64;
617 if (
Target.getEnvironment() == llvm::Triple::Musl)
618 Target.setEnvironment(llvm::Triple::MuslX32);
620 Target.setEnvironment(llvm::Triple::GNUX32);
621 }
else if (A->getOption().matches(options::OPT_m32) ||
622 A->getOption().matches(options::OPT_maix32)) {
623 AT =
Target.get32BitArchVariant().getArch();
624 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
625 Target.setEnvironment(llvm::Triple::GNU);
626 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
627 Target.setEnvironment(llvm::Triple::Musl);
628 }
else if (A->getOption().matches(options::OPT_m16) &&
629 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
630 AT = llvm::Triple::x86;
631 Target.setEnvironment(llvm::Triple::CODE16);
634 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
636 if (
Target.isWindowsGNUEnvironment())
642 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
643 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
644 D.Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
647 if (A && !A->getOption().matches(options::OPT_m32))
648 D.Diag(diag::err_drv_argument_not_allowed_with)
649 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
651 Target.setArch(llvm::Triple::x86);
652 Target.setArchName(
"i586");
653 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
654 Target.setEnvironmentName(
"");
655 Target.setOS(llvm::Triple::ELFIAMCU);
656 Target.setVendor(llvm::Triple::UnknownVendor);
657 Target.setVendorName(
"intel");
663 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
664 StringRef ABIName = A->getValue();
665 if (ABIName ==
"32") {
667 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
668 Target.getEnvironment() == llvm::Triple::GNUABIN32)
669 Target.setEnvironment(llvm::Triple::GNU);
670 }
else if (ABIName ==
"n32") {
672 if (
Target.getEnvironment() == llvm::Triple::GNU ||
673 Target.getEnvironment() == llvm::Triple::GNUT64 ||
674 Target.getEnvironment() == llvm::Triple::GNUABI64)
675 Target.setEnvironment(llvm::Triple::GNUABIN32);
676 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
677 Target.getEnvironment() == llvm::Triple::MuslABI64)
678 Target.setEnvironment(llvm::Triple::MuslABIN32);
679 }
else if (ABIName ==
"64") {
681 if (
Target.getEnvironment() == llvm::Triple::GNU ||
682 Target.getEnvironment() == llvm::Triple::GNUT64 ||
683 Target.getEnvironment() == llvm::Triple::GNUABIN32)
684 Target.setEnvironment(llvm::Triple::GNUABI64);
685 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
686 Target.getEnvironment() == llvm::Triple::MuslABIN32)
687 Target.setEnvironment(llvm::Triple::MuslABI64);
695 if (Args.hasArg(options::OPT_march_EQ) ||
696 Args.hasArg(options::OPT_mcpu_EQ)) {
698 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
700 if (!llvm::errorToBool(ISAInfo.takeError())) {
701 unsigned XLen = (*ISAInfo)->getXLen();
703 Target.setArch(llvm::Triple::riscv32);
705 Target.setArch(llvm::Triple::riscv64);
717 OptSpecifier OptEq, OptSpecifier OptNeg) {
718 if (!Args.hasFlag(OptEq, OptNeg,
false))
721 const Arg *A = Args.getLastArg(OptEq);
722 StringRef LTOName = A->getValue();
730 D.Diag(diag::err_drv_unsupported_option_argument)
731 << A->getSpelling() << A->getValue();
738void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
740 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
742 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
743 options::OPT_fno_offload_lto);
746 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
747 options::OPT_fno_openmp_target_jit,
false)) {
748 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
749 options::OPT_fno_offload_lto))
751 Diag(diag::err_drv_incompatible_options)
752 << A->getSpelling() <<
"-fopenmp-target-jit";
759 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
761 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
763 RuntimeName = A->getValue();
765 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
773 Diag(diag::err_drv_unsupported_option_argument)
774 << A->getSpelling() << A->getValue();
777 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
792 llvm::any_of(Inputs, [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
797 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
800 C.getInputArgs().hasArg(options::OPT_hip_link) ||
801 C.getInputArgs().hasArg(options::OPT_hipstdpar);
802 bool UseLLVMOffload =
C.getInputArgs().hasArg(
803 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
804 if (IsCuda && IsHIP) {
805 Diag(clang::diag::err_drv_mix_cuda_hip);
808 if (IsCuda && !UseLLVMOffload) {
810 const llvm::Triple &HostTriple = HostTC->
getTriple();
818 auto &CudaTC = ToolChains[CudaTriple->str() +
"/" + HostTriple.str()];
820 CudaTC = std::make_unique<toolchains::CudaToolChain>(
821 *
this, *CudaTriple, *HostTC,
C.getInputArgs());
826 if (CudaInstallation.
isValid())
829 C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
830 }
else if (IsHIP && !UseLLVMOffload) {
831 if (
auto *OMPTargetArg =
832 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
833 Diag(clang::diag::err_drv_unsupported_opt_for_language_mode)
834 << OMPTargetArg->getSpelling() <<
"HIP";
842 auto *HIPTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), *HIPTriple,
844 assert(HIPTC &&
"Could not create offloading device tool chain.");
845 C.addOffloadDeviceToolChain(HIPTC, OFK);
853 bool IsOpenMPOffloading =
854 ((IsCuda || IsHIP) && UseLLVMOffload) ||
855 (
C.getInputArgs().hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
856 options::OPT_fno_openmp,
false) &&
857 (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ) ||
858 C.getInputArgs().hasArg(options::OPT_offload_arch_EQ)));
859 if (IsOpenMPOffloading) {
865 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
869 llvm::StringMap<llvm::DenseSet<StringRef>> DerivedArchs;
870 llvm::StringMap<StringRef> FoundNormalizedTriples;
871 std::multiset<StringRef> OpenMPTriples;
876 if (Arg *OpenMPTargets =
877 C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
878 if (OpenMPTargets && !OpenMPTargets->getNumValues()) {
879 Diag(clang::diag::warn_drv_empty_joined_argument)
880 << OpenMPTargets->getAsString(
C.getInputArgs());
883 for (StringRef
T : OpenMPTargets->getValues())
884 OpenMPTriples.insert(
T);
885 }
else if (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
886 ((!IsHIP && !IsCuda) || UseLLVMOffload)) {
896 llvm::DenseSet<StringRef> Archs;
898 auto TempTC = std::make_unique<toolchains::CudaToolChain>(
899 *
this, *NVPTXTriple, *HostTC,
C.getInputArgs());
905 auto TempTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
906 *
this, *AMDTriple, *HostTC,
C.getInputArgs());
911 if (!AMDTriple && !NVPTXTriple) {
912 for (StringRef Arch :
917 for (StringRef Arch : Archs) {
920 DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
921 }
else if (AMDTriple &&
924 DerivedArchs[AMDTriple->getTriple()].insert(Arch);
926 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
933 Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
938 for (
const auto &TripleAndArchs : DerivedArchs)
939 OpenMPTriples.insert(TripleAndArchs.first());
942 for (StringRef Val : OpenMPTriples) {
944 std::string NormalizedName = TT.normalize();
947 auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
948 if (Duplicate != FoundNormalizedTriples.end()) {
949 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
950 << Val << Duplicate->second;
956 FoundNormalizedTriples[NormalizedName] = Val;
959 if (TT.getArch() == llvm::Triple::UnknownArch)
960 Diag(clang::diag::err_drv_invalid_omp_target) << Val;
965 if (TT.isNVPTX() || TT.isAMDGCN()) {
968 assert(HostTC &&
"Host toolchain should be always defined.");
970 ToolChains[TT.str() +
"/" + HostTC->
getTriple().normalize()];
973 DeviceTC = std::make_unique<toolchains::CudaToolChain>(
974 *
this, TT, *HostTC,
C.getInputArgs());
975 else if (TT.isAMDGCN())
976 DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
977 *
this, TT, *HostTC,
C.getInputArgs());
979 assert(DeviceTC &&
"Device toolchain not defined.");
984 TC = &getToolChain(
C.getInputArgs(), TT);
986 auto It = DerivedArchs.find(TT.getTriple());
987 if (It != DerivedArchs.end())
988 KnownArchs[TC] = It->second;
991 }
else if (
C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
992 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1005 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1006 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1007 Copy->getValues() = Opt->getValues();
1008 if (Opt->isClaimed())
1010 Copy->setOwnsValues(Opt->getOwnsValues());
1011 Opt->setOwnsValues(
false);
1013 if (Opt->getAlias()) {
1014 const Arg *Alias = Opt->getAlias();
1015 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1016 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1017 Args.getArgString(Index), Index);
1018 AliasCopy->getValues() = Alias->getValues();
1019 AliasCopy->setOwnsValues(
false);
1020 if (Alias->isClaimed())
1022 Copy->setAlias(std::move(AliasCopy));
1026bool Driver::readConfigFile(StringRef
FileName,
1027 llvm::cl::ExpansionContext &ExpCtx) {
1031 Diag(diag::err_drv_cannot_open_config_file)
1032 <<
FileName << Status.getError().message();
1035 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1036 Diag(diag::err_drv_cannot_open_config_file)
1037 <<
FileName <<
"not a regular file";
1043 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1044 Diag(diag::err_drv_cannot_read_config_file)
1051 for (
const char *Opt : NewCfgFileArgs) {
1053 if (Opt[0] ==
'$' && Opt[1])
1054 NewCfgTailArgs.push_back(Opt + 1);
1056 NewCfgHeadArgs.push_back(Opt);
1061 llvm::sys::path::native(CfgFileName);
1062 bool ContainErrors =
false;
1063 auto NewHeadOptions = std::make_unique<InputArgList>(
1067 auto NewTailOptions = std::make_unique<InputArgList>(
1074 for (Arg *A : *NewHeadOptions)
1076 for (Arg *A : *NewTailOptions)
1079 if (!CfgOptionsHead)
1080 CfgOptionsHead = std::move(NewHeadOptions);
1083 for (
auto *Opt : *NewHeadOptions)
1087 if (!CfgOptionsTail)
1088 CfgOptionsTail = std::move(NewTailOptions);
1091 for (
auto *Opt : *NewTailOptions)
1095 ConfigFiles.push_back(std::string(CfgFileName));
1099bool Driver::loadConfigFiles() {
1100 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1101 llvm::cl::tokenizeConfigFile);
1102 ExpCtx.setVFS(&
getVFS());
1106 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1109 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1110 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1115 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1117 llvm::sys::fs::expand_tilde(
1118 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1119 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1128 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1131 if (loadDefaultConfigFiles(ExpCtx))
1137 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1140 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1141 CfgFilePath.assign(CfgFileName);
1142 if (llvm::sys::path::is_relative(CfgFilePath)) {
1143 if (
getVFS().makeAbsolute(CfgFilePath)) {
1144 Diag(diag::err_drv_cannot_open_config_file)
1145 << CfgFilePath <<
"cannot get absolute path";
1149 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1151 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1152 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1153 if (!SearchDir.empty())
1154 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1159 if (readConfigFile(CfgFilePath, ExpCtx))
1170 llvm::Triple Triple, std::string Suffix) {
1172 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1176 VersionTuple OSVersion = Triple.getOSVersion();
1177 if (!OSVersion.getMinor().has_value())
1180 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1184 if (OSVersion.getMajor() != 0) {
1185 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1186 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1192 Triple.setOSName(BaseOSName);
1193 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1196bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1199 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1203 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1206 std::string RealMode = getExecutableForDriverMode(Mode);
1207 llvm::Triple Triple;
1216 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1217 PrefixTriple.isOSUnknown())
1218 Triple = PrefixTriple;
1222 if (Triple.str().empty()) {
1224 assert(!Triple.str().empty());
1240 "-" + RealMode +
".cfg"))
1241 return readConfigFile(CfgFilePath, ExpCtx);
1245 if (TryModeSuffix) {
1248 return readConfigFile(CfgFilePath, ExpCtx);
1253 std::string CfgFileName = RealMode +
".cfg";
1254 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1255 if (readConfigFile(CfgFilePath, ExpCtx))
1257 }
else if (TryModeSuffix) {
1259 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1260 readConfigFile(CfgFilePath, ExpCtx))
1266 return readConfigFile(CfgFilePath, ExpCtx);
1274 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1283 if (!DriverMode.empty())
1284 setDriverMode(DriverMode);
1290 CLOptions = std::make_unique<InputArgList>(
1295 ContainsError = loadConfigFiles();
1296 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1297 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1301 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1303 if (HasConfigFileHead)
1304 for (
auto *Opt : *CLOptions)
1305 if (!Opt->getOption().matches(options::OPT_config))
1309 if (
IsCLMode() && !ContainsError) {
1311 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1313 CLModePassThroughArgList.push_back(A->getValue());
1316 if (!CLModePassThroughArgList.empty()) {
1319 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1324 for (
auto *Opt : *CLModePassThroughOptions)
1330 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1331 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1332 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1336 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1337 if (!VFS->exists(IncludeDir))
1338 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1343 bool CCCPrintPhases;
1346 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1347 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1350 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1351 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1354 Args.ClaimAllArgs(options::OPT_pipe);
1362 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1364 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1365 CCCGenericGCCName = A->getValue();
1368 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1372 if (Args.hasArg(options::OPT_fproc_stat_report))
1379 llvm::Triple
T(TargetTriple);
1380 T.setOS(llvm::Triple::Win32);
1381 T.setVendor(llvm::Triple::PC);
1382 T.setEnvironment(llvm::Triple::MSVC);
1383 T.setObjectFormat(llvm::Triple::COFF);
1384 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1385 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1386 TargetTriple =
T.str();
1389 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1390 StringRef TargetProfile = A->getValue();
1393 TargetTriple = *Triple;
1395 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1399 if (Args.hasArg(options::OPT_spirv)) {
1400 llvm::Triple
T(TargetTriple);
1401 T.setArch(llvm::Triple::spirv);
1402 T.setOS(llvm::Triple::Vulkan);
1405 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1406 const llvm::StringSet<> ValidValues = {
"vulkan1.2",
"vulkan1.3"};
1407 if (ValidValues.contains(A->getValue())) {
1408 T.setOSName(A->getValue());
1410 Diag(diag::err_drv_invalid_value)
1411 << A->getAsString(Args) << A->getValue();
1416 TargetTriple =
T.str();
1419 Diag(diag::err_drv_dxc_missing_target_profile);
1423 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1424 TargetTriple = A->getValue();
1425 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1426 Dir =
Dir = A->getValue();
1427 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1431 if (std::optional<std::string> CompilerPathValue =
1432 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1433 StringRef CompilerPath = *CompilerPathValue;
1434 while (!CompilerPath.empty()) {
1435 std::pair<StringRef, StringRef> Split =
1436 CompilerPath.split(llvm::sys::EnvPathSeparator);
1437 PrefixDirs.push_back(std::string(Split.first));
1438 CompilerPath = Split.second;
1441 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1443 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1446 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1449 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1450 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1451 .Case(
"cwd", SaveTempsCwd)
1452 .Case(
"obj", SaveTempsObj)
1453 .Default(SaveTempsCwd);
1456 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1457 options::OPT_offload_device_only,
1458 options::OPT_offload_host_device)) {
1459 if (A->getOption().matches(options::OPT_offload_host_only))
1460 Offload = OffloadHost;
1461 else if (A->getOption().matches(options::OPT_offload_device_only))
1462 Offload = OffloadDevice;
1464 Offload = OffloadHostDevice;
1470 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1471 StringRef
Name = A->getValue();
1472 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1473 .Case(
"off", EmbedNone)
1474 .Case(
"all", EmbedBitcode)
1475 .Case(
"bitcode", EmbedBitcode)
1476 .Case(
"marker", EmbedMarker)
1479 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1482 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1486 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1487 llvm::sys::fs::remove(A->getValue());
1493 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ);
1495 !Args.hasArg(options::OPT_fmodules) &&
Std &&
1496 (
Std->containsValue(
"c++20") ||
Std->containsValue(
"c++2a") ||
1497 Std->containsValue(
"c++23") ||
Std->containsValue(
"c++2b") ||
1498 Std->containsValue(
"c++26") ||
Std->containsValue(
"c++2c") ||
1499 Std->containsValue(
"c++latest"));
1502 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1503 options::OPT_fmodule_header)) {
1505 ModulesModeCXX20 =
true;
1506 if (A->getOption().matches(options::OPT_fmodule_header))
1509 StringRef ArgName = A->getValue();
1510 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1515 Diags.
Report(diag::err_drv_invalid_value)
1516 << A->getAsString(Args) << ArgName;
1522 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1523 std::make_unique<InputArgList>(std::move(Args));
1526 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1534 if (!Triple.isWasm()) {
1535 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1536 StringRef TripleObjectFormat =
1537 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1538 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1539 TripleVersionName != TripleObjectFormat) {
1540 Diags.
Report(diag::err_drv_triple_version_invalid)
1542 ContainsError =
true;
1547 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1548 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1549 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1557 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1558 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1560 case llvm::Triple::arm:
1561 case llvm::Triple::armeb:
1562 case llvm::Triple::thumb:
1563 case llvm::Triple::thumbeb:
1564 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1565 Diag(diag::warn_target_unrecognized_env)
1567 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1570 case llvm::Triple::aarch64:
1571 case llvm::Triple::aarch64_be:
1572 case llvm::Triple::aarch64_32:
1573 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1574 Diag(diag::warn_target_unrecognized_env)
1576 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1593 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1594 if (HasConfigFileTail && Inputs.size()) {
1597 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1598 for (Arg *A : *CfgOptionsTail)
1599 TranslatedLinkerIns.append(A);
1600 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1609 if (TC.
getTriple().isOSBinFormatMachO())
1614 if (CCCPrintPhases) {
1625 llvm::opt::ArgStringList ASL;
1626 for (
const auto *A : Args) {
1630 while (A->getAlias())
1632 A->render(Args, ASL);
1635 for (
auto I = ASL.begin(),
E = ASL.end(); I !=
E; ++I) {
1636 if (I != ASL.begin())
1638 llvm::sys::printArg(OS, *I,
true);
1643bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1645 using namespace llvm::sys;
1646 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1647 "Only knows about .crash files on Darwin");
1652 path::home_directory(CrashDiagDir);
1653 if (CrashDiagDir.starts_with(
"/var/root"))
1655 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1663 fs::file_status FileStatus;
1664 TimePoint<> LastAccessTime;
1668 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1669 File != FileEnd && !EC;
File.increment(EC)) {
1673 if (fs::status(
File->path(), FileStatus))
1675 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1676 llvm::MemoryBuffer::getFile(
File->path());
1681 StringRef
Data = CrashFile.get()->getBuffer();
1682 if (!
Data.starts_with(
"Process:"))
1685 size_t ParentProcPos =
Data.find(
"Parent Process:");
1686 if (ParentProcPos == StringRef::npos)
1688 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1689 if (LineEnd == StringRef::npos)
1691 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1692 int OpenBracket = -1, CloseBracket = -1;
1693 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1694 if (ParentProcess[i] ==
'[')
1696 if (ParentProcess[i] ==
']')
1702 if (OpenBracket < 0 || CloseBracket < 0 ||
1703 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1704 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1714 const auto FileAccessTime = FileStatus.getLastModificationTime();
1715 if (FileAccessTime > LastAccessTime) {
1716 CrashFilePath.assign(
File->path());
1717 LastAccessTime = FileAccessTime;
1722 if (!CrashFilePath.empty()) {
1723 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1733 "\n********************\n\n"
1734 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1735 "Preprocessed source(s) and associated run script(s) are located at:";
1743 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1747 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1748 Level = llvm::StringSwitch<unsigned>(A->getValue())
1750 .Case(
"compiler", 1)
1762 ArgStringList SavedTemps;
1764 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1765 if (!IsLLD || Level < 2)
1772 SavedTemps = std::move(
C.getTempFiles());
1773 assert(!
C.getTempFiles().size());
1790 C.initCompilationForDiagnostics();
1796 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
1797 StringRef ReproduceOption =
1798 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
1801 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
1805 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
1807 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
1808 Diag(clang::diag::note_drv_command_failed_diag_msg)
1809 <<
"\n\n********************";
1811 Report->TemporaryFiles.push_back(TmpName);
1819 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
1820 bool IgnoreInput =
false;
1826 }
else if (!strcmp(it->second->getValue(),
"-")) {
1827 Diag(clang::diag::note_drv_command_failed_diag_msg)
1828 <<
"Error generating preprocessed source(s) - "
1829 "ignoring input from stdin.";
1834 it = Inputs.erase(it);
1841 if (Inputs.empty()) {
1842 Diag(clang::diag::note_drv_command_failed_diag_msg)
1843 <<
"Error generating preprocessed source(s) - "
1844 "no preprocessable inputs.";
1850 llvm::StringSet<> ArchNames;
1851 for (
const Arg *A :
C.getArgs()) {
1852 if (A->getOption().matches(options::OPT_arch)) {
1853 StringRef ArchName = A->getValue();
1854 ArchNames.insert(ArchName);
1857 if (ArchNames.size() > 1) {
1858 Diag(clang::diag::note_drv_command_failed_diag_msg)
1859 <<
"Error generating preprocessed source(s) - cannot generate "
1860 "preprocessed source with multiple -arch options.";
1866 const ToolChain &TC =
C.getDefaultToolChain();
1867 if (TC.
getTriple().isOSBinFormatMachO())
1876 Diag(clang::diag::note_drv_command_failed_diag_msg)
1877 <<
"Error generating preprocessed source(s).";
1883 C.ExecuteJobs(
C.getJobs(), FailingCommands);
1886 if (!FailingCommands.empty()) {
1887 Diag(clang::diag::note_drv_command_failed_diag_msg)
1888 <<
"Error generating preprocessed source(s).";
1892 const ArgStringList &TempFiles =
C.getTempFiles();
1893 if (TempFiles.empty()) {
1894 Diag(clang::diag::note_drv_command_failed_diag_msg)
1895 <<
"Error generating preprocessed source(s).";
1903 for (
const char *TempFile : TempFiles) {
1904 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
1906 Report->TemporaryFiles.push_back(TempFile);
1907 if (ReproCrashFilename.empty()) {
1908 ReproCrashFilename = TempFile;
1909 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
1911 if (StringRef(TempFile).ends_with(
".cache")) {
1914 VFS = llvm::sys::path::filename(TempFile);
1915 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
1919 for (
const char *TempFile : SavedTemps)
1920 C.addTempFile(TempFile);
1926 llvm::sys::path::replace_extension(Script,
"sh");
1928 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
1929 llvm::sys::fs::FA_Write,
1930 llvm::sys::fs::OF_Text);
1932 Diag(clang::diag::note_drv_command_failed_diag_msg)
1933 <<
"Error generating run script: " << Script <<
" " << EC.message();
1936 <<
"# Driver args: ";
1938 ScriptOS <<
"# Original command: ";
1939 Cmd.Print(ScriptOS,
"\n",
true);
1940 Cmd.Print(ScriptOS,
"\n",
true, &CrashInfo);
1941 if (!AdditionalInformation.empty())
1942 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
1945 Report->TemporaryFiles.push_back(std::string(Script));
1946 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
1950 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
1952 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
1953 Diag(clang::diag::note_drv_command_failed_diag_msg)
1954 << ReproCrashFilename.str();
1956 llvm::sys::path::append(CrashDiagDir,
Name);
1957 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
1958 Diag(clang::diag::note_drv_command_failed_diag_msg)
1959 <<
"Crash backtrace is located in";
1960 Diag(clang::diag::note_drv_command_failed_diag_msg)
1961 << CrashDiagDir.str();
1962 Diag(clang::diag::note_drv_command_failed_diag_msg)
1963 <<
"(choose the .crash file that corresponds to your crash)";
1967 Diag(clang::diag::note_drv_command_failed_diag_msg)
1968 <<
"\n\n********************";
1976 if (
Cmd.getResponseFileSupport().ResponseKind ==
1978 llvm::sys::commandLineFitsWithinSystemLimits(
Cmd.getExecutable(),
1979 Cmd.getArguments()))
1983 Cmd.setResponseFile(
C.addTempFile(
C.getArgs().MakeArgString(TmpName)));
1989 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
1990 if (
C.getArgs().hasArg(options::OPT_v))
1991 C.getJobs().Print(llvm::errs(),
"\n",
true);
1993 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2003 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2004 C.getJobs().Print(llvm::errs(),
"\n",
true);
2013 for (
auto &Job :
C.getJobs())
2014 setUpResponseFiles(
C, Job);
2016 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2019 if (FailingCommands.empty())
2025 for (
const auto &CmdPair : FailingCommands) {
2026 int CommandRes = CmdPair.first;
2027 const Command *FailingCommand = CmdPair.second;
2032 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2036 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2041 if (CommandRes == EX_IOERR) {
2058 Diag(clang::diag::err_drv_command_signalled)
2061 Diag(clang::diag::err_drv_command_failed)
2069 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2071 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2085 const ToolChain &TC =
C.getDefaultToolChain();
2089 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2092 OS <<
"Thread model: " << A->getValue();
2098 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2103 if (!llvm::cl::getCompilerBuildConfig().empty())
2104 llvm::cl::printBuildConfig(OS);
2107 for (
auto ConfigFile : ConfigFiles)
2108 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2121 if (PassedFlags ==
"")
2125 std::vector<std::string> SuggestedCompletions;
2126 std::vector<std::string> Flags;
2138 const bool HasSpace = PassedFlags.ends_with(
",");
2142 StringRef TargetFlags = PassedFlags;
2143 while (TargetFlags !=
"") {
2145 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2146 Flags.push_back(std::string(CurFlag));
2151 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2154 const llvm::opt::OptTable &Opts =
getOpts();
2156 Cur = Flags.at(Flags.size() - 1);
2158 if (Flags.size() >= 2) {
2159 Prev = Flags.at(Flags.size() - 2);
2160 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2163 if (SuggestedCompletions.empty())
2164 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2171 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2172 llvm::outs() <<
'\n';
2178 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2182 SuggestedCompletions = Opts.findByPrefix(
2183 Cur, VisibilityMask,
2190 if (S.starts_with(Cur))
2191 SuggestedCompletions.push_back(std::string(S));
2198 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2199 if (
int X = A.compare_insensitive(B))
2201 return A.compare(B) > 0;
2204 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2211 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2212 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2216 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2219 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2223 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2228 if (
C.getArgs().hasArg(options::OPT_help) ||
2229 C.getArgs().hasArg(options::OPT__help_hidden)) {
2230 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2234 if (
C.getArgs().hasArg(options::OPT__version)) {
2240 if (
C.getArgs().hasArg(options::OPT_v) ||
2241 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2242 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2243 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2244 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2246 SuppressMissingInputWarning =
true;
2249 if (
C.getArgs().hasArg(options::OPT_v)) {
2251 llvm::errs() <<
"System configuration file directory: "
2254 llvm::errs() <<
"User configuration file directory: "
2258 const ToolChain &TC =
C.getDefaultToolChain();
2260 if (
C.getArgs().hasArg(options::OPT_v))
2263 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2268 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2269 llvm::outs() <<
"programs: =";
2270 bool separator =
false;
2274 llvm::outs() << llvm::sys::EnvPathSeparator;
2275 llvm::outs() <<
Path;
2280 llvm::outs() << llvm::sys::EnvPathSeparator;
2281 llvm::outs() <<
Path;
2284 llvm::outs() <<
"\n";
2287 StringRef sysroot =
C.getSysRoot();
2291 llvm::outs() << llvm::sys::EnvPathSeparator;
2294 llvm::outs() << sysroot <<
Path.substr(1);
2296 llvm::outs() <<
Path;
2298 llvm::outs() <<
"\n";
2302 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2308 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2309 if (std::optional<std::string> RuntimePath = TC.
getRuntimePath())
2310 llvm::outs() << *RuntimePath <<
'\n';
2316 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2318 for (std::size_t I = 0; I != Flags.size(); I += 2)
2319 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2325 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2326 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2330 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2331 StringRef ProgName = A->getValue();
2334 if (! ProgName.empty())
2337 llvm::outs() <<
"\n";
2341 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2342 StringRef PassedFlags = A->getValue();
2347 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2361 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2364 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2370 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2377 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2380 std::set<llvm::StringRef> SortedFlags;
2381 for (
const auto &FlagEntry : ExpandedFlags)
2382 SortedFlags.insert(FlagEntry.getKey());
2383 for (
auto Flag : SortedFlags)
2384 llvm::outs() << Flag <<
'\n';
2388 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2391 llvm::outs() <<
".\n";
2394 assert(Suffix.front() ==
'/');
2395 llvm::outs() << Suffix.substr(1) <<
"\n";
2401 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2406 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2408 llvm::outs() << Triple.getTriple() <<
"\n";
2412 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2413 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2430 std::map<Action *, unsigned> &Ids,
2436 llvm::raw_string_ostream os(str);
2438 auto getSibIndent = [](
int K) -> Twine {
2442 Twine SibIndent = Indent + getSibIndent(Kind);
2446 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2448 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2449 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2450 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2451 bool IsFirst =
true;
2452 OA->doOnEachDependence(
2454 assert(TC &&
"Unknown host toolchain");
2466 os <<
":" << BoundArch;
2469 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2477 const char *Prefix =
"{";
2478 for (
Action *PreRequisite : *AL) {
2479 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2490 std::string offload_str;
2491 llvm::raw_string_ostream offload_os(offload_str);
2492 if (!isa<OffloadAction>(A)) {
2495 offload_os <<
", (" << S;
2502 auto getSelfIndent = [](
int K) -> Twine {
2506 unsigned Id = Ids.size();
2508 llvm::errs() << Indent + getSelfIndent(Kind) <<
Id <<
": " << os.str() <<
", "
2517 std::map<Action *, unsigned> Ids;
2518 for (
Action *A :
C.getActions())
2525 if (isa<CompileJobAction>(A) || isa<BackendJobAction>(A) ||
2526 isa<AssembleJobAction>(A))
2534 DerivedArgList &Args =
C.getArgs();
2536 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2539 llvm::StringSet<> ArchNames;
2541 for (Arg *A : Args) {
2542 if (A->getOption().matches(options::OPT_arch)) {
2545 llvm::Triple::ArchType Arch =
2547 if (Arch == llvm::Triple::UnknownArch) {
2548 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2553 if (ArchNames.insert(A->getValue()).second)
2554 Archs.push_back(A->getValue());
2568 for (
Action* Act : SingleActions) {
2576 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2580 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2585 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2586 Actions.append(Inputs.begin(), Inputs.end());
2588 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2591 Arg *A = Args.getLastArg(options::OPT_g_Group);
2592 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2593 !A->getOption().matches(options::OPT_gstabs);
2601 if (Act->getType() == types::TY_Image) {
2603 Inputs.push_back(Actions.back());
2610 if (Args.hasArg(options::OPT_verify_debug_info)) {
2611 Action* LastAction = Actions.back();
2614 LastAction, types::TY_Nothing));
2633 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2634 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2646 std::string Nearest;
2647 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2648 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2649 <<
Value << Nearest;
2688 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2691 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2699 return types::TY_CXXUHeader;
2701 return types::TY_CXXSHeader;
2705 llvm_unreachable(
"should not be called in this case");
2707 return types::TY_CXXHUHeader;
2713 const llvm::opt::OptTable &Opts =
getOpts();
2717 types::ID InputType = types::TY_Nothing;
2718 Arg *InputTypeArg =
nullptr;
2721 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2722 options::OPT__SLASH_TP)) {
2723 InputTypeArg = TCTP;
2724 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2729 bool ShowNote =
false;
2731 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2733 Diag(clang::diag::warn_drv_overriding_option)
2734 <<
Previous->getSpelling() << A->getSpelling();
2740 Diag(clang::diag::note_drv_t_option_is_global);
2745 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2746 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2747 if (LastXArg && LastInputArg &&
2748 LastInputArg->getIndex() < LastXArg->getIndex())
2749 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
2752 for (Arg *A : Args) {
2753 if (A->getOption().
getKind() == Option::InputClass) {
2754 const char *
Value = A->getValue();
2758 if (InputType == types::TY_Nothing) {
2761 InputTypeArg->claim();
2764 if (memcmp(
Value,
"-", 2) == 0) {
2766 Ty = types::TY_Fortran;
2768 Ty = types::TY_HLSL;
2777 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
2778 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
2779 : clang::diag::err_drv_unknown_stdin_type);
2788 if (
const char *Ext = strrchr(
Value,
'.'))
2797 Ty = types::TY_Object;
2808 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
2809 Diag(clang::diag::warn_drv_treating_input_as_cxx)
2810 << getTypeName(OldTy) << getTypeName(Ty);
2815 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
2816 Ty == types::TY_Object)
2817 Ty = types::TY_LLVM_BC;
2825 if (Ty != types::TY_Object) {
2826 if (Args.hasArg(options::OPT_ObjC))
2827 Ty = types::TY_ObjC;
2828 else if (Args.hasArg(options::OPT_ObjCXX))
2829 Ty = types::TY_ObjCXX;
2836 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
2840 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
2841 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
2844 const char *Ext = strrchr(
Value,
'.');
2846 Ty = types::TY_Object;
2850 InputTypeArg->claim();
2854 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
2855 Args.hasArgNoClaim(options::OPT_hipstdpar))
2859 Inputs.push_back(std::make_pair(Ty, A));
2861 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
2862 StringRef
Value = A->getValue();
2865 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2866 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
2869 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
2870 StringRef
Value = A->getValue();
2873 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
2874 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
2880 Inputs.push_back(std::make_pair(types::TY_Object, A));
2882 }
else if (A->getOption().matches(options::OPT_x)) {
2891 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
2892 InputType = types::TY_Object;
2899 }
else if (A->getOption().getID() == options::OPT_U) {
2900 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
2901 StringRef Val = A->getValue(0);
2902 if (Val.find_first_of(
"/\\") != StringRef::npos) {
2904 Diag(diag::warn_slash_u_filename) << Val;
2905 Diag(diag::note_use_dashdash);
2909 if (
CCCIsCPP() && Inputs.empty()) {
2913 Inputs.push_back(std::make_pair(types::TY_C, A));
2920class OffloadingActionBuilder final {
2922 bool IsValid =
false;
2928 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
2931 std::map<Action *, const Arg *> HostActionToInputArgMap;
2934 class DeviceActionBuilder {
2938 enum ActionBuilderReturnCode {
2957 DerivedArgList &Args;
2966 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
2969 :
C(
C), Args(Args), Inputs(Inputs),
2970 AssociatedOffloadKind(AssociatedOffloadKind) {}
2971 virtual ~DeviceActionBuilder() {}
2976 virtual ActionBuilderReturnCode
2980 return ABRT_Inactive;
2985 virtual ActionBuilderReturnCode addDeviceDependences(
Action *HostAction) {
2986 return ABRT_Inactive;
2990 virtual void appendTopLevelActions(
ActionList &AL) {}
2993 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3006 virtual bool canUseBundlerUnbundler()
const {
return false; }
3010 bool isValid() {
return !ToolChains.empty(); }
3014 return AssociatedOffloadKind;
3020 class CudaActionBuilderBase :
public DeviceActionBuilder {
3024 bool CompileHostOnly =
false;
3025 bool CompileDeviceOnly =
false;
3027 bool EmitAsm =
false;
3037 TargetID(
const char *
ID) :
ID(
ID) {}
3038 operator const char *() {
return ID; }
3039 operator StringRef() {
return StringRef(
ID); }
3048 Action *CudaFatBinary =
nullptr;
3051 bool IsActive =
false;
3054 bool Relocatable =
false;
3057 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3061 enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
3062 UseCUIDKind UseCUID = CUID_Hash;
3065 StringRef FixedCUID;
3068 CudaActionBuilderBase(
Compilation &
C, DerivedArgList &Args,
3071 : DeviceActionBuilder(
C, Args, Inputs, OFKind) {
3073 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3074 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3075 options::OPT_fno_gpu_rdc,
false);
3078 ActionBuilderReturnCode addDeviceDependences(
Action *HostAction)
override {
3085 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3086 assert(!GpuArchList.empty() &&
3087 "We should have at least one GPU architecture.");
3091 if (!(IA->getType() == types::TY_CUDA ||
3092 IA->getType() == types::TY_HIP ||
3093 IA->getType() == types::TY_PP_HIP)) {
3096 return ABRT_Inactive;
3102 std::string CUID = FixedCUID.str();
3104 if (UseCUID == CUID_Random)
3105 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
3107 else if (UseCUID == CUID_Hash) {
3109 llvm::MD5::MD5Result Hash;
3111 llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
3113 Hasher.update(RealPath);
3114 for (
auto *A : Args) {
3115 if (A->getOption().matches(options::OPT_INPUT))
3117 Hasher.update(A->getAsString(Args));
3120 CUID = llvm::utohexstr(Hash.low(),
true);
3125 if (CompileHostOnly)
3126 return ABRT_Success;
3129 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3130 : types::TY_CUDA_DEVICE;
3131 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3132 CudaDeviceActions.push_back(
3133 C.MakeAction<
InputAction>(IA->getInputArg(), Ty, IA->getId()));
3136 return ABRT_Success;
3140 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3144 if (UA->getType() == types::TY_Object && !Relocatable)
3145 return ABRT_Inactive;
3147 CudaDeviceActions.clear();
3148 auto *IA = cast<InputAction>(UA->getInputs().back());
3149 std::string
FileName = IA->getInputArg().getAsString(Args);
3155 const StringRef LibFileExt =
".lib";
3156 if (IA->getType() == types::TY_Object &&
3157 (!llvm::sys::path::has_extension(
FileName) ||
3159 llvm::sys::path::extension(
FileName).drop_front()) !=
3161 llvm::sys::path::extension(
FileName) == LibFileExt))
3162 return ABRT_Inactive;
3164 for (
auto Arch : GpuArchList) {
3165 CudaDeviceActions.push_back(UA);
3166 UA->registerDependentActionInfo(ToolChains[0], Arch,
3167 AssociatedOffloadKind);
3170 return ABRT_Success;
3173 return IsActive ? ABRT_Success : ABRT_Inactive;
3176 void appendTopLevelActions(
ActionList &AL)
override {
3178 auto AddTopLevel = [&](
Action *A, TargetID TargetID) {
3180 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3185 if (CudaFatBinary) {
3186 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3187 CudaDeviceActions.clear();
3188 CudaFatBinary =
nullptr;
3192 if (CudaDeviceActions.empty())
3198 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3199 "Expecting one action per GPU architecture.");
3200 assert(ToolChains.size() == 1 &&
3201 "Expecting to have a single CUDA toolchain.");
3202 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I)
3203 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3205 CudaDeviceActions.clear();
3210 virtual StringRef getCanonicalOffloadArch(StringRef Arch) = 0;
3212 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3230 assert(HostTC &&
"No toolchain for host compilation.");
3232 HostTC->
getTriple().getArch() == llvm::Triple::amdgcn) {
3236 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3241 ToolChains.push_back(
3246 CompileHostOnly =
C.getDriver().offloadHostOnly();
3247 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3248 EmitAsm = Args.getLastArg(options::OPT_S);
3249 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3250 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3251 StringRef UseCUIDStr = A->getValue();
3252 UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3253 .Case(
"hash", CUID_Hash)
3254 .Case(
"random", CUID_Random)
3255 .Case(
"none", CUID_None)
3256 .Default(CUID_Invalid);
3257 if (UseCUID == CUID_Invalid) {
3258 C.getDriver().Diag(diag::err_drv_invalid_value)
3259 << A->getAsString(Args) << UseCUIDStr;
3260 C.setContainsError();
3266 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
3267 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
3268 options::OPT_no_offload_arch_EQ)) {
3269 C.getDriver().Diag(diag::err_opt_not_valid_with_opt) <<
"--offload-arch"
3274 std::set<StringRef> GpuArchs;
3276 for (Arg *A : Args) {
3277 if (!(A->getOption().matches(options::OPT_offload_arch_EQ) ||
3278 A->getOption().matches(options::OPT_no_offload_arch_EQ)))
3282 for (StringRef ArchStr : llvm::split(A->getValue(),
",")) {
3283 if (A->getOption().matches(options::OPT_no_offload_arch_EQ) &&
3286 }
else if (ArchStr ==
"native") {
3287 const ToolChain &TC = *ToolChains.front();
3288 auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args);
3291 << llvm::Triple::getArchTypeName(TC.
getArch())
3292 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
3296 for (
auto GPU : *GPUsOrErr) {
3297 GpuArchs.insert(Args.MakeArgString(GPU));
3300 ArchStr = getCanonicalOffloadArch(ArchStr);
3301 if (ArchStr.empty()) {
3303 }
else if (A->getOption().matches(options::OPT_offload_arch_EQ))
3304 GpuArchs.insert(ArchStr);
3305 else if (A->getOption().matches(options::OPT_no_offload_arch_EQ))
3306 GpuArchs.erase(ArchStr);
3308 llvm_unreachable(
"Unexpected option.");
3314 if (ConflictingArchs) {
3315 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
3316 << ConflictingArchs->first << ConflictingArchs->second;
3317 C.setContainsError();
3322 for (
auto Arch : GpuArchs)
3323 GpuArchList.push_back(Arch.data());
3328 if (GpuArchList.empty()) {
3329 if (ToolChains.front()->getTriple().isSPIRV()) {
3330 if (ToolChains.front()->getTriple().getVendor() == llvm::Triple::AMD)
3331 GpuArchList.push_back(OffloadArch::AMDGCNSPIRV);
3333 GpuArchList.push_back(OffloadArch::Generic);
3335 GpuArchList.push_back(DefaultOffloadArch);
3345 class CudaActionBuilder final :
public CudaActionBuilderBase {
3347 CudaActionBuilder(
Compilation &
C, DerivedArgList &Args,
3349 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_Cuda) {
3350 DefaultOffloadArch = OffloadArch::CudaDefault;
3353 StringRef getCanonicalOffloadArch(StringRef ArchStr)
override {
3356 C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr;
3362 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3364 const std::set<StringRef> &GpuArchs)
override {
3365 return std::nullopt;
3368 ActionBuilderReturnCode
3371 PhasesTy &Phases)
override {
3373 return ABRT_Inactive;
3377 if (CudaDeviceActions.empty())
3378 return ABRT_Success;
3380 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3381 "Expecting one action per GPU architecture.");
3382 assert(!CompileHostOnly &&
3383 "Not expecting CUDA actions in host-only compilation.");
3393 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3396 for (
auto Ph : Phases) {
3401 if (Ph > FinalPhase)
3404 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3414 if (!isa<AssembleJobAction>(CudaDeviceActions[I]) ||
3418 Action *AssembleAction = CudaDeviceActions[I];
3419 assert(AssembleAction->
getType() == types::TY_Object);
3420 assert(AssembleAction->
getInputs().size() == 1);
3428 DeviceActions.push_back(
3434 if (!DeviceActions.empty()) {
3436 C.MakeAction<
LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3438 if (!CompileDeviceOnly) {
3439 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3443 CudaFatBinary =
nullptr;
3448 CudaDeviceActions.clear();
3452 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3457 return ABRT_Success;
3461 "instructions should only occur "
3462 "before the backend phase!");
3465 for (
Action *&A : CudaDeviceActions)
3466 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3468 return ABRT_Success;
3473 class HIPActionBuilder final :
public CudaActionBuilderBase {
3481 std::optional<bool> BundleOutput;
3482 std::optional<bool> EmitReloc;
3487 : CudaActionBuilderBase(
C, Args, Inputs,
Action::OFK_HIP) {
3489 DefaultOffloadArch = OffloadArch::HIPDefault;
3491 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3492 options::OPT_fno_hip_emit_relocatable)) {
3493 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3494 options::OPT_fno_hip_emit_relocatable,
false);
3498 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3499 <<
"-fhip-emit-relocatable"
3503 if (!CompileDeviceOnly) {
3504 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3505 <<
"-fhip-emit-relocatable"
3506 <<
"--cuda-device-only";
3511 if (Args.hasArg(options::OPT_gpu_bundle_output,
3512 options::OPT_no_gpu_bundle_output))
3513 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3514 options::OPT_no_gpu_bundle_output,
true) &&
3515 (!EmitReloc || !*EmitReloc);
3518 bool canUseBundlerUnbundler()
const override {
return true; }
3520 StringRef getCanonicalOffloadArch(StringRef IdStr)
override {
3521 llvm::StringMap<bool> Features;
3525 (IdStr ==
"amdgcnspirv")
3526 ? llvm::Triple(
"spirv64-amd-amdhsa")
3530 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
3531 C.setContainsError();
3535 return Args.MakeArgStringRef(CanId);
3538 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3540 const std::set<StringRef> &GpuArchs)
override {
3544 ActionBuilderReturnCode
3547 PhasesTy &Phases)
override {
3549 return ABRT_Inactive;
3555 if (CudaDeviceActions.empty())
3556 return ABRT_Success;
3559 CudaDeviceActions.size() == GpuArchList.size()) &&
3560 "Expecting one action per GPU architecture.");
3561 assert(!CompileHostOnly &&
3562 "Not expecting HIP actions in host-only compilation.");
3564 bool ShouldLink = !EmitReloc || !*EmitReloc;
3567 !EmitAsm && ShouldLink) {
3573 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3574 if (
C.getDriver().isUsingOffloadLTO()) {
3578 AL.push_back(CudaDeviceActions[I]);
3581 CudaDeviceActions[I] =
3588 if (ToolChains.front()->getTriple().isSPIRV()) {
3591 types::ID Output = Args.hasArg(options::OPT_S)
3593 : types::TY_LLVM_BC;
3599 AssociatedOffloadKind);
3600 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3602 AssociatedOffloadKind);
3603 AL.push_back(AssembleAction);
3606 CudaDeviceActions[I] =
3617 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3618 AssociatedOffloadKind);
3620 DDep, CudaDeviceActions[I]->getType());
3623 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3626 types::TY_HIP_FATBIN);
3628 if (!CompileDeviceOnly) {
3629 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3630 AssociatedOffloadKind);
3633 CudaFatBinary =
nullptr;
3638 CudaDeviceActions.clear();
3641 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3644 return ABRT_Success;
3650 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3651 auto LI = DeviceLinkerInputs.begin();
3652 for (
auto *A : CudaDeviceActions) {
3659 CudaDeviceActions.clear();
3660 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3664 for (
Action *&A : CudaDeviceActions)
3665 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3666 AssociatedOffloadKind);
3668 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3670 for (
unsigned I = 0,
E = GpuArchList.size(); I !=
E; ++I) {
3672 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3673 AssociatedOffloadKind);
3675 DDep, CudaDeviceActions[I]->getType());
3679 CudaDeviceActions.clear();
3682 return (CompileDeviceOnly &&
3683 (CurPhase == FinalPhase ||
3689 void appendLinkDeviceActions(
ActionList &AL)
override {
3690 if (DeviceLinkerInputs.size() == 0)
3693 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3694 "Linker inputs and GPU arch list sizes do not match.");
3700 for (
auto &LI : DeviceLinkerInputs) {
3702 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3706 auto *DeviceLinkAction =
C.MakeAction<
LinkJobAction>(LI, Output);
3710 DeviceLinkDeps.
add(*DeviceLinkAction, *ToolChains[0],
3711 GpuArchList[I], AssociatedOffloadKind);
3713 DeviceLinkDeps, DeviceLinkAction->getType()));
3716 DeviceLinkerInputs.clear();
3719 if (Args.hasArg(options::OPT_emit_llvm)) {
3728 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3731 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3732 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3733 AssociatedOffloadKind);
3736 C.MakeAction<
OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3742 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3758 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3766 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3769 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3777 unsigned ValidBuilders = 0u;
3778 unsigned ValidBuildersSupportingBundling = 0u;
3779 for (
auto *SB : SpecializedBuilders) {
3780 IsValid = IsValid && !SB->initialize();
3783 if (SB->isValid()) {
3785 if (SB->canUseBundlerUnbundler())
3786 ++ValidBuildersSupportingBundling;
3790 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3793 ~OffloadingActionBuilder() {
3794 for (
auto *SB : SpecializedBuilders)
3799 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3800 assert(HostAction &&
"Invalid host action");
3801 assert(InputArg &&
"Invalid input argument");
3802 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3803 assert(
Loc->second == InputArg &&
3804 "host action mapped to multiple input arguments");
3813 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3815 DeviceActionBuilder::PhasesTy &Phases) {
3819 if (SpecializedBuilders.empty())
3822 assert(HostAction &&
"Invalid host action!");
3823 recordHostAction(HostAction, InputArg);
3828 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3829 unsigned InactiveBuilders = 0u;
3830 unsigned IgnoringBuilders = 0u;
3831 for (
auto *SB : SpecializedBuilders) {
3832 if (!SB->isValid()) {
3837 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3842 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3847 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3848 OffloadKind |= SB->getAssociatedOffloadKind();
3853 if (IgnoringBuilders &&
3854 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3871 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3872 const Arg *InputArg) {
3876 recordHostAction(HostAction, InputArg);
3884 if (CanUseBundler && isa<InputAction>(HostAction) &&
3885 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
3887 HostAction->
getType() == types::TY_PP_HIP)) {
3888 auto UnbundlingHostAction =
3893 HostAction = UnbundlingHostAction;
3894 recordHostAction(HostAction, InputArg);
3897 assert(HostAction &&
"Invalid host action!");
3900 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3901 for (
auto *SB : SpecializedBuilders) {
3905 auto RetCode = SB->addDeviceDependences(HostAction);
3909 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
3910 "Host dependence not expected to be ignored.!");
3914 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3915 OffloadKind |= SB->getAssociatedOffloadKind();
3920 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
3930 const Arg *InputArg) {
3932 recordHostAction(HostAction, InputArg);
3936 for (
auto *SB : SpecializedBuilders) {
3939 SB->appendTopLevelActions(OffloadAL);
3946 if (CanUseBundler && HostAction &&
3947 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
3949 OffloadAL.push_back(HostAction);
3953 assert(HostAction == AL.back() &&
"Host action not in the list??");
3955 recordHostAction(HostAction, InputArg);
3956 AL.back() = HostAction;
3958 AL.append(OffloadAL.begin(), OffloadAL.end());
3968 void appendDeviceLinkActions(
ActionList &AL) {
3969 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3972 SB->appendLinkDeviceActions(AL);
3976 Action *makeHostLinkAction() {
3979 appendDeviceLinkActions(DeviceAL);
3980 if (DeviceAL.empty())
3985 for (DeviceActionBuilder *SB : SpecializedBuilders) {
3988 HA = SB->appendLinkHostActions(DeviceAL);
4005 for (
auto *SB : SpecializedBuilders) {
4009 SB->appendLinkDependences(DDeps);
4013 unsigned ActiveOffloadKinds = 0u;
4014 for (
auto &I : InputArgToOffloadKindMap)
4015 ActiveOffloadKinds |= I.second;
4027 for (
auto *A : HostAction->
inputs()) {
4028 auto ArgLoc = HostActionToInputArgMap.find(A);
4029 if (ArgLoc == HostActionToInputArgMap.end())
4031 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4032 if (OFKLoc == InputArgToOffloadKindMap.end())
4044 nullptr, ActiveOffloadKinds);
4050void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4051 const InputList &Inputs,
4055 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4056 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4057 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4058 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4059 Args.eraseArg(options::OPT__SLASH_Yc);
4060 Args.eraseArg(options::OPT__SLASH_Yu);
4061 YcArg = YuArg =
nullptr;
4063 if (YcArg && Inputs.size() > 1) {
4064 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4065 Args.eraseArg(options::OPT__SLASH_Yc);
4073 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4074 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4075 Args.AddFlagArg(
nullptr,
4076 getOpts().getOption(options::OPT_frtlib_add_rpath));
4079 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4080 Diag(clang::diag::err_drv_emit_llvm_link);
4081 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4083 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4084 .starts_with_insensitive(
"lld"))
4085 Diag(clang::diag::err_drv_lto_without_lld);
4091 if (!Args.hasArg(options::OPT_dumpdir)) {
4092 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4093 Arg *Arg = Args.MakeSeparateArg(
4094 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4096 (FinalOutput ? FinalOutput->getValue()
4108 Args.eraseArg(options::OPT__SLASH_Fp);
4109 Args.eraseArg(options::OPT__SLASH_Yc);
4110 Args.eraseArg(options::OPT__SLASH_Yu);
4111 YcArg = YuArg =
nullptr;
4114 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4115 for (
auto &I : Inputs) {
4117 const Arg *InputArg = I.second;
4122 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4126 if (InitialPhase > FinalPhase) {
4127 if (InputArg->isClaimed())
4134 if (Args.hasArg(options::OPT_Qunused_arguments))
4140 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4141 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4145 (Args.getLastArg(options::OPT__SLASH_EP,
4146 options::OPT__SLASH_P) ||
4147 Args.getLastArg(options::OPT_E) ||
4148 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4150 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4151 << InputArg->getAsString(Args) << !!FinalPhaseArg
4152 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4154 Diag(clang::diag::warn_drv_input_file_unused)
4155 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4157 << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() :
"");
4170 Actions.push_back(ClangClPch);
4182 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4183 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4189 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4191 if (!SuppressMissingInputWarning && Inputs.empty()) {
4192 Diag(clang::diag::err_drv_no_input_files);
4197 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4198 StringRef
V = A->getValue();
4199 if (Inputs.size() > 1 && !
V.empty() &&
4200 !llvm::sys::path::is_separator(
V.back())) {
4202 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4203 << A->getSpelling() <<
V;
4204 Args.eraseArg(options::OPT__SLASH_Fo);
4209 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4210 StringRef
V = A->getValue();
4211 if (Inputs.size() > 1 && !
V.empty() &&
4212 !llvm::sys::path::is_separator(
V.back())) {
4214 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4215 << A->getSpelling() <<
V;
4216 Args.eraseArg(options::OPT__SLASH_Fa);
4221 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4222 if (A->getValue()[0] ==
'\0') {
4224 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4225 Args.eraseArg(options::OPT__SLASH_o);
4229 handleArguments(
C, Args, Inputs, Actions);
4231 bool UseNewOffloadingDriver =
4233 Args.hasFlag(options::OPT_foffload_via_llvm,
4234 options::OPT_fno_offload_via_llvm,
false) ||
4235 Args.hasFlag(options::OPT_offload_new_driver,
4236 options::OPT_no_offload_new_driver,
false);
4239 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4240 !UseNewOffloadingDriver
4241 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4249 for (
auto &I : Inputs) {
4251 const Arg *InputArg = I.second;
4264 if (!UseNewOffloadingDriver)
4265 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4271 if (!UseNewOffloadingDriver)
4272 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4273 Current, InputArg, Phase, PL.back(), FullPL);
4279 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4282 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4283 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4285 LinkerInputs.push_back(Current);
4295 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4296 MergerInputs.push_back(Current);
4314 if (NewCurrent == Current)
4317 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4320 Current = NewCurrent;
4324 if (UseNewOffloadingDriver)
4328 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4332 if (Current->getType() == types::TY_Nothing)
4338 Actions.push_back(Current);
4341 if (!UseNewOffloadingDriver)
4342 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4344 Current->propagateHostOffloadInfo(
C.getActiveOffloadKinds(),
4350 if (LinkerInputs.empty()) {
4353 if (!UseNewOffloadingDriver)
4354 OffloadBuilder->appendDeviceLinkActions(Actions);
4357 if (!LinkerInputs.empty()) {
4358 if (!UseNewOffloadingDriver)
4359 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4360 LinkerInputs.push_back(Wrapper);
4365 }
else if (UseNewOffloadingDriver ||
4366 Args.hasArg(options::OPT_offload_link)) {
4373 if (!UseNewOffloadingDriver)
4374 LA = OffloadBuilder->processHostLinkAction(LA);
4375 Actions.push_back(LA);
4379 if (!MergerInputs.empty())
4383 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4390 for (
auto &I : Inputs) {
4392 const Arg *InputArg = I.second;
4397 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4398 InputType == types::TY_Asm)
4403 for (
auto Phase : PhaseList) {
4407 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4412 if (InputType == types::TY_Object)
4419 assert(Phase == PhaseList.back() &&
4420 "merging must be final compilation step.");
4421 MergerInputs.push_back(Current);
4430 Actions.push_back(Current);
4434 if (!MergerInputs.empty())
4439 for (
auto Opt : {options::OPT_print_supported_cpus,
4440 options::OPT_print_supported_extensions,
4441 options::OPT_print_enabled_extensions}) {
4448 if (Arg *A = Args.getLastArg(Opt)) {
4449 if (Opt == options::OPT_print_supported_extensions &&
4450 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4451 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4452 !
C.getDefaultToolChain().getTriple().isARM()) {
4453 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4454 <<
"--print-supported-extensions";
4457 if (Opt == options::OPT_print_enabled_extensions &&
4458 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4459 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4460 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4461 <<
"--print-enabled-extensions";
4468 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4471 for (
auto &I : Inputs)
4477 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4481 if (TC.requiresValidation(Args)) {
4482 Action *LastAction = Actions.back();
4484 LastAction, types::TY_DX_CONTAINER));
4489 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4495 const llvm::opt::DerivedArgList &Args,
4497 const llvm::Triple &Triple,
4498 bool SuppressError =
false) {
4503 if (!SuppressError && Triple.isNVPTX() &&
4505 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4506 <<
"CUDA" << ArchStr;
4508 }
else if (!SuppressError && Triple.isAMDGPU() &&
4510 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4511 <<
"HIP" << ArchStr;
4519 llvm::StringMap<bool> Features;
4525 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4526 C.setContainsError();
4538static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4540 llvm::Triple Triple) {
4541 if (!Triple.isAMDGPU())
4542 return std::nullopt;
4544 std::set<StringRef> ArchSet;
4545 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4549llvm::DenseSet<StringRef>
4552 bool SuppressError)
const {
4554 TC = &
C.getDefaultToolChain();
4557 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4558 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4559 options::OPT_no_offload_arch_EQ)) {
4560 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4562 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4564 :
"--no-offload-arch");
4567 if (KnownArchs.contains(TC))
4568 return KnownArchs.lookup(TC);
4570 llvm::DenseSet<StringRef> Archs;
4571 for (
auto *Arg : Args) {
4573 std::unique_ptr<llvm::opt::Arg> ExtractedArg =
nullptr;
4574 if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) &&
4577 unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1));
4578 unsigned Prev = Index;
4579 ExtractedArg =
getOpts().ParseOneArg(Args, Index);
4580 if (!ExtractedArg || Index > Prev + 1) {
4581 TC->
getDriver().
Diag(diag::err_drv_invalid_Xopenmp_target_with_args)
4582 << Arg->getAsString(Args);
4585 Arg = ExtractedArg.get();
4590 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4591 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4592 if (Arch ==
"native" || Arch.empty()) {
4596 llvm::consumeError(GPUsOrErr.takeError());
4599 << llvm::Triple::getArchTypeName(TC->
getArch())
4600 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4604 for (
auto ArchStr : *GPUsOrErr) {
4611 C, Args, Arch, TC->
getTriple(), SuppressError);
4612 if (ArchStr.empty())
4614 Archs.insert(ArchStr);
4617 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4618 for (StringRef Arch : llvm::split(Arg->getValue(),
",")) {
4619 if (Arch ==
"all") {
4623 C, Args, Arch, TC->
getTriple(), SuppressError);
4624 if (ArchStr.empty())
4626 Archs.erase(ArchStr);
4632 if (
auto ConflictingArchs =
4634 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4635 << ConflictingArchs->first << ConflictingArchs->second;
4636 C.setContainsError();
4643 if (Archs.empty()) {
4649 Archs.insert(StringRef());
4651 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4652 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4659 llvm::opt::DerivedArgList &Args,
4661 Action *HostAction)
const {
4666 !(isa<CompileJobAction>(HostAction) ||
4680 auto TCRange =
C.getOffloadToolChains(Kind);
4681 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4682 ToolChains.push_back(TI->second);
4684 if (ToolChains.empty())
4688 const Arg *InputArg = Input.second;
4697 for (
const ToolChain *TC : ToolChains) {
4701 for (StringRef Arch : Sorted)
4702 TCAndArchs.push_back(std::make_pair(TC, Arch));
4705 for (
unsigned I = 0,
E = TCAndArchs.size(); I !=
E; ++I)
4706 DeviceActions.push_back(
C.MakeAction<
InputAction>(*InputArg, InputType));
4708 if (DeviceActions.empty())
4715 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4719 auto TCAndArch = TCAndArchs.begin();
4720 for (
Action *&A : DeviceActions) {
4721 if (A->
getType() == types::TY_Nothing)
4729 if (isa<CompileJobAction>(A) && isa<CompileJobAction>(HostAction) &&
4731 HostAction->
getType() != types::TY_Nothing) {
4738 TCAndArch->second.data(), Kind);
4740 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4749 for (
Action *&A : DeviceActions) {
4750 if ((A->
getType() != types::TY_Object &&
4751 A->
getType() != types::TY_LTO_BC) ||
4753 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4759 auto TCAndArch = TCAndArchs.begin();
4760 for (
Action *A : DeviceActions) {
4761 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4763 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4768 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4770 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4778 bool ShouldBundleHIP =
4780 Args.hasFlag(options::OPT_gpu_bundle_output,
4781 options::OPT_no_gpu_bundle_output,
true) &&
4782 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) &&
4783 !llvm::any_of(OffloadActions,
4790 if (OffloadActions.empty())
4795 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4799 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
4803 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4808 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
4817 nullptr,
C.getActiveOffloadKinds());
4826 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
4827 return A->
getType() == types::TY_Nothing;
4828 }) && isa<CompileJobAction>(HostAction);
4831 nullptr, SingleDeviceOutput ? DDep : DDeps);
4832 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
4838 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
4848 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
4854 llvm_unreachable(
"link action invalid here.");
4856 llvm_unreachable(
"ifsmerge action invalid here.");
4861 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
4862 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
4863 OutputTy = types::TY_Dependencies;
4868 if (!Args.hasFlag(options::OPT_frewrite_includes,
4869 options::OPT_fno_rewrite_includes,
false) &&
4870 !Args.hasFlag(options::OPT_frewrite_imports,
4871 options::OPT_fno_rewrite_imports,
false) &&
4872 !Args.hasFlag(options::OPT_fdirectives_only,
4873 options::OPT_fno_directives_only,
false) &&
4877 "Cannot preprocess this input type!");
4883 if (Args.hasArg(options::OPT_extract_api))
4890 if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
4891 !Args.getLastArg(options::OPT__precompile))
4896 "Cannot precompile this input type!");
4900 const char *ModName =
nullptr;
4901 if (OutputTy == types::TY_PCH) {
4902 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
4903 ModName = A->getValue();
4905 OutputTy = types::TY_ModuleFile;
4908 if (Args.hasArg(options::OPT_fsyntax_only)) {
4910 OutputTy = types::TY_Nothing;
4916 if (Args.hasArg(options::OPT_fsyntax_only))
4918 if (Args.hasArg(options::OPT_rewrite_objc))
4920 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
4922 types::TY_RewrittenLegacyObjC);
4923 if (Args.hasArg(options::OPT__analyze))
4925 if (Args.hasArg(options::OPT__migrate))
4927 if (Args.hasArg(options::OPT_emit_ast))
4929 if (Args.hasArg(options::OPT_emit_cir))
4931 if (Args.hasArg(options::OPT_module_file_info))
4933 if (Args.hasArg(options::OPT_verify_pch))
4935 if (Args.hasArg(options::OPT_extract_api))
4942 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
4943 !Args.hasArg(options::OPT_emit_llvm))
4944 Output = types::TY_PP_Asm;
4945 else if (Args.hasArg(options::OPT_S))
4946 Output = types::TY_LTO_IR;
4948 Output = types::TY_LTO_BC;
4953 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
4956 if (Args.hasArg(options::OPT_emit_llvm) ||
4960 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4964 Args.hasArg(options::OPT_S) &&
4968 !Args.hasFlag(options::OPT_offload_new_driver,
4969 options::OPT_no_offload_new_driver,
false)))
4971 : types::TY_LLVM_BC;
4980 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
4984 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
4986 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5006 unsigned NumOutputs = 0;
5007 unsigned NumIfsOutputs = 0;
5008 for (
const Action *A :
C.getActions()) {
5009 if (A->
getType() != types::TY_Nothing &&
5010 A->
getType() != types::TY_DX_CONTAINER &&
5012 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5014 0 == NumIfsOutputs++) ||
5019 A->
getType() == types::TY_Nothing &&
5020 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5021 NumOutputs += A->
size();
5024 if (NumOutputs > 1) {
5025 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5026 FinalOutput =
nullptr;
5030 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5033 llvm::StringSet<> ArchNames;
5034 if (RawTriple.isOSBinFormatMachO())
5035 for (
const Arg *A :
C.getArgs())
5036 if (A->getOption().matches(options::OPT_arch))
5037 ArchNames.insert(A->getValue());
5040 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5041 for (
Action *A :
C.getActions()) {
5048 const char *LinkingOutput =
nullptr;
5049 if (isa<LipoJobAction>(A)) {
5051 LinkingOutput = FinalOutput->getValue();
5059 ArchNames.size() > 1,
5060 LinkingOutput, CachedResults,
5067 for (
auto &J :
C.getJobs())
5068 J.InProcess =
false;
5071 C.setPostCallback([=](
const Command &
Cmd,
int Res) {
5072 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5073 Cmd.getProcessStatistics();
5077 const char *LinkingOutput =
nullptr;
5079 LinkingOutput = FinalOutput->getValue();
5080 else if (!
Cmd.getOutputFilenames().empty())
5081 LinkingOutput =
Cmd.getOutputFilenames().front().c_str();
5086 using namespace llvm;
5088 outs() << sys::path::filename(Cmd.getExecutable()) <<
": "
5089 <<
"output=" << LinkingOutput;
5090 outs() <<
", total="
5091 << format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5093 << format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5094 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5098 llvm::raw_string_ostream Out(Buffer);
5099 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.getExecutable()),
5102 llvm::sys::printArg(Out, LinkingOutput, true);
5103 Out <<
',' << ProcStat->TotalTime.count() <<
','
5104 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5108 llvm::raw_fd_ostream OS(CCPrintStatReportFilename, EC,
5109 llvm::sys::fs::OF_Append |
5110 llvm::sys::fs::OF_Text);
5115 llvm::errs() <<
"ERROR: Cannot lock file "
5116 << CCPrintStatReportFilename <<
": "
5117 << toString(L.takeError()) <<
"\n";
5128 if (Diags.hasErrorOccurred() ||
5129 C.getArgs().hasArg(options::OPT_Qunused_arguments))
5133 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5135 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5138 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5139 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5141 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5145 return strstr(J.getCreator().getShortName(),
"assembler");
5147 for (Arg *A :
C.getArgs()) {
5151 if (!A->isClaimed()) {
5157 const Option &Opt = A->getOption();
5158 if (Opt.getKind() == Option::FlagClass) {
5159 bool DuplicateClaimed =
false;
5161 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5162 if (AA->isClaimed()) {
5163 DuplicateClaimed =
true;
5168 if (DuplicateClaimed)
5174 if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5176 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5181 !
C.getActions().empty()) {
5182 Diag(diag::err_drv_unsupported_opt_for_target)
5183 << A->getSpelling() << getTargetTriple();
5185 Diag(clang::diag::warn_drv_unused_argument)
5186 << A->getAsString(
C.getArgs());
5196class ToolSelector final {
5207 bool IsHostSelector;
5218 bool CanBeCollapsed =
true) {
5220 if (Inputs.size() != 1)
5223 Action *CurAction = *Inputs.begin();
5224 if (CanBeCollapsed &&
5230 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5234 if (!IsHostSelector) {
5235 if (OA->hasSingleDeviceDependence(
true)) {
5237 OA->getSingleDeviceDependence(
true);
5238 if (CanBeCollapsed &&
5241 SavedOffloadAction.push_back(OA);
5242 return dyn_cast<JobAction>(CurAction);
5244 }
else if (OA->hasHostDependence()) {
5245 CurAction = OA->getHostDependence();
5246 if (CanBeCollapsed &&
5249 SavedOffloadAction.push_back(OA);
5250 return dyn_cast<JobAction>(CurAction);
5255 return dyn_cast<JobAction>(CurAction);
5259 bool canCollapseAssembleAction()
const {
5260 return TC.useIntegratedAs() && !SaveTemps &&
5261 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5262 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5263 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5264 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5268 bool canCollapsePreprocessorAction()
const {
5269 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5270 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5271 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5276 struct JobActionInfo final {
5286 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5288 unsigned ElementNum) {
5289 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5290 for (
unsigned I = 0; I < ElementNum; ++I)
5291 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5292 ActionInfo[I].SavedOffloadAction.end());
5308 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5310 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5311 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5312 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5313 if (!AJ || !BJ || !CJ)
5317 const Tool *
T = TC.SelectTool(*CJ);
5324 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5330 const Tool *BT = TC.SelectTool(*BJ);
5335 if (!
T->hasIntegratedAssembler())
5338 Inputs = CJ->getInputs();
5339 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5346 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5348 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5349 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5354 const Tool *
T = TC.SelectTool(*BJ);
5358 if (!
T->hasIntegratedAssembler())
5361 Inputs = BJ->getInputs();
5362 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5369 if (ActionInfo.size() < 2)
5371 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5372 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5381 bool InputIsBitcode =
true;
5382 for (
size_t i = 1; i < ActionInfo.size(); i++)
5383 if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5384 ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5385 InputIsBitcode =
false;
5388 if (!InputIsBitcode && !canCollapsePreprocessorAction())
5392 const Tool *
T = TC.SelectTool(*CJ);
5399 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5402 if (
T->canEmitIR() && ((SaveTemps && !InputIsBitcode) ||
EmbedBitcode))
5405 Inputs = CJ->getInputs();
5406 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5417 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5423 for (
Action *A : Inputs) {
5424 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5425 if (!PJ || !isa<PreprocessJobAction>(PJ)) {
5426 NewInputs.push_back(A);
5432 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5433 PreprocessJobOffloadActions.end());
5434 NewInputs.append(PJ->input_begin(), PJ->input_end());
5442 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5444 assert(BaseAction &&
"Invalid base action.");
5461 ActionChain.back().JA = BaseAction;
5462 while (ActionChain.back().JA) {
5463 const Action *CurAction = ActionChain.back().JA;
5466 ActionChain.resize(ActionChain.size() + 1);
5467 JobActionInfo &AI = ActionChain.back();
5471 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5475 ActionChain.pop_back();
5483 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5484 CollapsedOffloadAction);
5486 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5488 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5494 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5506 StringRef BoundArch,
5508 std::string TriplePlusArch = TC->
getTriple().normalize();
5509 if (!BoundArch.empty()) {
5510 TriplePlusArch +=
"-";
5511 TriplePlusArch += BoundArch;
5513 TriplePlusArch +=
"-";
5515 return TriplePlusArch;
5520 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5521 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5524 std::pair<const Action *, std::string> ActionTC = {
5526 auto CachedResult = CachedResults.find(ActionTC);
5527 if (CachedResult != CachedResults.end()) {
5528 return CachedResult->second;
5531 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5532 CachedResults, TargetDeviceOffloadKind);
5533 CachedResults[ActionTC] =
Result;
5538 const JobAction *JA,
const char *BaseInput,
5541 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5545 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5546 Path = A->getValue();
5547 if (llvm::sys::fs::is_directory(
Path)) {
5549 llvm::sys::path::replace_extension(Tmp,
"json");
5550 llvm::sys::path::append(
Path, llvm::sys::path::filename(Tmp));
5553 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5556 Path = DumpDir->getValue();
5557 Path += llvm::sys::path::filename(BaseInput);
5561 llvm::sys::path::replace_extension(
Path,
"json");
5563 const char *ResultFile =
C.getArgs().MakeArgString(
Path);
5564 C.addTimeTraceFile(ResultFile, JA);
5565 C.addResultFile(ResultFile, JA);
5570 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5571 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5574 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5577 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5610 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5612 OA->doOnEachDeviceDependence([&](
Action *DepA,
const ToolChain *DepTC,
5613 const char *DepBoundArch) {
5616 LinkingOutput, CachedResults,
5626 OA->doOnEachDependence(
5627 BuildingForOffloadDevice,
5630 C, DepA, DepTC, DepBoundArch,
false,
5631 !!DepBoundArch, LinkingOutput, CachedResults,
5635 A = BuildingForOffloadDevice
5636 ? OA->getSingleDeviceDependence(
true)
5637 : OA->getHostDependence();
5641 std::pair<const Action *, std::string> ActionTC = {
5642 OA->getHostDependence(),
5644 auto It = CachedResults.find(ActionTC);
5645 if (It != CachedResults.end()) {
5647 Inputs.append(OffloadDependencesInputInfo);
5652 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5655 const Arg &Input = IA->getInputArg();
5657 if (Input.getOption().matches(options::OPT_INPUT)) {
5658 const char *
Name = Input.getValue();
5668 if (!ArchName.empty())
5669 TC = &getToolChain(
C.getArgs(),
5671 C.getArgs(), ArchName));
5673 TC = &
C.getDefaultToolChain();
5676 MultipleArchs, LinkingOutput, CachedResults,
5677 TargetDeviceOffloadKind);
5683 const JobAction *JA = cast<JobAction>(A);
5688 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5695 for (
const auto *OA : CollapsedOffloadActions)
5696 cast<OffloadAction>(OA)->doOnEachDependence(
5697 BuildingForOffloadDevice,
5700 C, DepA, DepTC, DepBoundArch,
false,
5701 !!DepBoundArch, LinkingOutput, CachedResults,
5707 for (
const Action *Input : Inputs) {
5711 bool SubJobAtTopLevel =
5712 AtTopLevel && (isa<DsymutilJobAction>(A) || isa<VerifyJobAction>(A));
5714 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5719 const char *BaseInput = InputInfos[0].getBaseInput();
5720 for (
auto &Info : InputInfos) {
5721 if (Info.isFilename()) {
5722 BaseInput = Info.getBaseInput();
5729 if (JA->
getType() == types::TY_dSYM)
5730 BaseInput = InputInfos[0].getFilename();
5733 if (!OffloadDependencesInputInfo.empty())
5734 InputInfos.append(OffloadDependencesInputInfo.begin(),
5735 OffloadDependencesInputInfo.end());
5738 llvm::Triple EffectiveTriple;
5740 const ArgList &Args =
5742 if (InputInfos.size() != 1) {
5746 EffectiveTriple = llvm::Triple(
5754 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
5758 for (
auto &UI : UA->getDependentActionsInfo()) {
5760 "Unbundling with no offloading??");
5767 UI.DependentOffloadKind,
5768 UI.DependentToolChain->getTriple().normalize(),
5779 UnbundlingResults.push_back(CurI);
5788 Arch = UI.DependentBoundArch;
5793 UI.DependentOffloadKind)}] = {
5799 std::pair<const Action *, std::string> ActionTC = {
5801 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
5802 "Result does not exist??");
5803 Result = CachedResults[ActionTC].front();
5804 }
else if (JA->
getType() == types::TY_Nothing)
5811 isa<OffloadPackagerJobAction>(A) ||
5815 AtTopLevel, MultipleArchs,
5818 if (
T->canEmitIR() && OffloadingPrefix.empty())
5823 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
5824 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
5825 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
5826 llvm::errs() << InputInfos[i].getAsString();
5828 llvm::errs() <<
", ";
5830 if (UnbundlingResults.empty())
5831 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
5833 llvm::errs() <<
"], outputs: [";
5834 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
5835 llvm::errs() << UnbundlingResults[i].getAsString();
5837 llvm::errs() <<
", ";
5839 llvm::errs() <<
"] \n";
5842 if (UnbundlingResults.empty())
5843 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
5845 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
5846 Args, LinkingOutput);
5852 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5853 return Target.isOSWindows() ?
"a.exe" :
"a.out";
5865 if (ArgValue.empty()) {
5868 }
else if (llvm::sys::path::is_separator(
Filename.back())) {
5870 llvm::sys::path::append(
Filename, BaseName);
5873 if (!llvm::sys::path::has_extension(ArgValue)) {
5878 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
5883 llvm::sys::path::replace_extension(
Filename, Extension);
5886 return Args.MakeArgString(
Filename.c_str());
5890 if (isa<PreprocessJobAction>(JA))
5892 if (isa<OffloadAction>(JA) && isa<PreprocessJobAction>(JA.
getInputs()[0]))
5894 if (isa<OffloadBundlingJobAction>(JA) &&
5901 StringRef Suffix,
bool MultipleArchs,
5902 StringRef BoundArch,
5903 bool NeedUniqueDirectory)
const {
5905 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
5906 std::optional<std::string> CrashDirectory =
5908 ? std::string(A->getValue())
5909 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
5910 if (CrashDirectory) {
5911 if (!
getVFS().exists(*CrashDirectory))
5912 llvm::sys::fs::create_directories(*CrashDirectory);
5914 llvm::sys::path::append(
Path, Prefix);
5915 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
5916 if (std::error_code EC =
5917 llvm::sys::fs::createUniqueFile(
Path + Middle + Suffix, TmpName)) {
5918 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
5922 if (MultipleArchs && !BoundArch.empty()) {
5923 if (NeedUniqueDirectory) {
5925 llvm::sys::path::append(TmpName,
5926 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
5936 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
5951 const char *BaseInput) {
5952 assert(isa<PrecompileJobAction>(JA) && JA.
getType() == types::TY_ModuleFile &&
5953 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
5954 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
5959 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
5963 const char *BaseInput,
5964 StringRef OrigBoundArch,
bool AtTopLevel,
5966 StringRef OffloadingPrefix)
const {
5967 std::string BoundArch = OrigBoundArch.str();
5968 if (is_style_windows(llvm::sys::path::Style::native)) {
5971 std::replace(BoundArch.begin(), BoundArch.end(),
':',
'@');
5974 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
5976 if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
5977 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
5978 return C.addResultFile(FinalOutput->getValue(), &JA);
5982 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
5983 assert(AtTopLevel && isa<PreprocessJobAction>(JA));
5984 StringRef BaseName = llvm::sys::path::filename(BaseInput);
5986 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
5987 NameArg = A->getValue();
5988 return C.addResultFile(
5998 if (JA.
getType() == types::TY_ModuleFile &&
5999 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6003 if (JA.
getType() == types::TY_PP_Asm &&
6004 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6005 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6008 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6011 if (JA.
getType() == types::TY_Object &&
6012 C.getArgs().hasArg(options::OPT_dxc_Fo)) {
6013 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6016 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6020 if (JA.
getType() == types::TY_PP_Asm &&
6021 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6022 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6024 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6025 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6026 return C.addResultFile(
6031 if (JA.
getType() == types::TY_API_INFO &&
6032 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6033 C.getArgs().hasArg(options::OPT_o))
6034 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6035 <<
C.getArgs().getLastArgValue(options::OPT_o);
6042 bool SpecifiedModuleOutput =
6043 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6044 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6045 if (MultipleArchs && SpecifiedModuleOutput)
6046 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6050 if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
6051 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6052 assert(!
C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
6058 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6060 StringRef
Name = llvm::sys::path::filename(BaseInput);
6061 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6062 const char *Suffix =
6067 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6068 bool NeedUniqueDirectory =
6071 Triple.isOSDarwin();
6072 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6073 NeedUniqueDirectory);
6081 if (isa<DsymutilJobAction>(JA) &&
C.getArgs().hasArg(options::OPT_dsym_dir)) {
6082 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6087 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6088 llvm::sys::path::filename(BasePath));
6089 BaseName = ExternalPath;
6090 }
else if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
6091 BaseName = BasePath;
6093 BaseName = llvm::sys::path::filename(BasePath);
6096 const char *NamedOutput;
6098 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6099 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6103 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6107 }
else if (JA.
getType() == types::TY_Image &&
6108 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6109 options::OPT__SLASH_o)) {
6113 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6117 }
else if (JA.
getType() == types::TY_Image) {
6127 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6128 options::OPT_fno_gpu_rdc,
false);
6129 bool UseOutExtension = IsHIPNoRDC || isa<OffloadPackagerJobAction>(JA);
6130 if (UseOutExtension) {
6132 llvm::sys::path::replace_extension(Output,
"");
6134 Output += OffloadingPrefix;
6135 if (MultipleArchs && !BoundArch.empty()) {
6137 Output.append(BoundArch);
6139 if (UseOutExtension)
6141 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6144 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6145 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6146 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6149 .getLastArg(options::OPT__SLASH_o)
6154 const char *Suffix =
6156 assert(Suffix &&
"All types used for output should have a suffix.");
6158 std::string::size_type End = std::string::npos;
6160 End = BaseName.rfind(
'.');
6162 Suffixed += OffloadingPrefix;
6163 if (MultipleArchs && !BoundArch.empty()) {
6165 Suffixed.append(BoundArch);
6170 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6171 const llvm::opt::DerivedArgList &Args) {
6176 return isa<CompileJobAction>(JA) &&
6178 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6183 if (!AtTopLevel && JA.
getType() == types::TY_LLVM_BC &&
6184 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6185 IsAMDRDCInCompilePhase(JA,
C.getArgs())))
6189 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6193 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6194 JA.
getType() != types::TY_PCH) {
6195 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6197 llvm::sys::path::remove_filename(TempPath);
6198 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6199 llvm::sys::path::append(TempPath, OutputFileName);
6200 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6206 bool SameFile =
false;
6208 llvm::sys::fs::current_path(
Result);
6209 llvm::sys::path::append(
Result, BaseName);
6210 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6213 StringRef
Name = llvm::sys::path::filename(BaseInput);
6214 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6218 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6224 llvm::sys::path::remove_filename(BasePath);
6225 if (BasePath.empty())
6226 BasePath = NamedOutput;
6228 llvm::sys::path::append(BasePath, NamedOutput);
6229 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6232 return C.addResultFile(NamedOutput, &JA);
6238 -> std::optional<std::string> {
6241 for (
const auto &
Dir :
P) {
6245 llvm::sys::path::append(
P,
Name);
6246 if (llvm::sys::fs::exists(Twine(
P)))
6247 return std::string(
P);
6249 return std::nullopt;
6256 llvm::sys::path::append(R,
Name);
6257 if (llvm::sys::fs::exists(Twine(R)))
6258 return std::string(R);
6261 llvm::sys::path::append(
P,
Name);
6262 if (llvm::sys::fs::exists(Twine(
P)))
6263 return std::string(
P);
6266 llvm::sys::path::append(
D,
"..",
Name);
6267 if (llvm::sys::fs::exists(Twine(
D)))
6268 return std::string(
D);
6276 return std::string(
Name);
6279void Driver::generatePrefixedToolNames(
6283 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6284 Names.emplace_back(
Tool);
6288 llvm::sys::path::append(Dir, Name);
6289 if (llvm::sys::fs::can_execute(Twine(Dir)))
6291 llvm::sys::path::remove_filename(Dir);
6297 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6302 if (llvm::sys::fs::is_directory(PrefixDir)) {
6305 return std::string(
P);
6308 if (llvm::sys::fs::can_execute(Twine(
P)))
6309 return std::string(
P);
6314 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6322 for (
const auto &
Path : List) {
6325 return std::string(
P);
6329 if (llvm::ErrorOr<std::string>
P =
6330 llvm::sys::findProgramByName(TargetSpecificExecutable))
6334 return std::string(
Name);
6339 std::string error =
"<NOT PRESENT>";
6343 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6360 llvm::sys::path::remove_filename(path);
6361 llvm::sys::path::append(path,
"libc++.modules.json");
6362 if (TC.
getVFS().exists(path))
6363 return static_cast<std::string
>(path);
6368 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6371 return evaluate(
"libc++.a").value_or(error);
6384 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix,
Path);
6386 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6390 return std::string(
Path);
6395 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix,
Path);
6397 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6401 return std::string(
Path);
6406 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6410 Output = FpArg->getValue();
6414 if (!llvm::sys::path::has_extension(Output))
6417 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6418 Output = YcArg->getValue();
6421 llvm::sys::path::replace_extension(Output,
".pch");
6423 return std::string(Output);
6426const ToolChain &Driver::getToolChain(
const ArgList &Args,
6427 const llvm::Triple &
Target)
const {
6429 auto &TC = ToolChains[
Target.str()];
6431 switch (
Target.getOS()) {
6432 case llvm::Triple::AIX:
6433 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6435 case llvm::Triple::Haiku:
6436 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6438 case llvm::Triple::Darwin:
6439 case llvm::Triple::MacOSX:
6440 case llvm::Triple::IOS:
6441 case llvm::Triple::TvOS:
6442 case llvm::Triple::WatchOS:
6443 case llvm::Triple::XROS:
6444 case llvm::Triple::DriverKit:
6445 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6447 case llvm::Triple::DragonFly:
6448 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6450 case llvm::Triple::OpenBSD:
6451 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6453 case llvm::Triple::NetBSD:
6454 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6456 case llvm::Triple::FreeBSD:
6458 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6461 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6463 case llvm::Triple::Linux:
6464 case llvm::Triple::ELFIAMCU:
6465 if (
Target.getArch() == llvm::Triple::hexagon)
6466 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6468 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6469 !
Target.hasEnvironment())
6470 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6473 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6475 else if (
Target.getArch() == llvm::Triple::ve)
6476 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6477 else if (
Target.isOHOSFamily())
6478 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6480 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6482 case llvm::Triple::NaCl:
6483 TC = std::make_unique<toolchains::NaClToolChain>(*
this,
Target, Args);
6485 case llvm::Triple::Fuchsia:
6486 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6488 case llvm::Triple::Solaris:
6489 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6491 case llvm::Triple::CUDA:
6492 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6494 case llvm::Triple::AMDHSA:
6495 TC = std::make_unique<toolchains::ROCMToolChain>(*
this,
Target, Args);
6497 case llvm::Triple::AMDPAL:
6498 case llvm::Triple::Mesa3D:
6499 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6501 case llvm::Triple::UEFI:
6502 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6504 case llvm::Triple::Win32:
6505 switch (
Target.getEnvironment()) {
6507 if (
Target.isOSBinFormatELF())
6508 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6509 else if (
Target.isOSBinFormatMachO())
6510 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6512 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6514 case llvm::Triple::GNU:
6515 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6517 case llvm::Triple::Itanium:
6518 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6521 case llvm::Triple::MSVC:
6522 case llvm::Triple::UnknownEnvironment:
6523 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6524 .starts_with_insensitive(
"bfd"))
6525 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6529 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6533 case llvm::Triple::PS4:
6534 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6536 case llvm::Triple::PS5:
6537 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6539 case llvm::Triple::Hurd:
6540 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6542 case llvm::Triple::LiteOS:
6543 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6545 case llvm::Triple::ZOS:
6546 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6548 case llvm::Triple::Vulkan:
6549 case llvm::Triple::ShaderModel:
6550 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6555 switch (
Target.getArch()) {
6556 case llvm::Triple::tce:
6557 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6559 case llvm::Triple::tcele:
6560 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6562 case llvm::Triple::hexagon:
6563 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6566 case llvm::Triple::lanai:
6567 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6569 case llvm::Triple::xcore:
6570 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6572 case llvm::Triple::wasm32:
6573 case llvm::Triple::wasm64:
6574 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6576 case llvm::Triple::avr:
6577 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6579 case llvm::Triple::msp430:
6581 std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6583 case llvm::Triple::riscv32:
6584 case llvm::Triple::riscv64:
6587 std::make_unique<toolchains::RISCVToolChain>(*
this,
Target, Args);
6589 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6591 case llvm::Triple::ve:
6592 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6594 case llvm::Triple::spirv32:
6595 case llvm::Triple::spirv64:
6596 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6598 case llvm::Triple::csky:
6599 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6603 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6604 else if (
Target.isOSBinFormatELF())
6605 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6606 else if (
Target.isOSBinFormatMachO())
6607 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6609 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6617const ToolChain &Driver::getOffloadingDeviceToolChain(
6618 const ArgList &Args,
const llvm::Triple &
Target,
const ToolChain &HostTC,
6627 switch (TargetDeviceOffloadKind) {
6629 if (((
Target.getArch() == llvm::Triple::amdgcn ||
6630 Target.getArch() == llvm::Triple::spirv64) &&
6631 Target.getVendor() == llvm::Triple::AMD &&
6632 Target.getOS() == llvm::Triple::AMDHSA) ||
6633 !Args.hasArgNoClaim(options::OPT_offload_EQ))
6634 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6636 else if (
Target.getArch() == llvm::Triple::spirv64 &&
6637 Target.getVendor() == llvm::Triple::UnknownVendor &&
6638 Target.getOS() == llvm::Triple::UnknownOS)
6639 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6653 if (JA.
size() != 1 ||
6658 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6659 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
6660 !isa<ExtractAPIJobAction>(JA))
6668 if (JA.
size() != 1 ||
6673 if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
6674 !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
6682 if (Args.hasArg(options::OPT_emit_static_lib))
6693 unsigned &Micro,
bool &HadExtra) {
6696 Major = Minor = Micro = 0;
6700 if (Str.consumeInteger(10, Major))
6704 if (!Str.consume_front(
"."))
6707 if (Str.consumeInteger(10, Minor))
6711 if (!Str.consume_front(
"."))
6714 if (Str.consumeInteger(10, Micro))
6732 unsigned CurDigit = 0;
6733 while (CurDigit < Digits.size()) {
6735 if (Str.consumeInteger(10, Digit))
6737 Digits[CurDigit] = Digit;
6740 if (!Str.consume_front(
"."))
6749llvm::opt::Visibility
6750Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
6763const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
6779 llvm_unreachable(
"Unhandled Mode");
6783 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
6788 if (Args.hasFlag(options::OPT_fsave_optimization_record,
6789 options::OPT_fno_save_optimization_record,
false))
6793 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
6794 options::OPT_fno_save_optimization_record,
false))
6798 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
6799 options::OPT_fno_save_optimization_record,
false))
6803 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
6804 options::OPT_fno_save_optimization_record,
false))
6811 static StringRef OptName =
6813 llvm::StringRef Opt;
6814 for (StringRef Arg : Args) {
6815 if (!Arg.starts_with(OptName))
6821 return Opt.consume_front(OptName) ? Opt :
"";
6828 llvm::BumpPtrAllocator &Alloc,
6829 llvm::vfs::FileSystem *FS) {
6838 for (
const char *F : Args) {
6839 if (strcmp(F,
"--rsp-quoting=posix") == 0)
6841 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
6842 RSPQuoting = Windows;
6850 llvm::cl::TokenizerCallback Tokenizer;
6852 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
6854 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
6856 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
6859 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
6860 ECtx.setMarkEOLs(MarkEOLs);
6864 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
6868 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
6869 [](
const char *A) {
return A !=
nullptr; });
6870 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
6873 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
6874 Args.resize(newEnd - Args.begin());
6878 return llvm::Error::success();
6882 return SavedStrings.insert(S).first->getKeyData();
6915 llvm::StringSet<> &SavedStrings) {
6918 if (Edit[0] ==
'^') {
6919 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6920 OS <<
"### Adding argument " << Str <<
" at beginning\n";
6921 Args.insert(Args.begin() + 1, Str);
6922 }
else if (Edit[0] ==
'+') {
6923 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
6924 OS <<
"### Adding argument " << Str <<
" at end\n";
6925 Args.push_back(Str);
6926 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
6927 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
6928 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
6929 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
6930 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
6932 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
6934 if (Args[i] ==
nullptr)
6936 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
6938 if (Repl != Args[i]) {
6939 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
6943 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
6944 auto Option = Edit.substr(1);
6945 for (
unsigned i = 1; i < Args.size();) {
6946 if (Option == Args[i]) {
6947 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6948 Args.erase(Args.begin() + i);
6949 if (Edit[0] ==
'X') {
6950 if (i < Args.size()) {
6951 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6952 Args.erase(Args.begin() + i);
6954 OS <<
"### Invalid X edit, end of command line!\n";
6959 }
else if (Edit[0] ==
'O') {
6960 for (
unsigned i = 1; i < Args.size();) {
6961 const char *A = Args[i];
6965 if (A[0] ==
'-' && A[1] ==
'O' &&
6966 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
6967 (
'0' <= A[2] && A[2] <=
'9'))))) {
6968 OS <<
"### Deleting argument " << Args[i] <<
'\n';
6969 Args.erase(Args.begin() + i);
6973 OS <<
"### Adding argument " << Edit <<
" at end\n";
6974 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
6976 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
6981 const char *OverrideStr,
6982 llvm::StringSet<> &SavedStrings,
6985 OS = &llvm::nulls();
6987 if (OverrideStr[0] ==
'#') {
6989 OS = &llvm::nulls();
6992 *OS <<
"### CCC_OVERRIDE_OPTIONS: " << OverrideStr <<
"\n";
6996 const char *S = OverrideStr;
6998 const char *End = ::strchr(S,
' ');
7000 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 const char BugReporMsg[]
static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, SmallString< 128 > &ConfigFilePath, llvm::Triple Triple, std::string Suffix)
static bool ScanDirForExecutable(SmallString< 128 > &Dir, StringRef Name)
static std::optional< llvm::Triple > getOffloadTargetTriple(const Driver &D, const ArgList &Args)
static void appendOneArg(InputArgList &Args, const Arg *Opt)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines version macros and version-related utility functions for Clang.
__DEVICE__ int max(int __a, int __b)
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool hasErrorOccurred() const
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const
Based on the way the client configured the DiagnosticsEngine object, classify the specified diagnosti...
Encodes a location in the source.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
unsigned getOffloadingHostActiveKinds() const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void replaceArguments(llvm::opt::ArgStringList List)
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Compilation - A set of tasks to perform for a single driver invocation.
A class to find a viable CUDA installation.
void WarnIfUnsupportedVersion()
bool isValid() const
Check whether we detected a valid Cuda install.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, Action *HostAction) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
llvm::DenseSet< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain *TC, bool SuppressError=false) const
Returns the set of bound architectures active for this offload kind.
void BuildJobs(Compilation &C) const
BuildJobs - Bind actions to concrete tools and translate arguments to form the list of jobs to run.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput, std::map< std::pair< const Action *, std::string >, InputInfoList > &CachedResults, Action::OffloadKind TargetDeviceOffloadKind) const
BuildJobsForAction - Construct the jobs to perform for the action A and return an InputInfo for the r...
std::string GetFilePath(StringRef Name, const ToolChain &TC) const
GetFilePath - Lookup Name in the list of file search paths.
unsigned CCPrintProcessStats
Set CC_PRINT_PROC_STAT mode, which causes the driver to dump performance report to CC_PRINT_PROC_STAT...
DiagnosticsEngine & getDiags() const
void PrintActions(const Compilation &C) const
PrintActions - Print the list of actions.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, StringRef BoundArch, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
static std::string GetResourcesPath(StringRef BinaryPath)
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args, InputList &Inputs) const
BuildInputs - Construct the list of inputs and their types from the given arguments.
unsigned CCGenDiagnostics
Whether the driver is generating diagnostics for debugging purposes.
bool HandleImmediateArgs(Compilation &C)
HandleImmediateArgs - Handle any arguments which should be treated before building actions or binding...
int ExecuteCompilation(Compilation &C, SmallVectorImpl< std::pair< int, const Command * > > &FailingCommands)
ExecuteCompilation - Execute the compilation according to the command line arguments and return an ap...
DiagnosticBuilder Diag(unsigned DiagID) const
std::string SystemConfigDir
System directory for config files.
ParsedClangName ClangNameParts
Target and driver mode components extracted from clang executable name.
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
std::string Name
The name the driver was invoked as.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
std::string ClangExecutable
The original path to the clang executable.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
std::pair< types::ID, const llvm::opt::Arg * > InputTy
An input type and its arguments.
bool isUsingOffloadLTO() const
Returns true if we are performing any kind of offload LTO.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError)
ParseArgStrings - Parse the given list of strings into an ArgList.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
bool ShouldUseClangCompiler(const JobAction &JA) const
ShouldUseClangCompiler - Should the clang compiler be used to handle this action.
std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const
GetTemporaryPath - Return the pathname of a temporary file to use as part of compilation; the file wi...
std::string Dir
The path the driver executable was in, as invoked from the command line.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
const char * getPhaseName(ID Id)
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
llvm::SmallVector< phases::ID, phases::MaxNumberOfPhases > getCompilationPhases(ID Id, phases::ID LastPhase=phases::IfsMerge)
getCompilationPhases - Get the list of compilation phases ('Phases') to be done for type 'Id' up unti...
bool isSrcFile(ID Id)
isSrcFile - Is this a source file, i.e.
ID lookupCXXTypeForCType(ID Id)
lookupCXXTypeForCType - Lookup CXX input type that corresponds to given C type (used for clang++ emul...
bool isHIP(ID Id)
isHIP - Is this a HIP input.
bool isAcceptedByClang(ID Id)
isAcceptedByClang - Can clang handle this input type.
bool appendSuffixForType(ID Id)
appendSuffixForType - When generating outputs of this type, should the suffix be appended (instead of...
bool canLipoType(ID Id)
canLipoType - Is this type acceptable as the output of a universal build (currently,...
const char * getTypeTempSuffix(ID Id, bool CLStyle=false)
getTypeTempSuffix - Return the suffix to use when creating a temp file of this type,...
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
bool isAcceptedByFlang(ID Id)
isAcceptedByFlang - Can flang handle this input type.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
const llvm::opt::OptTable & getDriverOptTable()
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ EmitLLVM
Emit a .ll file.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
static bool IsAMDOffloadArch(OffloadArch A)
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
std::string getClangToolFullVersion(llvm::StringRef ToolName)
Like getClangFullVersion(), but with a custom tool name.
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)
Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...
@ Result
The result type of a method or function.
static bool IsNVIDIAOffloadArch(OffloadArch A)
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
const FunctionProtoType * T
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
std::string ModeSuffix
Driver mode part of the executable name, as g++.
std::string TargetPrefix
Target part of the executable name, as i686-linux-android.