59#include "clang/Config/config.h"
71#include "llvm/ADT/ArrayRef.h"
72#include "llvm/ADT/STLExtras.h"
73#include "llvm/ADT/SmallSet.h"
74#include "llvm/ADT/SmallVector.h"
75#include "llvm/ADT/StringExtras.h"
76#include "llvm/ADT/StringRef.h"
77#include "llvm/ADT/StringSet.h"
78#include "llvm/ADT/StringSwitch.h"
79#include "llvm/Config/llvm-config.h"
80#include "llvm/MC/TargetRegistry.h"
81#include "llvm/Option/Arg.h"
82#include "llvm/Option/ArgList.h"
83#include "llvm/Option/OptSpecifier.h"
84#include "llvm/Option/OptTable.h"
85#include "llvm/Option/Option.h"
86#include "llvm/Support/CommandLine.h"
87#include "llvm/Support/ErrorHandling.h"
88#include "llvm/Support/ExitCodes.h"
89#include "llvm/Support/FileSystem.h"
90#include "llvm/Support/FileUtilities.h"
91#include "llvm/Support/FormatVariadic.h"
92#include "llvm/Support/IOSandbox.h"
93#include "llvm/Support/MD5.h"
94#include "llvm/Support/Path.h"
95#include "llvm/Support/PrettyStackTrace.h"
96#include "llvm/Support/Process.h"
97#include "llvm/Support/Program.h"
98#include "llvm/Support/Regex.h"
99#include "llvm/Support/StringSaver.h"
100#include "llvm/Support/VirtualFileSystem.h"
101#include "llvm/Support/raw_ostream.h"
102#include "llvm/TargetParser/Host.h"
103#include "llvm/TargetParser/RISCVISAInfo.h"
116using namespace clang;
119template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
120 return llvm::any_of(Args, [&](Arg *A) {
121 return (A->getOption().matches(options::OPT_x) &&
123 (A->getOption().
getKind() == Option::InputClass &&
124 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
126 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
132 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
133 StringRef UseCUIDStr = A->getValue();
134 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
135 .Case(
"hash", Kind::Hash)
136 .Case(
"random", Kind::Random)
137 .Case(
"none", Kind::None)
138 .Default(Kind::Invalid);
139 if (UseCUID == Kind::Invalid)
140 D.Diag(clang::diag::err_drv_invalid_value)
141 << A->getAsString(Args) << UseCUIDStr;
144 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
145 if (!FixedCUID.empty())
150 llvm::opt::DerivedArgList &Args)
const {
151 std::string CUID = FixedCUID.str();
154 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
158 llvm::MD5::MD5Result
Hash;
159 Hasher.update(InputFile);
160 for (
auto *A : Args) {
161 if (A->getOption().matches(options::OPT_INPUT))
163 Hasher.update(A->getAsString(Args));
166 CUID = llvm::utohexstr(
Hash.low(),
true);
174 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
175 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
182 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
183 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
184 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
187 this->VFS = llvm::vfs::getRealFileSystem();
192 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
195 llvm::sys::path::append(P,
SysRoot);
199#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
200 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
204 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
205 llvm::sys::path::remove_dots(configFileDir,
true);
209#if defined(CLANG_CONFIG_FILE_USER_DIR)
212 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
221void Driver::setDriverMode(StringRef
Value) {
222 static StringRef OptName =
223 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
224 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
225 .Case(
"gcc", GCCMode)
226 .Case(
"g++", GXXMode)
227 .Case(
"cpp", CPPMode)
229 .Case(
"flang", FlangMode)
230 .Case(
"dxc", DXCMode)
234 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
239 bool &ContainsError)
const {
240 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
241 ContainsError =
false;
243 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
244 unsigned MissingArgIndex, MissingArgCount;
245 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
246 MissingArgCount, VisibilityMask);
249 if (MissingArgCount) {
250 Diag(diag::err_drv_missing_argument)
251 << Args.getArgString(MissingArgIndex) << MissingArgCount;
253 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
258 for (
const Arg *A : Args) {
260 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
261 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
268 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
269 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
270 ContainsError |= Diags.getDiagnosticLevel(
271 diag::warn_drv_empty_joined_argument,
276 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
278 auto ArgString = A->getAsString(Args);
280 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
282 if (
getOpts().findExact(ArgString, Nearest,
284 DiagID = diag::err_drv_unknown_argument_with_suggestion;
285 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
287 DiagID = diag::err_drv_unknown_argument;
288 Diags.Report(DiagID) << ArgString;
291 llvm::opt::Visibility(
293 DiagID = diag::err_drv_unknown_argument_with_suggestion;
294 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
296 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
297 : diag::err_drv_unknown_argument;
298 Diags.Report(DiagID) << ArgString;
302 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
303 : diag::err_drv_unknown_argument_with_suggestion;
304 Diags.Report(DiagID) << ArgString << Nearest;
306 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
310 for (
const Arg *A : Args.filtered(options::OPT_o)) {
311 if (ArgStrings[A->getIndex()] == A->getSpelling())
315 std::string ArgString = ArgStrings[A->getIndex()];
317 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
318 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
319 << A->getAsString(Args) << Nearest;
329 Arg **FinalPhaseArg)
const {
330 Arg *PhaseArg =
nullptr;
334 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
335 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
336 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
337 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
344 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
345 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
346 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
347 options::OPT_fmodule_header_EQ))) {
350 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
351 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
353 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
354 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
355 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
356 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
357 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
358 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
359 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
360 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
364 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
368 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
371 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
379 *FinalPhaseArg = PhaseArg;
387 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
388 llvm::sys::fs::OF_Text);
389 llvm::FileRemover OutputRemover(OutputFile.c_str());
390 std::optional<llvm::StringRef> Redirects[] = {
396 std::string ErrorMessage;
397 int SecondsToWait = 60;
398 if (std::optional<std::string> Str =
399 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
400 if (!llvm::to_integer(*Str, SecondsToWait))
401 return llvm::createStringError(std::error_code(),
402 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
403 "an integer, got '" +
405 SecondsToWait = std::max(SecondsToWait, 0);
407 StringRef Executable = Args[0];
408 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
410 return llvm::createStringError(std::error_code(),
411 Executable +
": " + ErrorMessage);
413 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
414 llvm::MemoryBuffer::getFile(OutputFile.c_str());
416 return llvm::createStringError(OutputBuf.getError(),
417 "Failed to read stdout of " + Executable +
418 ": " + OutputBuf.getError().message());
419 return std::move(*OutputBuf);
423 StringRef
Value,
bool Claim =
true) {
424 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
425 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
426 Args.AddSynthesizedArg(A);
432DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
433 const llvm::opt::OptTable &Opts =
getOpts();
434 DerivedArgList *DAL =
new DerivedArgList(Args);
436 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
437 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
438 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
439 bool IgnoreUnused =
false;
440 for (Arg *A : Args) {
444 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
448 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
449 IgnoreUnused =
false;
459 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
460 A->getOption().matches(options::OPT_Xlinker)) &&
461 A->containsValue(
"--no-demangle")) {
463 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
466 for (StringRef Val : A->getValues())
467 if (Val !=
"--no-demangle")
468 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
476 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
477 A->getNumValues() > 0 &&
478 (A->getValue(0) == StringRef(
"-MD") ||
479 A->getValue(0) == StringRef(
"-MMD"))) {
481 if (A->getValue(0) == StringRef(
"-MD"))
482 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
484 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
485 if (A->getNumValues() == 2)
486 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
491 if (A->getOption().matches(options::OPT_l)) {
492 StringRef
Value = A->getValue();
495 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
497 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
502 if (
Value ==
"cc_kext") {
503 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
509 if (A->getOption().matches(options::OPT__DASH_DASH)) {
511 for (StringRef Val : A->getValues())
520 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
521 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
524 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
525 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
529#if defined(HOST_LINK_VERSION)
530 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
531 strlen(HOST_LINK_VERSION) > 0) {
532 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
534 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
542 StringRef ArgTarget) {
544 static bool BeSilent =
false;
545 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
546 return ((v < 2) || ((v == 2) && (r < 4)));
550 if (ArgTarget.equals_insensitive(
"CURRENT")) {
554 unsigned int Version = 0;
555 unsigned int Release = 0;
556 unsigned int Modification = 0;
558 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
559 llvm::Regex HexRegex(
562 "([0-9a-fA-F][0-9a-fA-F])"
563 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
566 if (ZOsvRegex.match(ArgTarget, &Matches)) {
567 Matches[1].getAsInteger(10, Version);
568 Matches[2].getAsInteger(10, Release);
570 if (IsTooOldToBeSupported(Version, Release)) {
572 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
575 }
else if (HexRegex.match(ArgTarget, &Matches)) {
576 Matches[1].getAsInteger(16, Version);
577 Matches[2].getAsInteger(16, Release);
578 Matches[3].getAsInteger(16, Modification);
579 if (IsTooOldToBeSupported(Version, Release)) {
581 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
587 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
592 llvm::VersionTuple
V(Version, Release, Modification);
593 llvm::VersionTuple TV =
Target.getOSVersion();
596 if (TV.empty() ||
V < TV) {
598 Str = llvm::Triple::getOSTypeName(
Target.getOS());
599 Str +=
V.getAsString();
612 StringRef TargetTriple,
614 StringRef DarwinArchName =
"") {
616 if (
const Arg *A = Args.getLastArg(options::OPT_target))
617 TargetTriple = A->getValue();
619 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
624 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
628 if (
Target.isOSBinFormatMachO()) {
630 if (!DarwinArchName.empty()) {
637 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
638 StringRef ArchName = A->getValue();
645 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
646 options::OPT_mbig_endian)) {
647 llvm::Triple
T = A->getOption().matches(options::OPT_mlittle_endian)
648 ?
Target.getLittleEndianArchVariant()
649 :
Target.getBigEndianArchVariant();
650 if (
T.getArch() != llvm::Triple::UnknownArch) {
652 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
657 if (
Target.getArch() == llvm::Triple::tce)
662 if (std::optional<std::string> ObjectModeValue =
663 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
664 StringRef ObjectMode = *ObjectModeValue;
665 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
667 if (ObjectMode ==
"64") {
668 AT =
Target.get64BitArchVariant().getArch();
669 }
else if (ObjectMode ==
"32") {
670 AT =
Target.get32BitArchVariant().getArch();
672 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
675 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch())
681 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
682 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
685 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
687 D.
Diag(diag::err_drv_unsupported_opt_for_target)
688 << A->getAsString(Args) <<
Target.str();
691 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
692 options::OPT_m32, options::OPT_m16,
693 options::OPT_maix32, options::OPT_maix64);
695 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
697 if (A->getOption().matches(options::OPT_m64) ||
698 A->getOption().matches(options::OPT_maix64)) {
699 AT =
Target.get64BitArchVariant().getArch();
700 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
701 Target.getEnvironment() == llvm::Triple::GNUT64)
702 Target.setEnvironment(llvm::Triple::GNU);
703 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
704 Target.setEnvironment(llvm::Triple::Musl);
705 }
else if (A->getOption().matches(options::OPT_mx32) &&
706 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
707 AT = llvm::Triple::x86_64;
708 if (
Target.getEnvironment() == llvm::Triple::Musl)
709 Target.setEnvironment(llvm::Triple::MuslX32);
711 Target.setEnvironment(llvm::Triple::GNUX32);
712 }
else if (A->getOption().matches(options::OPT_m32) ||
713 A->getOption().matches(options::OPT_maix32)) {
715 D.
Diag(diag::err_drv_unsupported_opt_for_target)
716 << A->getAsString(Args) <<
Target.str();
718 AT =
Target.get32BitArchVariant().getArch();
719 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
720 Target.setEnvironment(llvm::Triple::GNU);
721 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
722 Target.setEnvironment(llvm::Triple::Musl);
724 }
else if (A->getOption().matches(options::OPT_m16) &&
725 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
726 AT = llvm::Triple::x86;
727 Target.setEnvironment(llvm::Triple::CODE16);
730 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
732 if (
Target.isWindowsGNUEnvironment())
738 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
744 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
745 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
746 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
749 if (A && !A->getOption().matches(options::OPT_m32))
750 D.
Diag(diag::err_drv_argument_not_allowed_with)
751 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
753 Target.setArch(llvm::Triple::x86);
754 Target.setArchName(
"i586");
755 Target.setEnvironment(llvm::Triple::UnknownEnvironment);
756 Target.setEnvironmentName(
"");
757 Target.setOS(llvm::Triple::ELFIAMCU);
758 Target.setVendor(llvm::Triple::UnknownVendor);
759 Target.setVendorName(
"intel");
765 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
766 StringRef ABIName = A->getValue();
767 if (ABIName ==
"32") {
769 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
770 Target.getEnvironment() == llvm::Triple::GNUABIN32)
771 Target.setEnvironment(llvm::Triple::GNU);
772 }
else if (ABIName ==
"n32") {
774 if (
Target.getEnvironment() == llvm::Triple::GNU ||
775 Target.getEnvironment() == llvm::Triple::GNUT64 ||
776 Target.getEnvironment() == llvm::Triple::GNUABI64)
777 Target.setEnvironment(llvm::Triple::GNUABIN32);
778 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
779 Target.getEnvironment() == llvm::Triple::MuslABI64)
780 Target.setEnvironment(llvm::Triple::MuslABIN32);
781 }
else if (ABIName ==
"64") {
783 if (
Target.getEnvironment() == llvm::Triple::GNU ||
784 Target.getEnvironment() == llvm::Triple::GNUT64 ||
785 Target.getEnvironment() == llvm::Triple::GNUABIN32)
786 Target.setEnvironment(llvm::Triple::GNUABI64);
787 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
788 Target.getEnvironment() == llvm::Triple::MuslABIN32)
789 Target.setEnvironment(llvm::Triple::MuslABI64);
797 if (Args.hasArg(options::OPT_march_EQ) ||
798 Args.hasArg(options::OPT_mcpu_EQ)) {
800 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
802 if (!llvm::errorToBool(ISAInfo.takeError())) {
803 unsigned XLen = (*ISAInfo)->getXLen();
805 Target.setArch(llvm::Triple::riscv32);
807 Target.setArch(llvm::Triple::riscv64);
819 OptSpecifier OptEq, OptSpecifier OptNeg) {
820 if (!Args.hasFlag(OptEq, OptNeg,
false))
823 const Arg *A = Args.getLastArg(OptEq);
824 StringRef LTOName = A->getValue();
832 D.
Diag(diag::err_drv_unsupported_option_argument)
833 << A->getSpelling() << A->getValue();
840void Driver::setLTOMode(
const llvm::opt::ArgList &Args) {
842 parseLTOMode(*
this, Args, options::OPT_flto_EQ, options::OPT_fno_lto);
844 OffloadLTOMode =
parseLTOMode(*
this, Args, options::OPT_foffload_lto_EQ,
845 options::OPT_fno_offload_lto);
848 if (Args.hasFlag(options::OPT_fopenmp_target_jit,
849 options::OPT_fno_openmp_target_jit,
false)) {
850 if (Arg *A = Args.getLastArg(options::OPT_foffload_lto_EQ,
851 options::OPT_fno_offload_lto))
853 Diag(diag::err_drv_incompatible_options)
854 << A->getSpelling() <<
"-fopenmp-target-jit";
861 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
863 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
865 RuntimeName = A->getValue();
867 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
875 Diag(diag::err_drv_unsupported_option_argument)
876 << A->getSpelling() << A->getValue();
879 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
888 StringRef Program =
C.getArgs().getLastArgValue(
889 options::OPT_offload_arch_tool_EQ,
"offload-arch");
892 if (llvm::ErrorOr<std::string> Executable =
893 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
896 Args.push_back(
"--only=amdgpu");
898 Args.push_back(
"--only=nvptx");
899 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
902 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
907 if ((*StdoutOrErr)->getBuffer().empty()) {
908 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
914 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
916 GPUArchs.push_back(
Arch.str());
918 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
925static llvm::DenseSet<llvm::StringRef>
927 std::set<std::string> Archs;
928 for (Arg *A :
C.getInputArgs()) {
929 for (StringRef
Arch : A->getValues()) {
930 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
931 if (
Arch ==
"native") {
933 Archs.insert(Str.str());
935 Archs.insert(
Arch.str());
937 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
941 Archs.erase(
Arch.str());
946 llvm::DenseSet<llvm::StringRef> Triples;
947 for (llvm::StringRef
Arch : Archs) {
954 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
956 return llvm::DenseSet<llvm::StringRef>();
959 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
961 return llvm::DenseSet<llvm::StringRef>();
965 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
967 return llvm::DenseSet<llvm::StringRef>();
970 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
971 <<
"offload" <<
Arch;
972 return llvm::DenseSet<llvm::StringRef>();
977 Triple =
"spirv64-amd-amdhsa";
979 Triple =
C.getDefaultToolChain().getTriple().isArch64Bit()
980 ?
"nvptx64-nvidia-cuda"
981 :
"nvptx-nvidia-cuda";
983 Triple =
"amdgcn-amd-amdhsa";
990 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
991 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
992 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
993 C.getArgs().MakeArgString(Triple.split(
"-").first),
994 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
996 C.getArgs().append(A);
997 C.getArgs().AddSynthesizedArg(A);
998 Triples.insert(Triple);
1003 Triples.insert(
"amdgcn-amd-amdhsa");
1005 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1006 ?
"nvptx64-nvidia-cuda"
1007 :
"nvptx-nvidia-cuda");
1009 Triples.insert(
C.getDefaultToolChain().getTriple().isArch64Bit()
1010 ?
"spirv64-unknown-unknown"
1011 :
"spirv32-unknown-unknown");
1014 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1015 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1022 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1023 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1025 llvm::any_of(Inputs,
1026 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1031 (llvm::any_of(Inputs,
1032 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1035 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1036 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1038 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1039 options::OPT_fno_sycl,
false);
1040 bool IsOpenMPOffloading =
1042 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1043 options::OPT_fno_openmp,
false) &&
1044 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1045 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1046 !(IsCuda || IsHIP))));
1048 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1049 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1054 for (
const auto &[Active, Kind] : ActiveKinds)
1059 if (Kinds.size() > 1) {
1060 Diag(clang::diag::err_drv_mix_offload)
1067 if (IsCuda || IsHIP)
1073 std::multiset<llvm::StringRef> Triples;
1074 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1075 std::vector<std::string> ArgValues =
1076 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1077 for (llvm::StringRef
Target : ArgValues)
1078 Triples.insert(
C.getInputArgs().MakeArgString(
Target));
1080 if (ArgValues.empty())
1081 Diag(clang::diag::warn_drv_empty_joined_argument)
1083 .getLastArg(options::OPT_offload_targets_EQ)
1084 ->getAsString(
C.getInputArgs());
1085 }
else if (Kinds.size() > 0) {
1088 Triples.insert(Derived.begin(), Derived.end());
1093 llvm::StringMap<StringRef> FoundNormalizedTriples;
1094 for (StringRef
Target : Triples) {
1099 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1107 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1108 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1109 Diag(clang::diag::err_drv_argument_not_allowed_with)
1110 << IncompatArg->getSpelling() <<
"-fsycl";
1118 if (TT.getArch() == llvm::Triple::ArchType::UnknownArch) {
1119 Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT.str();
1123 std::string NormalizedName = TT.normalize();
1124 auto [TripleIt, Inserted] =
1125 FoundNormalizedTriples.try_emplace(NormalizedName,
Target);
1127 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1128 <<
Target << TripleIt->second;
1132 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind, TT,
1133 C.getDefaultToolChain().getTriple());
1137 auto &CudaInstallation =
1139 if (CudaInstallation.isValid())
1140 CudaInstallation.WarnIfUnsupportedVersion();
1143 C.addOffloadDeviceToolChain(&TC, Kind);
1148bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1153 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1157 if (!PathLIBEnv.empty()) {
1158 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1159 if (llvm::sys::fs::is_directory(PathLIBEnv))
1160 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1161 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1162 return readConfigFile(CustomizationFile, ExpCtx);
1163 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1168 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1169 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1170 return readConfigFile(CustomizationFile, ExpCtx);
1180 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1181 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1182 Copy->getValues() = Opt->getValues();
1183 if (Opt->isClaimed())
1185 Copy->setOwnsValues(Opt->getOwnsValues());
1186 Opt->setOwnsValues(
false);
1188 if (Opt->getAlias()) {
1189 const Arg *Alias = Opt->getAlias();
1190 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1191 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1192 Args.getArgString(Index), Index);
1193 AliasCopy->getValues() = Alias->getValues();
1194 AliasCopy->setOwnsValues(
false);
1195 if (Alias->isClaimed())
1197 Copy->setAlias(std::move(AliasCopy));
1201bool Driver::readConfigFile(StringRef
FileName,
1202 llvm::cl::ExpansionContext &ExpCtx) {
1206 Diag(diag::err_drv_cannot_open_config_file)
1207 <<
FileName << Status.getError().message();
1210 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1211 Diag(diag::err_drv_cannot_open_config_file)
1212 <<
FileName <<
"not a regular file";
1217 SmallVector<const char *, 32> NewCfgFileArgs;
1218 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1219 Diag(diag::err_drv_cannot_read_config_file)
1225 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1226 for (
const char *Opt : NewCfgFileArgs) {
1228 if (Opt[0] ==
'$' && Opt[1])
1229 NewCfgTailArgs.push_back(Opt + 1);
1231 NewCfgHeadArgs.push_back(Opt);
1235 llvm::SmallString<128> CfgFileName(
FileName);
1236 llvm::sys::path::native(CfgFileName);
1237 bool ContainErrors =
false;
1238 auto NewHeadOptions = std::make_unique<InputArgList>(
1242 auto NewTailOptions = std::make_unique<InputArgList>(
1249 for (Arg *A : *NewHeadOptions)
1251 for (Arg *A : *NewTailOptions)
1254 if (!CfgOptionsHead)
1255 CfgOptionsHead = std::move(NewHeadOptions);
1258 for (
auto *Opt : *NewHeadOptions)
1262 if (!CfgOptionsTail)
1263 CfgOptionsTail = std::move(NewTailOptions);
1266 for (
auto *Opt : *NewTailOptions)
1270 ConfigFiles.push_back(std::string(CfgFileName));
1274bool Driver::loadConfigFiles() {
1275 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1276 llvm::cl::tokenizeConfigFile);
1277 ExpCtx.setVFS(&
getVFS());
1281 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1282 SmallString<128> CfgDir;
1284 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1285 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1290 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1291 SmallString<128> CfgDir;
1292 llvm::sys::fs::expand_tilde(
1293 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1294 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1303 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1306 if (loadDefaultConfigFiles(ExpCtx))
1310 SmallString<128> CfgFilePath;
1312 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1315 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1316 CfgFilePath.assign(CfgFileName);
1317 if (llvm::sys::path::is_relative(CfgFilePath)) {
1318 if (
getVFS().makeAbsolute(CfgFilePath)) {
1319 Diag(diag::err_drv_cannot_open_config_file)
1320 << CfgFilePath <<
"cannot get absolute path";
1324 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1326 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1327 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1328 if (!SearchDir.empty())
1329 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1334 if (readConfigFile(CfgFilePath, ExpCtx))
1345 llvm::Triple Triple, std::string Suffix) {
1347 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1351 VersionTuple OSVersion = Triple.getOSVersion();
1352 if (!OSVersion.getMinor().has_value())
1355 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1359 if (OSVersion.getMajor() != 0) {
1360 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1361 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1367 Triple.setOSName(BaseOSName);
1368 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1371bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1374 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1378 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1381 std::string RealMode = getExecutableForDriverMode(Mode);
1382 llvm::Triple Triple;
1391 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1392 PrefixTriple.isOSUnknown())
1393 Triple = PrefixTriple;
1397 llvm::Triple RealTriple =
1399 if (Triple.str().empty()) {
1400 Triple = RealTriple;
1401 assert(!Triple.str().empty());
1406 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1420 SmallString<128> CfgFilePath;
1422 "-" + RealMode +
".cfg"))
1423 return readConfigFile(CfgFilePath, ExpCtx);
1427 if (TryModeSuffix) {
1430 return readConfigFile(CfgFilePath, ExpCtx);
1435 std::string CfgFileName = RealMode +
".cfg";
1436 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1437 if (readConfigFile(CfgFilePath, ExpCtx))
1439 }
else if (TryModeSuffix) {
1441 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1442 readConfigFile(CfgFilePath, ExpCtx))
1448 return readConfigFile(CfgFilePath, ExpCtx);
1456 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1465 if (!DriverMode.empty())
1466 setDriverMode(DriverMode);
1472 CLOptions = std::make_unique<InputArgList>(
1477 ContainsError = loadConfigFiles();
1478 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1479 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1483 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1485 if (HasConfigFileHead)
1486 for (
auto *Opt : *CLOptions)
1487 if (!Opt->getOption().matches(options::OPT_config))
1491 if (
IsCLMode() && !ContainsError) {
1493 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1495 CLModePassThroughArgList.push_back(A->getValue());
1498 if (!CLModePassThroughArgList.empty()) {
1501 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1506 for (
auto *Opt : *CLModePassThroughOptions)
1512 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1513 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1514 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1517 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1518 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1519 if (!VFS->exists(IncludeDir))
1520 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1525 bool CCCPrintPhases;
1528 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1529 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1532 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1533 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1536 Args.ClaimAllArgs(options::OPT_pipe);
1544 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1546 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1547 CCCGenericGCCName = A->getValue();
1550 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1554 if (Args.hasArg(options::OPT_fproc_stat_report))
1561 llvm::Triple
T(TargetTriple);
1562 T.setOS(llvm::Triple::Win32);
1563 T.setVendor(llvm::Triple::PC);
1564 T.setEnvironment(llvm::Triple::MSVC);
1565 T.setObjectFormat(llvm::Triple::COFF);
1566 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1567 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1568 TargetTriple =
T.str();
1571 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1572 StringRef TargetProfile = A->getValue();
1575 TargetTriple = *Triple;
1577 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1581 if (Args.hasArg(options::OPT_spirv)) {
1582 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1583 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1584 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1585 llvm::Triple
T(TargetTriple);
1588 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1590 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1591 TargetInfo = ValidTargets.find(A->getValue());
1593 Diag(diag::err_drv_invalid_value)
1594 << A->getAsString(Args) << A->getValue();
1600 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1601 TargetTriple =
T.str();
1605 Diag(diag::err_drv_dxc_missing_target_profile);
1609 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1610 TargetTriple = A->getValue();
1611 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1612 Dir =
Dir = A->getValue();
1613 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1617 if (std::optional<std::string> CompilerPathValue =
1618 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1619 StringRef CompilerPath = *CompilerPathValue;
1620 while (!CompilerPath.empty()) {
1621 std::pair<StringRef, StringRef> Split =
1622 CompilerPath.split(llvm::sys::EnvPathSeparator);
1623 PrefixDirs.push_back(std::string(Split.first));
1624 CompilerPath = Split.second;
1627 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1629 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1632 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1635 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1636 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1637 .Case(
"cwd", SaveTempsCwd)
1638 .Case(
"obj", SaveTempsObj)
1639 .Default(SaveTempsCwd);
1642 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1643 options::OPT_offload_device_only,
1644 options::OPT_offload_host_device)) {
1645 if (A->getOption().matches(options::OPT_offload_host_only))
1646 Offload = OffloadHost;
1647 else if (A->getOption().matches(options::OPT_offload_device_only))
1648 Offload = OffloadDevice;
1650 Offload = OffloadHostDevice;
1656 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1657 StringRef
Name = A->getValue();
1658 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1659 .Case(
"off", EmbedNone)
1660 .Case(
"all", EmbedBitcode)
1661 .Case(
"bitcode", EmbedBitcode)
1662 .Case(
"marker", EmbedMarker)
1665 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1668 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1672 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1673 llvm::sys::fs::remove(A->getValue());
1679 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1681 !Args.hasArg(options::OPT_fmodules) && Std &&
1682 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1683 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1684 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1685 Std->containsValue(
"c++latest"));
1688 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1689 options::OPT_fmodule_header)) {
1691 ModulesModeCXX20 =
true;
1692 if (A->getOption().matches(options::OPT_fmodule_header))
1695 StringRef ArgName = A->getValue();
1696 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1701 Diags.Report(diag::err_drv_invalid_value)
1702 << A->getAsString(Args) << ArgName;
1708 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1709 std::make_unique<InputArgList>(std::move(Args));
1719 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1720 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1722 bool MLContainsError;
1723 auto MultilibMacroDefineList =
1725 MLMacroDefinesChar,
false, MLContainsError));
1726 if (!MLContainsError) {
1727 for (
auto *Opt : *MultilibMacroDefineList) {
1734 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1738 if (!Triple.isWasm()) {
1739 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1740 StringRef TripleObjectFormat =
1741 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1742 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1743 TripleVersionName != TripleObjectFormat) {
1744 Diags.Report(diag::err_drv_triple_version_invalid)
1746 ContainsError =
true;
1751 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1752 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1753 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1761 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1762 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1764 case llvm::Triple::arm:
1765 case llvm::Triple::armeb:
1766 case llvm::Triple::thumb:
1767 case llvm::Triple::thumbeb:
1768 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1769 Diag(diag::warn_target_unrecognized_env)
1771 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1774 case llvm::Triple::aarch64:
1775 case llvm::Triple::aarch64_be:
1776 case llvm::Triple::aarch64_32:
1777 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1778 Diag(diag::warn_target_unrecognized_env)
1780 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1797 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1798 if (HasConfigFileTail && Inputs.size()) {
1801 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1802 for (Arg *A : *CfgOptionsTail)
1803 TranslatedLinkerIns.append(A);
1804 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1813 if (TC.
getTriple().isOSBinFormatMachO())
1818 if (CCCPrintPhases) {
1829 llvm::opt::ArgStringList ASL;
1830 for (
const auto *A : Args) {
1834 while (A->getAlias())
1836 A->render(Args, ASL);
1839 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1840 if (I != ASL.begin())
1842 llvm::sys::printArg(OS, *I,
true);
1847bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1848 SmallString<128> &CrashDiagDir) {
1849 using namespace llvm::sys;
1850 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1851 "Only knows about .crash files on Darwin");
1853 auto BypassSandbox = sandbox::scopedDisable();
1858 path::home_directory(CrashDiagDir);
1859 if (CrashDiagDir.starts_with(
"/var/root"))
1861 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1869 fs::file_status FileStatus;
1870 TimePoint<> LastAccessTime;
1871 SmallString<128> CrashFilePath;
1874 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1875 File != FileEnd && !EC;
File.increment(EC)) {
1879 if (fs::status(
File->path(), FileStatus))
1881 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1882 llvm::MemoryBuffer::getFile(
File->path());
1887 StringRef
Data = CrashFile.get()->getBuffer();
1888 if (!
Data.starts_with(
"Process:"))
1891 size_t ParentProcPos =
Data.find(
"Parent Process:");
1892 if (ParentProcPos == StringRef::npos)
1894 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1895 if (LineEnd == StringRef::npos)
1897 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1898 int OpenBracket = -1, CloseBracket = -1;
1899 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1900 if (ParentProcess[i] ==
'[')
1902 if (ParentProcess[i] ==
']')
1908 if (OpenBracket < 0 || CloseBracket < 0 ||
1909 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1910 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1920 const auto FileAccessTime = FileStatus.getLastModificationTime();
1921 if (FileAccessTime > LastAccessTime) {
1922 CrashFilePath.assign(
File->path());
1923 LastAccessTime = FileAccessTime;
1928 if (!CrashFilePath.empty()) {
1929 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1939 "\n********************\n\n"
1940 "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n"
1941 "Preprocessed source(s) and associated run script(s) are located at:";
1949 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1953 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1954 Level = llvm::StringSwitch<unsigned>(A->getValue())
1956 .Case(
"compiler", 1)
1968 ArgStringList SavedTemps;
1970 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
1971 if (!IsLLD || Level < 2)
1978 SavedTemps = std::move(
C.getTempFiles());
1979 assert(!
C.getTempFiles().size());
1996 C.initCompilationForDiagnostics();
2001 Command NewLLDInvocation = Cmd;
2002 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2003 StringRef ReproduceOption =
2004 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2007 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2011 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2013 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2014 Diag(clang::diag::note_drv_command_failed_diag_msg)
2015 <<
"\n\n********************";
2017 Report->TemporaryFiles.push_back(TmpName);
2025 ArgStringList IRInputs;
2026 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2027 bool IgnoreInput =
false;
2033 IRInputs.push_back(it->second->getValue());
2037 }
else if (!strcmp(it->second->getValue(),
"-")) {
2038 Diag(clang::diag::note_drv_command_failed_diag_msg)
2039 <<
"Error generating preprocessed source(s) - "
2040 "ignoring input from stdin.";
2045 it = Inputs.erase(it);
2052 if (Inputs.empty() && IRInputs.empty()) {
2053 Diag(clang::diag::note_drv_command_failed_diag_msg)
2054 <<
"Error generating preprocessed source(s) - "
2055 "no preprocessable inputs.";
2062 for (
const Arg *A :
C.getArgs()) {
2063 if (A->getOption().matches(options::OPT_arch)) {
2064 StringRef ArchName = A->getValue();
2069 Diag(clang::diag::note_drv_command_failed_diag_msg)
2070 <<
"Error generating preprocessed source(s) - cannot generate "
2071 "preprocessed source with multiple -arch options.";
2076 if (!Inputs.empty()) {
2079 const ToolChain &TC =
C.getDefaultToolChain();
2080 if (TC.
getTriple().isOSBinFormatMachO())
2089 Diag(clang::diag::note_drv_command_failed_diag_msg)
2090 <<
"Error generating preprocessed source(s).";
2095 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2098 if (!FailingCommands.empty()) {
2099 Diag(clang::diag::note_drv_command_failed_diag_msg)
2100 <<
"Error generating preprocessed source(s).";
2104 const ArgStringList &TempFiles =
C.getTempFiles();
2105 if (TempFiles.empty()) {
2106 Diag(clang::diag::note_drv_command_failed_diag_msg)
2107 <<
"Error generating preprocessed source(s).";
2113 const ArgStringList &Files =
C.getTempFiles();
2118 for (
auto const *Input : IRInputs) {
2122 StringRef extension = llvm::sys::path::extension(Input);
2123 if (!extension.empty())
2124 extension = extension.drop_front();
2126 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2127 llvm::sys::path::stem(Input), extension, FD, Path);
2129 Diag(clang::diag::note_drv_command_failed_diag_msg)
2130 <<
"Error generating run script: " <<
"Failed copying IR input files"
2131 <<
" " << EC.message();
2135 EC = llvm::sys::fs::copy_file(Input, FD);
2137 Diag(clang::diag::note_drv_command_failed_diag_msg)
2138 <<
"Error generating run script: " <<
"Failed copying IR input files"
2139 <<
" " << EC.message();
2143 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2150 for (std::string &TempFile : TempFiles) {
2151 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2153 Report->TemporaryFiles.push_back(TempFile);
2154 if (ReproCrashFilename.empty()) {
2155 ReproCrashFilename = TempFile;
2156 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2158 if (StringRef(TempFile).ends_with(
".cache")) {
2161 VFS = llvm::sys::path::filename(TempFile);
2162 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2166 for (
const char *TempFile : SavedTemps)
2167 TempFiles.push_back(TempFile);
2173 llvm::sys::path::replace_extension(Script,
"sh");
2175 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2176 llvm::sys::fs::FA_Write,
2177 llvm::sys::fs::OF_Text);
2179 Diag(clang::diag::note_drv_command_failed_diag_msg)
2180 <<
"Error generating run script: " << Script <<
" " << EC.message();
2183 <<
"# Driver args: ";
2185 ScriptOS <<
"# Original command: ";
2186 Cmd.
Print(ScriptOS,
"\n",
true);
2187 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2188 if (!AdditionalInformation.empty())
2189 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2192 Report->TemporaryFiles.push_back(std::string(Script));
2193 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2197 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2199 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2200 Diag(clang::diag::note_drv_command_failed_diag_msg)
2201 << ReproCrashFilename.str();
2203 llvm::sys::path::append(CrashDiagDir,
Name);
2204 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2205 Diag(clang::diag::note_drv_command_failed_diag_msg)
2206 <<
"Crash backtrace is located in";
2207 Diag(clang::diag::note_drv_command_failed_diag_msg)
2208 << CrashDiagDir.str();
2209 Diag(clang::diag::note_drv_command_failed_diag_msg)
2210 <<
"(choose the .crash file that corresponds to your crash)";
2214 Diag(clang::diag::note_drv_command_failed_diag_msg)
2215 <<
"\n\n********************";
2225 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2236 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2237 if (
C.getArgs().hasArg(options::OPT_v))
2238 C.getJobs().Print(llvm::errs(),
"\n",
true);
2240 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2243 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2250 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2251 C.getJobs().Print(llvm::errs(),
"\n",
true);
2252 return Diags.hasErrorOccurred() ? 1 : 0;
2256 if (Diags.hasErrorOccurred())
2260 for (
auto &Job :
C.getJobs())
2261 setUpResponseFiles(
C, Job);
2263 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2266 if (FailingCommands.empty())
2272 for (
const auto &CmdPair : FailingCommands) {
2273 int CommandRes = CmdPair.first;
2274 const Command *FailingCommand = CmdPair.second;
2279 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2283 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2288 if (CommandRes == EX_IOERR) {
2305 Diag(clang::diag::err_drv_command_signalled)
2308 Diag(clang::diag::err_drv_command_failed)
2316 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2318 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2332 const ToolChain &TC =
C.getDefaultToolChain();
2336 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2339 OS <<
"Thread model: " << A->getValue();
2345 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2350 if (!llvm::cl::getCompilerBuildConfig().empty())
2351 llvm::cl::printBuildConfig(OS);
2354 for (
auto ConfigFile : ConfigFiles)
2355 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2368 if (PassedFlags ==
"")
2372 std::vector<std::string> SuggestedCompletions;
2373 std::vector<std::string> Flags;
2385 const bool HasSpace = PassedFlags.ends_with(
",");
2389 StringRef TargetFlags = PassedFlags;
2390 while (TargetFlags !=
"") {
2392 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2393 Flags.push_back(std::string(CurFlag));
2398 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2401 const llvm::opt::OptTable &Opts =
getOpts();
2403 Cur = Flags.at(Flags.size() - 1);
2405 if (Flags.size() >= 2) {
2406 Prev = Flags.at(Flags.size() - 2);
2407 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2410 if (SuggestedCompletions.empty())
2411 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2418 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2419 llvm::outs() <<
'\n';
2425 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2429 SuggestedCompletions = Opts.findByPrefix(
2430 Cur, VisibilityMask,
2437 if (S.starts_with(Cur))
2438 SuggestedCompletions.push_back(std::string(S));
2445 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2446 if (
int X = A.compare_insensitive(B))
2448 return A.compare(B) > 0;
2451 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2458 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2459 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2463 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2466 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2470 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2475 if (
C.getArgs().hasArg(options::OPT_help) ||
2476 C.getArgs().hasArg(options::OPT__help_hidden)) {
2477 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2481 if (
C.getArgs().hasArg(options::OPT__version)) {
2487 if (
C.getArgs().hasArg(options::OPT_v) ||
2488 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2489 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2490 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2491 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2493 SuppressMissingInputWarning =
true;
2496 if (
C.getArgs().hasArg(options::OPT_v)) {
2498 llvm::errs() <<
"System configuration file directory: "
2501 llvm::errs() <<
"User configuration file directory: "
2505 const ToolChain &TC =
C.getDefaultToolChain();
2507 if (
C.getArgs().hasArg(options::OPT_v))
2510 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2515 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2516 llvm::outs() <<
"programs: =";
2517 bool separator =
false;
2521 llvm::outs() << llvm::sys::EnvPathSeparator;
2522 llvm::outs() << Path;
2527 llvm::outs() << llvm::sys::EnvPathSeparator;
2528 llvm::outs() << Path;
2531 llvm::outs() <<
"\n";
2534 StringRef sysroot =
C.getSysRoot();
2538 llvm::outs() << llvm::sys::EnvPathSeparator;
2541 llvm::outs() << sysroot << Path.substr(1);
2543 llvm::outs() << Path;
2545 llvm::outs() <<
"\n";
2549 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2555 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2556 for (
auto RuntimePath :
2558 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2559 llvm::outs() << *RuntimePath <<
'\n';
2563 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2567 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2569 for (std::size_t I = 0; I != Flags.size(); I += 2)
2570 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2576 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2577 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2581 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2582 StringRef ProgName = A->getValue();
2585 if (! ProgName.empty())
2588 llvm::outs() <<
"\n";
2592 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2593 StringRef PassedFlags = A->getValue();
2598 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2612 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2615 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2621 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2628 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2631 std::set<llvm::StringRef> SortedFlags;
2632 for (
const auto &FlagEntry : ExpandedFlags)
2633 SortedFlags.insert(FlagEntry.getKey());
2634 for (
auto Flag : SortedFlags)
2635 llvm::outs() << Flag <<
'\n';
2639 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2642 llvm::outs() <<
".\n";
2645 assert(Suffix.front() ==
'/');
2646 llvm::outs() << Suffix.substr(1) <<
"\n";
2652 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2657 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2659 llvm::outs() << Triple.getTriple() <<
"\n";
2663 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2664 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2681 std::map<Action *, unsigned> &Ids,
2683 if (
auto It = Ids.find(A); It != Ids.end())
2687 llvm::raw_string_ostream os(str);
2689 auto getSibIndent = [](
int K) -> Twine {
2693 Twine SibIndent =
Indent + getSibIndent(Kind);
2697 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2699 os <<
'"' << BIA->getArchName() <<
'"' <<
", {"
2700 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2701 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2703 OA->doOnEachDependence(
2705 assert(TC &&
"Unknown host toolchain");
2717 os <<
":" << BoundArch;
2720 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2728 const char *Prefix =
"{";
2729 for (
Action *PreRequisite : *AL) {
2730 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2741 std::string offload_str;
2742 llvm::raw_string_ostream offload_os(offload_str);
2746 offload_os <<
", (" << S;
2753 auto getSelfIndent = [](
int K) -> Twine {
2757 unsigned Id = Ids.size();
2759 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2768 std::map<Action *, unsigned> Ids;
2769 for (
Action *A :
C.getActions())
2785 DerivedArgList &Args =
C.getArgs();
2787 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2792 for (Arg *A : Args) {
2793 if (A->getOption().matches(options::OPT_arch)) {
2796 llvm::Triple::ArchType
Arch =
2798 if (
Arch == llvm::Triple::UnknownArch) {
2799 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2804 if (
ArchNames.insert(A->getValue()).second)
2805 Archs.push_back(A->getValue());
2819 for (
Action* Act : SingleActions) {
2827 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2831 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2836 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2837 Actions.append(Inputs.begin(), Inputs.end());
2839 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2842 Arg *A = Args.getLastArg(options::OPT_g_Group);
2843 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2844 !A->getOption().matches(options::OPT_gstabs);
2852 if (Act->getType() == types::TY_Image) {
2854 Inputs.push_back(Actions.back());
2861 if (Args.hasArg(options::OPT_verify_debug_info)) {
2862 Action *LastAction = Actions.pop_back_val();
2864 LastAction, types::TY_Nothing));
2883 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
2884 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
2896 std::string Nearest;
2897 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
2898 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
2899 <<
Value << Nearest;
2938 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
2941 Diag(clang::diag::err_drv_no_such_file) <<
Value;
2949 return types::TY_CXXUHeader;
2951 return types::TY_CXXSHeader;
2955 llvm_unreachable(
"should not be called in this case");
2957 return types::TY_CXXHUHeader;
2963 const llvm::opt::OptTable &Opts =
getOpts();
2967 types::ID InputType = types::TY_Nothing;
2968 Arg *InputTypeArg =
nullptr;
2971 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
2972 options::OPT__SLASH_TP)) {
2973 InputTypeArg = TCTP;
2974 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
2979 bool ShowNote =
false;
2981 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
2983 Diag(clang::diag::warn_drv_overriding_option)
2984 <<
Previous->getSpelling() << A->getSpelling();
2990 Diag(clang::diag::note_drv_t_option_is_global);
2995 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
2996 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
2997 if (LastXArg && LastInputArg &&
2998 LastInputArg->getIndex() < LastXArg->getIndex())
2999 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3002 for (Arg *A : Args) {
3003 if (A->getOption().
getKind() == Option::InputClass) {
3004 const char *
Value = A->getValue();
3008 if (InputType == types::TY_Nothing) {
3011 InputTypeArg->claim();
3014 if (memcmp(
Value,
"-", 2) == 0) {
3016 Ty = types::TY_Fortran;
3018 Ty = types::TY_HLSL;
3027 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3028 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3029 : clang::diag::err_drv_unknown_stdin_type);
3038 if (
const char *Ext = strrchr(
Value,
'.'))
3047 Ty = types::TY_HLSL;
3049 Ty = types::TY_Object;
3060 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3061 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3062 << getTypeName(OldTy) << getTypeName(Ty);
3067 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3068 Ty == types::TY_Object)
3069 Ty = types::TY_LLVM_BC;
3077 if (Ty != types::TY_Object) {
3078 if (Args.hasArg(options::OPT_ObjC))
3079 Ty = types::TY_ObjC;
3080 else if (Args.hasArg(options::OPT_ObjCXX))
3081 Ty = types::TY_ObjCXX;
3088 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3092 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3093 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3096 const char *Ext = strrchr(
Value,
'.');
3098 Ty = types::TY_Object;
3102 InputTypeArg->claim();
3106 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3107 Args.hasArgNoClaim(options::OPT_hipstdpar))
3111 Inputs.push_back(std::make_pair(Ty, A));
3113 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3114 StringRef
Value = A->getValue();
3117 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3118 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3121 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3122 StringRef
Value = A->getValue();
3125 Arg *InputArg =
MakeInputArg(Args, Opts, A->getValue());
3126 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3132 Inputs.push_back(std::make_pair(types::TY_Object, A));
3134 }
else if (A->getOption().matches(options::OPT_x)) {
3143 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3144 InputType = types::TY_Object;
3151 }
else if (A->getOption().getID() == options::OPT_U) {
3152 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3153 StringRef Val = A->getValue(0);
3154 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3156 Diag(diag::warn_slash_u_filename) << Val;
3157 Diag(diag::note_use_dashdash);
3161 if (
CCCIsCPP() && Inputs.empty()) {
3165 Inputs.push_back(std::make_pair(types::TY_C, A));
3172class OffloadingActionBuilder final {
3174 bool IsValid =
false;
3180 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3183 std::map<Action *, const Arg *> HostActionToInputArgMap;
3186 class DeviceActionBuilder {
3190 enum ActionBuilderReturnCode {
3209 DerivedArgList &Args;
3218 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3221 :
C(
C), Args(Args), Inputs(Inputs),
3222 AssociatedOffloadKind(AssociatedOffloadKind) {}
3223 virtual ~DeviceActionBuilder() {}
3228 virtual ActionBuilderReturnCode
3229 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3232 return ABRT_Inactive;
3237 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3238 return ABRT_Inactive;
3242 virtual void appendTopLevelActions(
ActionList &AL) {}
3245 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3248 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3251 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3258 virtual bool canUseBundlerUnbundler()
const {
return false; }
3262 bool isValid() {
return !ToolChains.empty(); }
3266 return AssociatedOffloadKind;
3272 class CudaActionBuilderBase :
public DeviceActionBuilder {
3276 bool CompileHostOnly =
false;
3277 bool CompileDeviceOnly =
false;
3279 bool EmitAsm =
false;
3289 TargetID(
const char *ID) :
ID(
ID) {}
3290 operator const char *() {
return ID; }
3291 operator StringRef() {
return StringRef(ID); }
3294 SmallVector<TargetID, 4> GpuArchList;
3300 Action *CudaFatBinary =
nullptr;
3303 bool IsActive =
false;
3306 bool Relocatable =
false;
3309 OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
3312 const CUIDOptions &CUIDOpts;
3315 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3318 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3319 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3321 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3322 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3323 options::OPT_fno_gpu_rdc,
false);
3326 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3333 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3336 if (!(IA->getType() == types::TY_CUDA ||
3337 IA->getType() == types::TY_HIP ||
3338 IA->getType() == types::TY_PP_HIP)) {
3341 return ABRT_Inactive;
3348 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3350 if (CompileHostOnly)
3351 return ABRT_Success;
3354 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3355 : types::TY_CUDA_DEVICE;
3356 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3357 CudaDeviceActions.push_back(
3358 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3361 return ABRT_Success;
3365 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3369 if (UA->getType() == types::TY_Object && !Relocatable)
3370 return ABRT_Inactive;
3372 CudaDeviceActions.clear();
3374 std::string
FileName = IA->getInputArg().getAsString(Args);
3380 const StringRef LibFileExt =
".lib";
3381 if (IA->getType() == types::TY_Object &&
3382 (!llvm::sys::path::has_extension(
FileName) ||
3384 llvm::sys::path::extension(
FileName).drop_front()) !=
3386 llvm::sys::path::extension(
FileName) == LibFileExt))
3387 return ABRT_Inactive;
3389 for (
auto Arch : GpuArchList) {
3390 CudaDeviceActions.push_back(UA);
3391 UA->registerDependentActionInfo(ToolChains[0],
Arch,
3392 AssociatedOffloadKind);
3395 return ABRT_Success;
3398 return IsActive ? ABRT_Success : ABRT_Inactive;
3401 void appendTopLevelActions(
ActionList &AL)
override {
3403 auto AddTopLevel = [&](Action *A, TargetID TargetID) {
3404 OffloadAction::DeviceDependences Dep;
3405 Dep.
add(*A, *ToolChains.front(), TargetID, AssociatedOffloadKind);
3406 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3410 if (CudaFatBinary) {
3411 AddTopLevel(CudaFatBinary, OffloadArch::UNUSED);
3412 CudaDeviceActions.clear();
3413 CudaFatBinary =
nullptr;
3417 if (CudaDeviceActions.empty())
3423 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3424 "Expecting one action per GPU architecture.");
3425 assert(ToolChains.size() == 1 &&
3426 "Expecting to have a single CUDA toolchain.");
3427 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3428 AddTopLevel(CudaDeviceActions[I], GpuArchList[I]);
3430 CudaDeviceActions.clear();
3433 virtual std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3451 assert(HostTC &&
"No toolchain for host compilation.");
3456 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3461 std::set<StringRef> GpuArchs;
3463 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3464 ToolChains.push_back(I.second);
3467 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3468 GpuArchs.insert(
Arch);
3472 for (
auto Arch : GpuArchs)
3473 GpuArchList.push_back(
Arch.data());
3475 CompileHostOnly =
C.getDriver().offloadHostOnly();
3476 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3477 EmitAsm = Args.getLastArg(options::OPT_S);
3485 class CudaActionBuilder final :
public CudaActionBuilderBase {
3487 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3489 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3490 DefaultOffloadArch = OffloadArch::CudaDefault;
3493 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3495 const std::set<StringRef> &GpuArchs)
override {
3496 return std::nullopt;
3499 ActionBuilderReturnCode
3500 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3502 PhasesTy &Phases)
override {
3504 return ABRT_Inactive;
3508 if (CudaDeviceActions.empty())
3509 return ABRT_Success;
3511 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3512 "Expecting one action per GPU architecture.");
3513 assert(!CompileHostOnly &&
3514 "Not expecting CUDA actions in host-only compilation.");
3524 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3527 for (
auto Ph : Phases) {
3532 if (Ph > FinalPhase)
3535 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3549 Action *AssembleAction = CudaDeviceActions[I];
3550 assert(AssembleAction->
getType() == types::TY_Object);
3551 assert(AssembleAction->
getInputs().size() == 1);
3557 OffloadAction::DeviceDependences DDep;
3559 DeviceActions.push_back(
3560 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3565 if (!DeviceActions.empty()) {
3567 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3569 if (!CompileDeviceOnly) {
3570 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3574 CudaFatBinary =
nullptr;
3579 CudaDeviceActions.clear();
3583 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3588 return ABRT_Success;
3592 "instructions should only occur "
3593 "before the backend phase!");
3596 for (Action *&A : CudaDeviceActions)
3597 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3599 return ABRT_Success;
3604 class HIPActionBuilder final :
public CudaActionBuilderBase {
3606 SmallVector<ActionList, 8> DeviceLinkerInputs;
3612 std::optional<bool> BundleOutput;
3613 std::optional<bool> EmitReloc;
3616 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3618 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3620 DefaultOffloadArch = OffloadArch::HIPDefault;
3622 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3623 options::OPT_fno_hip_emit_relocatable)) {
3624 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3625 options::OPT_fno_hip_emit_relocatable, false);
3629 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3630 <<
"-fhip-emit-relocatable"
3634 if (!CompileDeviceOnly) {
3635 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3636 <<
"-fhip-emit-relocatable"
3637 <<
"--offload-device-only";
3642 if (Args.hasArg(options::OPT_gpu_bundle_output,
3643 options::OPT_no_gpu_bundle_output))
3644 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3645 options::OPT_no_gpu_bundle_output,
true) &&
3646 (!EmitReloc || !*EmitReloc);
3649 bool canUseBundlerUnbundler()
const override {
return true; }
3651 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
3653 const std::set<StringRef> &GpuArchs)
override {
3657 ActionBuilderReturnCode
3658 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3660 PhasesTy &Phases)
override {
3662 return ABRT_Inactive;
3668 if (CudaDeviceActions.empty())
3669 return ABRT_Success;
3672 CudaDeviceActions.size() == GpuArchList.size()) &&
3673 "Expecting one action per GPU architecture.");
3674 assert(!CompileHostOnly &&
3675 "Not expecting HIP actions in host-only compilation.");
3677 bool ShouldLink = !EmitReloc || !*EmitReloc;
3680 !EmitAsm && ShouldLink) {
3686 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3687 if (
C.getDriver().isUsingOffloadLTO()) {
3691 AL.push_back(CudaDeviceActions[I]);
3694 CudaDeviceActions[I] =
3695 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3701 if (ToolChains.front()->getTriple().isSPIRV() ||
3702 (ToolChains.front()->getTriple().isAMDGCN() &&
3703 GpuArchList[I] == StringRef(
"amdgcnspirv"))) {
3707 types::ID Output = Args.hasArg(options::OPT_S)
3709 : types::TY_LLVM_BC;
3711 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3715 AssociatedOffloadKind);
3716 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3718 AssociatedOffloadKind);
3719 AL.push_back(AssembleAction);
3722 CudaDeviceActions[I] =
3723 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3732 OffloadAction::DeviceDependences DDep;
3733 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3734 AssociatedOffloadKind);
3735 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3736 DDep, CudaDeviceActions[I]->getType());
3739 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3741 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3742 types::TY_HIP_FATBIN);
3744 if (!CompileDeviceOnly) {
3745 DA.
add(*CudaFatBinary, *ToolChains.front(),
nullptr,
3746 AssociatedOffloadKind);
3749 CudaFatBinary =
nullptr;
3754 CudaDeviceActions.clear();
3757 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3760 return ABRT_Success;
3766 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3767 auto LI = DeviceLinkerInputs.begin();
3768 for (
auto *A : CudaDeviceActions) {
3775 CudaDeviceActions.clear();
3776 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3780 for (Action *&A : CudaDeviceActions)
3781 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A,
3782 AssociatedOffloadKind);
3784 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3786 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3787 OffloadAction::DeviceDependences DDep;
3788 DDep.
add(*CudaDeviceActions[I], *ToolChains.front(), GpuArchList[I],
3789 AssociatedOffloadKind);
3790 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3791 DDep, CudaDeviceActions[I]->getType());
3794 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3795 CudaDeviceActions.clear();
3798 return (CompileDeviceOnly &&
3799 (CurPhase == FinalPhase ||
3805 void appendLinkDeviceActions(
ActionList &AL)
override {
3806 if (DeviceLinkerInputs.size() == 0)
3809 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3810 "Linker inputs and GPU arch list sizes do not match.");
3816 for (
auto &LI : DeviceLinkerInputs) {
3818 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3822 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3825 OffloadAction::DeviceDependences DeviceLinkDeps;
3826 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0],
3827 GpuArchList[I], AssociatedOffloadKind);
3828 Actions.push_back(
C.MakeAction<OffloadAction>(
3829 DeviceLinkDeps, DeviceLinkAction->getType()));
3832 DeviceLinkerInputs.clear();
3835 if (Args.hasArg(options::OPT_emit_llvm)) {
3843 OffloadAction::DeviceDependences DDeps;
3844 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3845 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3847 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3848 DDeps.
add(*TopDeviceLinkAction, *ToolChains[0],
nullptr,
3849 AssociatedOffloadKind);
3852 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3858 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3860 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3868 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3874 bool ShouldUseBundler;
3877 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
3885 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
3888 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
3896 unsigned ValidBuilders = 0u;
3897 unsigned ValidBuildersSupportingBundling = 0u;
3898 for (
auto *SB : SpecializedBuilders) {
3899 IsValid = IsValid && !SB->initialize();
3902 if (SB->isValid()) {
3904 if (SB->canUseBundlerUnbundler())
3905 ++ValidBuildersSupportingBundling;
3909 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
3911 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
3912 options::OPT_no_gpu_bundle_output,
true);
3915 ~OffloadingActionBuilder() {
3916 for (
auto *SB : SpecializedBuilders)
3921 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
3922 assert(HostAction &&
"Invalid host action");
3923 assert(InputArg &&
"Invalid input argument");
3924 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
3925 assert(Loc->second == InputArg &&
3926 "host action mapped to multiple input arguments");
3935 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
3937 DeviceActionBuilder::PhasesTy &Phases) {
3941 if (SpecializedBuilders.empty())
3944 assert(HostAction &&
"Invalid host action!");
3945 recordHostAction(HostAction, InputArg);
3950 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
3951 unsigned InactiveBuilders = 0u;
3952 unsigned IgnoringBuilders = 0u;
3953 for (
auto *SB : SpecializedBuilders) {
3954 if (!SB->isValid()) {
3959 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
3964 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
3969 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
3970 OffloadKind |= SB->getAssociatedOffloadKind();
3975 if (IgnoringBuilders &&
3976 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
3993 bool addHostDependenceToDeviceActions(
Action *&HostAction,
3994 const Arg *InputArg) {
3998 recordHostAction(HostAction, InputArg);
4007 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4009 HostAction->
getType() == types::TY_PP_HIP)) {
4010 auto UnbundlingHostAction =
4015 HostAction = UnbundlingHostAction;
4016 recordHostAction(HostAction, InputArg);
4019 assert(HostAction &&
"Invalid host action!");
4022 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4023 for (
auto *SB : SpecializedBuilders) {
4027 auto RetCode = SB->addDeviceDependences(HostAction);
4031 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4032 "Host dependence not expected to be ignored.!");
4036 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4037 OffloadKind |= SB->getAssociatedOffloadKind();
4042 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4052 const Arg *InputArg) {
4054 recordHostAction(HostAction, InputArg);
4058 for (
auto *SB : SpecializedBuilders) {
4061 SB->appendTopLevelActions(OffloadAL);
4068 if (CanUseBundler && ShouldUseBundler && HostAction &&
4069 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4071 OffloadAL.push_back(HostAction);
4075 assert(HostAction == AL.back() &&
"Host action not in the list??");
4077 recordHostAction(HostAction, InputArg);
4078 AL.back() = HostAction;
4080 AL.append(OffloadAL.begin(), OffloadAL.end());
4090 void appendDeviceLinkActions(
ActionList &AL) {
4091 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4094 SB->appendLinkDeviceActions(AL);
4098 Action *makeHostLinkAction() {
4101 appendDeviceLinkActions(DeviceAL);
4102 if (DeviceAL.empty())
4107 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4110 HA = SB->appendLinkHostActions(DeviceAL);
4127 for (
auto *SB : SpecializedBuilders) {
4131 SB->appendLinkDependences(DDeps);
4135 unsigned ActiveOffloadKinds = 0u;
4136 for (
auto &I : InputArgToOffloadKindMap)
4137 ActiveOffloadKinds |= I.second;
4149 for (
auto *A : HostAction->
inputs()) {
4150 auto ArgLoc = HostActionToInputArgMap.find(A);
4151 if (ArgLoc == HostActionToInputArgMap.end())
4153 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4154 if (OFKLoc == InputArgToOffloadKindMap.end())
4166 nullptr, ActiveOffloadKinds);
4172void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4173 const InputList &Inputs,
4177 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4178 StringRef
V = A->getValue();
4179 if (Inputs.size() > 1 && !
V.empty() &&
4180 !llvm::sys::path::is_separator(
V.back())) {
4182 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4183 << A->getSpelling() <<
V;
4184 Args.eraseArg(options::OPT__SLASH_Fo);
4189 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4190 StringRef
V = A->getValue();
4191 if (Inputs.size() > 1 && !
V.empty() &&
4192 !llvm::sys::path::is_separator(
V.back())) {
4194 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4195 << A->getSpelling() <<
V;
4196 Args.eraseArg(options::OPT__SLASH_Fa);
4201 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4202 if (A->getValue()[0] ==
'\0') {
4204 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4205 Args.eraseArg(options::OPT__SLASH_o);
4210 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4211 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4212 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4213 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4214 Args.eraseArg(options::OPT__SLASH_Yc);
4215 Args.eraseArg(options::OPT__SLASH_Yu);
4216 YcArg = YuArg =
nullptr;
4218 if (YcArg && Inputs.size() > 1) {
4219 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4220 Args.eraseArg(options::OPT__SLASH_Yc);
4228 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4229 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4230 Args.AddFlagArg(
nullptr,
4231 getOpts().getOption(options::OPT_frtlib_add_rpath));
4234 if (Args.hasArg(options::OPT_emit_llvm) && !Args.hasArg(options::OPT_hip_link))
4235 Diag(clang::diag::err_drv_emit_llvm_link);
4236 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4238 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4239 .starts_with_insensitive(
"lld"))
4240 Diag(clang::diag::err_drv_lto_without_lld);
4246 if (!Args.hasArg(options::OPT_dumpdir)) {
4247 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4248 Arg *Arg = Args.MakeSeparateArg(
4249 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4251 (FinalOutput ? FinalOutput->getValue()
4263 Args.eraseArg(options::OPT__SLASH_Fp);
4264 Args.eraseArg(options::OPT__SLASH_Yc);
4265 Args.eraseArg(options::OPT__SLASH_Yu);
4266 YcArg = YuArg =
nullptr;
4269 if (Args.hasArg(options::OPT_include_pch) &&
4270 Args.hasArg(options::OPT_ignore_pch)) {
4274 Args.eraseArg(options::OPT_include_pch);
4277 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4278 for (
auto &I : Inputs) {
4280 const Arg *InputArg = I.second;
4285 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4289 if (InitialPhase > FinalPhase) {
4290 if (InputArg->isClaimed())
4297 if (Args.hasArg(options::OPT_Qunused_arguments))
4303 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4304 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4308 (Args.getLastArg(options::OPT__SLASH_EP,
4309 options::OPT__SLASH_P) ||
4310 Args.getLastArg(options::OPT_E) ||
4311 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4313 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4314 << InputArg->getAsString(Args) << !!FinalPhaseArg
4315 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4317 Diag(clang::diag::warn_drv_input_file_unused)
4318 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4320 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4329 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4333 Actions.push_back(ClangClPch);
4345 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4346 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4352 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4354 if (!SuppressMissingInputWarning && Inputs.empty()) {
4355 Diag(clang::diag::err_drv_no_input_files);
4359 handleArguments(
C, Args, Inputs, Actions);
4361 bool UseNewOffloadingDriver =
4364 Args.hasFlag(options::OPT_foffload_via_llvm,
4365 options::OPT_fno_offload_via_llvm,
false) ||
4366 Args.hasFlag(options::OPT_offload_new_driver,
4367 options::OPT_no_offload_new_driver,
4371 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4372 !UseNewOffloadingDriver
4373 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4381 for (
auto &I : Inputs) {
4383 const Arg *InputArg = I.second;
4396 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4402 if (!UseNewOffloadingDriver)
4403 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4409 if (!UseNewOffloadingDriver)
4410 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4411 Current, InputArg, Phase, PL.back(), FullPL);
4417 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4420 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4421 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4423 LinkerInputs.push_back(Current);
4433 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4434 MergerInputs.push_back(Current);
4452 if (NewCurrent == Current)
4455 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4458 Current = NewCurrent;
4462 if (UseNewOffloadingDriver)
4466 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4470 if (Current->
getType() == types::TY_Nothing)
4476 Actions.push_back(Current);
4479 if (!UseNewOffloadingDriver)
4480 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4488 if (LinkerInputs.empty()) {
4491 if (!UseNewOffloadingDriver)
4492 OffloadBuilder->appendDeviceLinkActions(Actions);
4495 if (!LinkerInputs.empty()) {
4496 if (!UseNewOffloadingDriver)
4497 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4498 LinkerInputs.push_back(Wrapper);
4503 }
else if (UseNewOffloadingDriver ||
4504 Args.hasArg(options::OPT_offload_link)) {
4511 if (!UseNewOffloadingDriver)
4512 LA = OffloadBuilder->processHostLinkAction(LA);
4513 Actions.push_back(LA);
4517 if (!MergerInputs.empty())
4521 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4528 for (
auto &I : Inputs) {
4530 const Arg *InputArg = I.second;
4535 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4536 InputType == types::TY_Asm)
4541 for (
auto Phase : PhaseList) {
4545 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4550 if (InputType == types::TY_Object)
4557 assert(Phase == PhaseList.back() &&
4558 "merging must be final compilation step.");
4559 MergerInputs.push_back(Current);
4568 Actions.push_back(Current);
4572 if (!MergerInputs.empty())
4577 for (
auto Opt : {options::OPT_print_supported_cpus,
4578 options::OPT_print_supported_extensions,
4579 options::OPT_print_enabled_extensions}) {
4586 if (Arg *A = Args.getLastArg(Opt)) {
4587 if (Opt == options::OPT_print_supported_extensions &&
4588 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4589 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4590 !
C.getDefaultToolChain().getTriple().isARM()) {
4591 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4592 <<
"--print-supported-extensions";
4595 if (Opt == options::OPT_print_enabled_extensions &&
4596 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4597 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4598 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4599 <<
"--print-enabled-extensions";
4606 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4609 for (
auto &I : Inputs)
4614 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
4620 if (TC.requiresObjcopy(Args)) {
4621 Action *LastAction = Actions.back();
4623 if (LastAction->
getType() == types::TY_Object)
4629 if (TC.requiresValidation(Args)) {
4630 Action *LastAction = Actions.back();
4632 LastAction, types::TY_DX_CONTAINER));
4636 if (TC.requiresBinaryTranslation(Args)) {
4637 Action *LastAction = Actions.back();
4641 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4642 LastAction->
getType() == types::TY_Object)
4644 LastAction, types::TY_DX_CONTAINER));
4649 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4655 const llvm::opt::DerivedArgList &Args,
4657 const llvm::Triple &Triple) {
4662 if (Triple.isNVPTX() &&
4664 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4665 <<
"CUDA" << ArchStr;
4667 }
else if (Triple.isAMDGPU() &&
4669 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4670 <<
"HIP" << ArchStr;
4678 llvm::StringMap<bool> Features;
4681 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4693static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4695 llvm::Triple Triple) {
4696 if (!Triple.isAMDGPU())
4697 return std::nullopt;
4699 std::set<StringRef> ArchSet;
4700 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4704llvm::SmallVector<StringRef>
4708 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4709 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4710 options::OPT_no_offload_arch_EQ)) {
4711 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4713 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4715 :
"--no-offload-arch");
4718 llvm::DenseSet<StringRef> Archs;
4719 for (
auto *Arg :
C.getArgsForToolChain(&TC,
"", Kind)) {
4722 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4723 for (StringRef
Arch : Arg->getValues()) {
4724 if (
Arch ==
"native" ||
Arch.empty()) {
4728 << llvm::Triple::getArchTypeName(TC.
getArch())
4729 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4733 for (
auto ArchStr : *GPUsOrErr) {
4735 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4736 if (!CanonicalStr.empty())
4737 Archs.insert(CanonicalStr);
4742 StringRef CanonicalStr =
4744 if (!CanonicalStr.empty())
4745 Archs.insert(CanonicalStr);
4750 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4751 for (StringRef
Arch : Arg->getValues()) {
4752 if (
Arch ==
"all") {
4757 Archs.erase(ArchStr);
4763 if (
auto ConflictingArchs =
4765 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4766 << ConflictingArchs->first << ConflictingArchs->second;
4769 if (Archs.empty()) {
4777 Archs.insert(StringRef());
4780 if (
auto *Arg =
C.getArgsForToolChain(&TC,
"", Kind)
4781 .getLastArg(options::OPT_march_EQ)) {
4782 Archs.insert(Arg->getValue());
4787 << llvm::Triple::getArchTypeName(TC.
getArch())
4788 << llvm::toString(ArchsOrErr.takeError()) <<
"--offload-arch";
4789 }
else if (!ArchsOrErr->empty()) {
4790 for (
auto Arch : *ArchsOrErr)
4791 Archs.insert(Args.MakeArgStringRef(
Arch));
4793 Archs.insert(StringRef());
4798 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4799 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4807 llvm::opt::DerivedArgList &Args,
4808 const InputTy &Input, StringRef CUID,
4809 Action *HostAction)
const {
4817 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
4819 bool HIPRelocatableObj =
4821 Args.hasFlag(options::OPT_fhip_emit_relocatable,
4822 options::OPT_fno_hip_emit_relocatable,
false);
4824 if (!HIPNoRDC && HIPRelocatableObj)
4825 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4826 <<
"-fhip-emit-relocatable"
4830 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
4831 <<
"-fhip-emit-relocatable"
4832 <<
"--offload-device-only";
4850 auto TCRange =
C.getOffloadToolChains(Kind);
4851 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
4852 ToolChains.push_back(TI->second);
4854 if (ToolChains.empty())
4858 const Arg *InputArg = Input.second;
4867 for (
const ToolChain *TC : ToolChains) {
4869 TCAndArchs.push_back(std::make_pair(TC,
Arch));
4870 DeviceActions.push_back(
4871 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
4875 if (DeviceActions.empty())
4881 HostAction->
getType() != types::TY_Nothing &&
4891 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4900 auto *TCAndArch = TCAndArchs.begin();
4901 for (
Action *&A : DeviceActions) {
4902 if (A->
getType() == types::TY_Nothing)
4912 HostAction->
getType() != types::TY_Nothing) {
4919 TCAndArch->second.data(), Kind);
4921 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4931 for (
Action *&A : DeviceActions) {
4934 llvm::Triple::OSType::AMDHSA &&
4936 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
4937 options::OPT_no_use_spirv_backend,
4944 bool IsAMDGCNSPIRVWithBackend = IsAMDGCNSPIRV && UseSPIRVBackend;
4946 if ((A->
getType() != types::TY_Object && !IsAMDGCNSPIRV &&
4947 A->
getType() != types::TY_LTO_BC) ||
4955 auto *TCAndArch = TCAndArchs.begin();
4956 for (
Action *A : DeviceActions) {
4957 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4959 DDep.
add(*A, *TCAndArch->first, TCAndArch->second.data(), Kind);
4964 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
4966 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second.data(), Kind);
4975 bool ShouldBundleHIP =
4976 Args.hasFlag(options::OPT_gpu_bundle_output,
4977 options::OPT_no_gpu_bundle_output,
false) ||
4979 llvm::none_of(OffloadActions, [](
Action *A) {
4980 return A->
getType() != types::TY_Image;
4987 if (OffloadActions.empty())
4992 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
4996 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5003 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5004 DDep.
add(*FatbinAction,
5007 }
else if (HIPNoRDC) {
5019 DDep.
add(*PackagerAction,
5028 nullptr,
C.getActiveOffloadKinds());
5037 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5038 return A->
getType() == types::TY_Nothing;
5042 nullptr, SingleDeviceOutput ? DDep : DDeps);
5043 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5049 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5059 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5065 llvm_unreachable(
"link action invalid here.");
5067 llvm_unreachable(
"ifsmerge action invalid here.");
5072 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5073 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5074 OutputTy = types::TY_Dependencies;
5079 if (!Args.hasFlag(options::OPT_frewrite_includes,
5080 options::OPT_fno_rewrite_includes,
false) &&
5081 !Args.hasFlag(options::OPT_frewrite_imports,
5082 options::OPT_fno_rewrite_imports,
false) &&
5083 !Args.hasFlag(options::OPT_fdirectives_only,
5084 options::OPT_fno_directives_only,
false) &&
5088 "Cannot preprocess this input type!");
5094 if (Args.hasArg(options::OPT_extract_api))
5101 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5102 (Input->
getType() == driver::types::TY_CXXModule ||
5103 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5104 !Args.getLastArg(options::OPT__precompile))
5109 "Cannot precompile this input type!");
5113 const char *ModName =
nullptr;
5114 if (OutputTy == types::TY_PCH) {
5115 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5116 ModName = A->getValue();
5118 OutputTy = types::TY_ModuleFile;
5121 if (Args.hasArg(options::OPT_fsyntax_only)) {
5123 OutputTy = types::TY_Nothing;
5129 if (Args.hasArg(options::OPT_fsyntax_only))
5131 if (Args.hasArg(options::OPT_rewrite_objc))
5133 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5135 types::TY_RewrittenLegacyObjC);
5136 if (Args.hasArg(options::OPT__analyze))
5138 if (Args.hasArg(options::OPT_emit_ast))
5140 if (Args.hasArg(options::OPT_emit_cir))
5142 if (Args.hasArg(options::OPT_module_file_info))
5144 if (Args.hasArg(options::OPT_verify_pch))
5146 if (Args.hasArg(options::OPT_extract_api))
5154 Args.hasFlag(options::OPT_offload_new_driver,
5155 options::OPT_no_offload_new_driver,
false) &&
5161 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5162 !Args.hasArg(options::OPT_emit_llvm))
5163 Output = types::TY_PP_Asm;
5164 else if (Args.hasArg(options::OPT_S))
5165 Output = types::TY_LTO_IR;
5167 Output = types::TY_LTO_BC;
5172 Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
5175 bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
5176 options::OPT_no_use_spirv_backend,
5184 bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
5186 OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
5188 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5190 if (Args.hasArg(options::OPT_emit_llvm) ||
5196 !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
5197 ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5199 (Args.hasFlag(options::OPT_offload_new_driver,
5200 options::OPT_no_offload_new_driver,
false) &&
5207 Args.hasArg(options::OPT_S) &&
5211 !Args.hasFlag(options::OPT_offload_new_driver,
5212 options::OPT_no_offload_new_driver,
5215 : types::TY_LLVM_BC;
5228 if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
5237 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5241 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5243 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5263 unsigned NumOutputs = 0;
5264 unsigned NumIfsOutputs = 0;
5265 for (
const Action *A :
C.getActions()) {
5268 if (A->
getType() == types::TY_DX_CONTAINER &&
5273 if (A->
getType() != types::TY_Nothing &&
5275 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5277 0 == NumIfsOutputs++) ||
5282 A->
getType() == types::TY_Nothing &&
5283 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5284 NumOutputs += A->
size();
5287 if (NumOutputs > 1) {
5288 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5289 FinalOutput =
nullptr;
5293 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5297 if (RawTriple.isOSBinFormatMachO())
5298 for (
const Arg *A :
C.getArgs())
5299 if (A->getOption().matches(options::OPT_arch))
5303 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5304 for (
Action *A :
C.getActions()) {
5311 const char *LinkingOutput =
nullptr;
5314 LinkingOutput = FinalOutput->getValue();
5323 LinkingOutput, CachedResults,
5330 for (
auto &J :
C.getJobs())
5331 J.InProcess =
false;
5334 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5335 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5340 const char *LinkingOutput =
nullptr;
5342 LinkingOutput = FinalOutput->getValue();
5349 using namespace llvm;
5352 <<
"output=" << LinkingOutput;
5353 outs() <<
", total="
5354 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5356 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5357 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5361 llvm::raw_string_ostream Out(Buffer);
5362 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5365 llvm::sys::printArg(Out, LinkingOutput,
true);
5366 Out <<
',' << ProcStat->TotalTime.count() <<
','
5367 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5372 llvm::sys::fs::OF_Append |
5373 llvm::sys::fs::OF_Text);
5378 llvm::errs() <<
"ERROR: Cannot lock file "
5380 <<
toString(L.takeError()) <<
"\n";
5391 bool ReportUnusedArguments =
5392 !Diags.hasErrorOccurred() &&
5393 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5396 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5398 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5401 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5402 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5404 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5408 return strstr(J.getCreator().getShortName(),
"assembler");
5410 for (Arg *A :
C.getArgs()) {
5414 if (!A->isClaimed()) {
5420 const Option &Opt = A->getOption();
5421 if (Opt.getKind() == Option::FlagClass) {
5422 bool DuplicateClaimed =
false;
5424 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5425 if (AA->isClaimed()) {
5426 DuplicateClaimed =
true;
5431 if (DuplicateClaimed)
5437 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5439 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5444 !
C.getActions().empty()) {
5445 Diag(diag::err_drv_unsupported_opt_for_target)
5447 }
else if (ReportUnusedArguments) {
5448 Diag(clang::diag::warn_drv_unused_argument)
5449 << A->getAsString(
C.getArgs());
5459class ToolSelector final {
5470 bool IsHostSelector;
5481 bool CanBeCollapsed =
true) {
5483 if (Inputs.size() != 1)
5486 Action *CurAction = *Inputs.begin();
5487 if (CanBeCollapsed &&
5493 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5497 if (!IsHostSelector) {
5498 if (OA->hasSingleDeviceDependence(
true)) {
5500 OA->getSingleDeviceDependence(
true);
5501 if (CanBeCollapsed &&
5504 SavedOffloadAction.push_back(OA);
5505 return dyn_cast<JobAction>(CurAction);
5507 }
else if (OA->hasHostDependence()) {
5508 CurAction = OA->getHostDependence();
5509 if (CanBeCollapsed &&
5512 SavedOffloadAction.push_back(OA);
5513 return dyn_cast<JobAction>(CurAction);
5518 return dyn_cast<JobAction>(CurAction);
5522 bool canCollapseAssembleAction()
const {
5523 return TC.useIntegratedAs() && !SaveTemps &&
5524 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5525 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5526 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5527 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5531 bool canCollapsePreprocessorAction()
const {
5532 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5533 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5534 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5539 struct JobActionInfo final {
5541 const JobAction *JA =
nullptr;
5549 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5550 ArrayRef<JobActionInfo> &ActionInfo,
5551 unsigned ElementNum) {
5552 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5553 for (
unsigned I = 0; I < ElementNum; ++I)
5554 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5555 ActionInfo[I].SavedOffloadAction.end());
5568 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5571 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5573 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5574 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5575 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5576 if (!AJ || !BJ || !CJ)
5580 const Tool *
T = TC.SelectTool(*CJ);
5587 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5593 const Tool *BT = TC.SelectTool(*BJ);
5598 if (!
T->hasIntegratedAssembler())
5601 Inputs = CJ->getInputs();
5602 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5606 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5609 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5611 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5612 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5617 const Tool *
T = TC.SelectTool(*BJ);
5621 if (!
T->hasIntegratedAssembler())
5624 Inputs = BJ->getInputs();
5625 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5629 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5632 if (ActionInfo.size() < 2)
5634 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5635 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5639 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5640 for (
auto &Input : AI.JA->getInputs())
5651 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5652 if (SaveTemps && !InputIsBitcode)
5656 const Tool *
T = TC.SelectTool(*CJ);
5663 if (!
T->hasIntegratedBackend() && !(OutputIsLLVM &&
T->canEmitIR()))
5669 Inputs = CJ->getInputs();
5670 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5679 void combineWithPreprocessor(
const Tool *
T,
ActionList &Inputs,
5681 if (!
T || !canCollapsePreprocessorAction() || !
T->hasIntegratedCPP())
5687 for (Action *A : Inputs) {
5688 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5690 NewInputs.push_back(A);
5696 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5697 PreprocessJobOffloadActions.end());
5698 NewInputs.append(PJ->input_begin(), PJ->input_end());
5704 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5706 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5708 assert(BaseAction &&
"Invalid base action.");
5724 SmallVector<JobActionInfo, 5> ActionChain(1);
5725 ActionChain.back().JA = BaseAction;
5726 while (ActionChain.back().JA) {
5727 const Action *CurAction = ActionChain.back().JA;
5730 ActionChain.resize(ActionChain.size() + 1);
5731 JobActionInfo &AI = ActionChain.back();
5735 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5739 ActionChain.pop_back();
5747 const Tool *
T = combineAssembleBackendCompile(ActionChain, Inputs,
5748 CollapsedOffloadAction);
5750 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5752 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5758 combineWithPreprocessor(
T, Inputs, CollapsedOffloadAction);
5770 StringRef BoundArch,
5772 std::string TriplePlusArch = TC->
getTriple().normalize();
5773 if (!BoundArch.empty()) {
5774 TriplePlusArch +=
"-";
5775 TriplePlusArch += BoundArch;
5777 TriplePlusArch +=
"-";
5779 return TriplePlusArch;
5784 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5785 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5788 std::pair<const Action *, std::string> ActionTC = {
5790 auto CachedResult = CachedResults.find(ActionTC);
5791 if (CachedResult != CachedResults.end()) {
5792 return CachedResult->second;
5795 C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
5796 CachedResults, TargetDeviceOffloadKind);
5797 CachedResults[ActionTC] =
Result;
5802 const JobAction *JA,
const char *BaseInput,
5805 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
5809 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
5810 Path = A->getValue();
5811 if (llvm::sys::fs::is_directory(Path)) {
5813 llvm::sys::path::replace_extension(Tmp,
"json");
5814 llvm::sys::path::append(Path, llvm::sys::path::filename(Tmp));
5817 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
5820 Path = DumpDir->getValue();
5821 Path += llvm::sys::path::filename(BaseInput);
5823 Path = Result.getFilename();
5825 llvm::sys::path::replace_extension(Path,
"json");
5827 const char *ResultFile =
C.getArgs().MakeArgString(Path);
5828 C.addTimeTraceFile(ResultFile, JA);
5829 C.addResultFile(ResultFile, JA);
5834 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
5835 std::map<std::pair<const Action *, std::string>,
InputInfoList>
5838 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5841 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
5842 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
5874 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
5876 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
5877 const char *DepBoundArch) {
5880 LinkingOutput, CachedResults,
5890 OA->doOnEachDependence(
5891 BuildingForOffloadDevice,
5892 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
5894 C, DepA, DepTC, DepBoundArch,
false,
5895 !!DepBoundArch, LinkingOutput, CachedResults,
5899 A = BuildingForOffloadDevice
5900 ? OA->getSingleDeviceDependence(
true)
5901 : OA->getHostDependence();
5905 std::pair<const Action *, std::string> ActionTC = {
5906 OA->getHostDependence(),
5908 auto It = CachedResults.find(ActionTC);
5909 if (It != CachedResults.end()) {
5911 Inputs.append(OffloadDependencesInputInfo);
5916 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
5919 const Arg &Input = IA->getInputArg();
5921 if (Input.getOption().matches(options::OPT_INPUT)) {
5922 const char *
Name = Input.getValue();
5925 return {InputInfo(A, &Input,
"")};
5928 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
5929 const ToolChain *TC;
5932 if (!ArchName.empty())
5933 TC = &getToolChain(
C.getArgs(),
5935 C.getArgs(), ArchName));
5937 TC = &
C.getDefaultToolChain();
5940 MultipleArchs, LinkingOutput, CachedResults,
5941 TargetDeviceOffloadKind);
5952 const Tool *
T = TS.getTool(Inputs, CollapsedOffloadActions);
5955 return {InputInfo()};
5959 for (
const auto *OA : CollapsedOffloadActions)
5961 BuildingForOffloadDevice,
5962 [&](Action *DepA,
const ToolChain *DepTC,
const char *DepBoundArch) {
5964 C, DepA, DepTC, DepBoundArch,
false,
5965 !!DepBoundArch, LinkingOutput, CachedResults,
5971 for (
const Action *Input : Inputs) {
5975 bool SubJobAtTopLevel =
5978 C, Input, TC, BoundArch, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
5983 const char *BaseInput = InputInfos[0].getBaseInput();
5984 for (
auto &Info : InputInfos) {
5985 if (Info.isFilename()) {
5986 BaseInput = Info.getBaseInput();
5993 if (JA->
getType() == types::TY_dSYM)
5994 BaseInput = InputInfos[0].getFilename();
5997 if (!OffloadDependencesInputInfo.empty())
5998 InputInfos.append(OffloadDependencesInputInfo.begin(),
5999 OffloadDependencesInputInfo.end());
6002 llvm::Triple EffectiveTriple;
6003 const ToolChain &ToolTC =
T->getToolChain();
6004 const ArgList &Args =
6006 if (InputInfos.size() != 1) {
6010 EffectiveTriple = llvm::Triple(
6013 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6018 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6022 for (
auto &UI : UA->getDependentActionsInfo()) {
6024 "Unbundling with no offloading??");
6031 UI.DependentOffloadKind,
6032 UI.DependentToolChain->getTriple().normalize(),
6034 auto CurI = InputInfo(
6043 UnbundlingResults.push_back(CurI);
6052 Arch = UI.DependentBoundArch;
6057 UI.DependentOffloadKind)}] = {
6063 std::pair<const Action *, std::string> ActionTC = {
6065 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6066 "Result does not exist??");
6067 Result = CachedResults[ActionTC].front();
6068 }
else if (JA->
getType() == types::TY_Nothing)
6069 Result = {InputInfo(A, BaseInput)};
6079 AtTopLevel, MultipleArchs,
6082 if (
T->canEmitIR() && OffloadingPrefix.empty())
6087 llvm::errs() <<
"# \"" <<
T->getToolChain().getTripleString() <<
'"'
6088 <<
" - \"" <<
T->getName() <<
"\", inputs: [";
6089 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6090 llvm::errs() << InputInfos[i].getAsString();
6092 llvm::errs() <<
", ";
6094 if (UnbundlingResults.empty())
6095 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6097 llvm::errs() <<
"], outputs: [";
6098 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6099 llvm::errs() << UnbundlingResults[i].getAsString();
6101 llvm::errs() <<
", ";
6103 llvm::errs() <<
"] \n";
6106 if (UnbundlingResults.empty())
6107 T->ConstructJob(
C, *JA,
Result, InputInfos, Args, LinkingOutput);
6109 T->ConstructJobMultipleOutputs(
C, *JA, UnbundlingResults, InputInfos,
6110 Args, LinkingOutput);
6116 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6117 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6129 if (ArgValue.empty()) {
6131 Filename = BaseName;
6132 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6134 llvm::sys::path::append(Filename, BaseName);
6137 if (!llvm::sys::path::has_extension(ArgValue)) {
6142 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6147 llvm::sys::path::replace_extension(Filename, Extension);
6150 return Args.MakeArgString(Filename.c_str());
6165 StringRef Suffix,
bool MultipleArchs,
6166 StringRef BoundArch,
6167 bool NeedUniqueDirectory)
const {
6169 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6170 std::optional<std::string> CrashDirectory =
6172 ? std::string(A->getValue())
6173 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6174 if (CrashDirectory) {
6175 if (!
getVFS().exists(*CrashDirectory))
6176 llvm::sys::fs::create_directories(*CrashDirectory);
6178 llvm::sys::path::append(Path, Prefix);
6179 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6180 if (std::error_code EC =
6181 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6182 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6186 if (MultipleArchs && !BoundArch.empty()) {
6187 if (NeedUniqueDirectory) {
6189 llvm::sys::path::append(TmpName,
6190 Twine(Prefix) +
"-" + BoundArch +
"." + Suffix);
6200 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6215 const char *BaseInput) {
6217 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6218 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6223 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6227 const char *BaseInput,
6228 StringRef OrigBoundArch,
bool AtTopLevel,
6230 StringRef OffloadingPrefix)
const {
6233 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6236 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6237 return C.addResultFile(FinalOutput->getValue(), &JA);
6241 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6243 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6245 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6246 NameArg = A->getValue();
6247 return C.addResultFile(
6257 if (JA.
getType() == types::TY_ModuleFile &&
6258 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6262 if (JA.
getType() == types::TY_PP_Asm &&
6263 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6264 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6267 return C.addResultFile(
C.getArgs().MakeArgString(FcValue.str()), &JA);
6270 if ((JA.
getType() == types::TY_Object &&
6271 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6272 JA.
getType() == types::TY_DX_CONTAINER) {
6273 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6277 if (
C.getDefaultToolChain().getTriple().isDXIL()) {
6279 C.getDefaultToolChain());
6282 if (TC.isLastJob(
C.getArgs(), JA.
getKind()) && !FoValue.empty())
6283 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6284 StringRef
Name = llvm::sys::path::filename(BaseInput);
6285 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6291 assert(
C.getDefaultToolChain().getTriple().isSPIRV());
6292 return C.addResultFile(
C.getArgs().MakeArgString(FoValue.str()), &JA);
6296 if (JA.
getType() == types::TY_PP_Asm &&
6297 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6298 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6300 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6301 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6302 return C.addResultFile(
6307 if (JA.
getType() == types::TY_API_INFO &&
6308 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6309 C.getArgs().hasArg(options::OPT_o))
6310 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6311 <<
C.getArgs().getLastArgValue(options::OPT_o);
6318 bool SpecifiedModuleOutput =
6319 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6320 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6321 if (MultipleArchs && SpecifiedModuleOutput)
6322 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6327 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6328 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6334 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6336 StringRef
Name = llvm::sys::path::filename(BaseInput);
6337 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6338 const char *Suffix =
6343 llvm::Triple Triple(
C.getDriver().getTargetTriple());
6344 bool NeedUniqueDirectory =
6347 Triple.isOSDarwin();
6348 return CreateTempFile(
C, Split.first, Suffix, MultipleArchs, BoundArch,
6349 NeedUniqueDirectory);
6358 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6363 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6364 llvm::sys::path::filename(BasePath));
6365 BaseName = ExternalPath;
6367 BaseName = BasePath;
6369 BaseName = llvm::sys::path::filename(BasePath);
6372 const char *NamedOutput;
6374 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC) &&
6375 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6379 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6383 }
else if (JA.
getType() == types::TY_Image &&
6384 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6385 options::OPT__SLASH_o)) {
6389 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6393 }
else if (JA.
getType() == types::TY_Image) {
6403 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6404 options::OPT_fno_gpu_rdc,
false);
6406 if (UseOutExtension) {
6408 llvm::sys::path::replace_extension(Output,
"");
6410 Output += OffloadingPrefix;
6411 if (MultipleArchs && !BoundArch.empty()) {
6413 Output.append(BoundArch);
6415 if (UseOutExtension)
6417 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6420 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6421 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6422 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6425 .getLastArg(options::OPT__SLASH_o)
6430 const char *Suffix =
6432 assert(Suffix &&
"All types used for output should have a suffix.");
6434 std::string::size_type End = std::string::npos;
6436 End = BaseName.rfind(
'.');
6438 Suffixed += OffloadingPrefix;
6439 if (MultipleArchs && !BoundArch.empty()) {
6441 Suffixed.append(BoundArch);
6446 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6447 const llvm::opt::DerivedArgList &Args) {
6454 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6462 bool IsLinkerWrapper =
6464 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6465 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6466 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6468 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6472 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6476 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6477 JA.
getType() != types::TY_PCH) {
6478 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6480 llvm::sys::path::remove_filename(TempPath);
6481 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6482 llvm::sys::path::append(TempPath, OutputFileName);
6483 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6489 bool SameFile =
false;
6491 llvm::sys::fs::current_path(
Result);
6492 llvm::sys::path::append(
Result, BaseName);
6493 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6496 StringRef
Name = llvm::sys::path::filename(BaseInput);
6497 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6501 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6507 llvm::sys::path::remove_filename(BasePath);
6508 if (BasePath.empty())
6509 BasePath = NamedOutput;
6511 llvm::sys::path::append(BasePath, NamedOutput);
6512 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6515 return C.addResultFile(NamedOutput, &JA);
6521 -> std::optional<std::string> {
6524 for (
const auto &
Dir : P) {
6528 llvm::sys::path::append(P,
Name);
6529 if (llvm::sys::fs::exists(Twine(P)))
6530 return std::string(P);
6532 return std::nullopt;
6539 llvm::sys::path::append(R,
Name);
6540 if (llvm::sys::fs::exists(Twine(R)))
6541 return std::string(R);
6544 llvm::sys::path::append(P,
Name);
6545 if (llvm::sys::fs::exists(Twine(P)))
6546 return std::string(P);
6549 llvm::sys::path::append(D,
"..",
Name);
6550 if (llvm::sys::fs::exists(Twine(D)))
6551 return std::string(D);
6560 llvm::sys::path::append(R2,
"..",
"..",
Name);
6561 if (llvm::sys::fs::exists(Twine(R2)))
6562 return std::string(R2);
6564 return std::string(
Name);
6567void Driver::generatePrefixedToolNames(
6571 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6572 Names.emplace_back(
Tool);
6576 llvm::sys::path::append(Dir, Name);
6577 if (llvm::sys::fs::can_execute(Twine(Dir)))
6579 llvm::sys::path::remove_filename(Dir);
6585 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6590 if (llvm::sys::fs::is_directory(PrefixDir)) {
6593 return std::string(P);
6596 if (llvm::sys::fs::can_execute(Twine(P)))
6597 return std::string(P);
6602 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6610 for (
const auto &Path : List) {
6613 return std::string(P);
6617 if (llvm::ErrorOr<std::string> P =
6618 llvm::sys::findProgramByName(TargetSpecificExecutable))
6622 return std::string(
Name);
6627 std::string error =
"<NOT PRESENT>";
6629 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6634 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6651 llvm::sys::path::remove_filename(path);
6652 llvm::sys::path::append(path,
"libc++.modules.json");
6653 if (TC.
getVFS().exists(path))
6654 return static_cast<std::string
>(path);
6659 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6662 return evaluate(
"libc++.a").value_or(error);
6666 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6670 llvm::sys::path::remove_filename(path);
6671 llvm::sys::path::append(path,
"libstdc++.modules.json");
6672 if (TC.
getVFS().exists(path))
6673 return static_cast<std::string
>(path);
6678 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6681 return evaluate(
"libstdc++.a").value_or(error);
6690 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6692 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6696 return std::string(Path);
6701 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
6703 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6707 return std::string(Path);
6712 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
6716 Output = FpArg->getValue();
6720 if (!llvm::sys::path::has_extension(Output))
6723 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
6724 Output = YcArg->getValue();
6727 llvm::sys::path::replace_extension(Output,
".pch");
6729 return std::string(Output);
6732const ToolChain &Driver::getOffloadToolChain(
6734 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
6735 std::unique_ptr<ToolChain> &TC =
6736 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
6737 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
6739 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
6742 switch (
Target.getOS()) {
6743 case llvm::Triple::CUDA:
6744 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6747 case llvm::Triple::AMDHSA:
6749 TC = std::make_unique<toolchains::HIPAMDToolChain>(*
this,
Target,
6752 TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*
this,
Target,
6761 switch (
Target.getArch()) {
6762 case llvm::Triple::spir:
6763 case llvm::Triple::spir64:
6764 case llvm::Triple::spirv:
6765 case llvm::Triple::spirv32:
6766 case llvm::Triple::spirv64:
6769 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
6773 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
6777 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
6781 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
6795 return getToolChain(Args,
Target);
6799const ToolChain &Driver::getToolChain(
const ArgList &Args,
6800 const llvm::Triple &
Target)
const {
6802 auto &TC = ToolChains[
Target.str()];
6804 switch (
Target.getOS()) {
6805 case llvm::Triple::AIX:
6806 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
6808 case llvm::Triple::Haiku:
6809 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
6811 case llvm::Triple::Darwin:
6812 case llvm::Triple::MacOSX:
6813 case llvm::Triple::IOS:
6814 case llvm::Triple::TvOS:
6815 case llvm::Triple::WatchOS:
6816 case llvm::Triple::XROS:
6817 case llvm::Triple::DriverKit:
6818 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
6820 case llvm::Triple::DragonFly:
6821 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
6823 case llvm::Triple::OpenBSD:
6824 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
6826 case llvm::Triple::NetBSD:
6827 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
6829 case llvm::Triple::FreeBSD:
6831 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
6834 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
6836 case llvm::Triple::Linux:
6837 case llvm::Triple::ELFIAMCU:
6838 if (
Target.getArch() == llvm::Triple::hexagon)
6839 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6841 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
6842 !
Target.hasEnvironment())
6843 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
6846 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
6848 else if (
Target.getArch() == llvm::Triple::ve)
6849 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6850 else if (
Target.isOHOSFamily())
6851 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6852 else if (
Target.isWALI())
6853 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6855 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
6857 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
6859 case llvm::Triple::Fuchsia:
6860 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
6862 case llvm::Triple::Managarm:
6863 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
6865 case llvm::Triple::Solaris:
6866 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
6868 case llvm::Triple::CUDA:
6869 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
6871 case llvm::Triple::AMDHSA: {
6872 if (
Target.getArch() == llvm::Triple::spirv64) {
6873 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
6878 TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*
this,
Target,
6880 : std::make_unique<toolchains::AMDGPUToolChain>(*this,
Target,
6885 case llvm::Triple::AMDPAL:
6886 case llvm::Triple::Mesa3D:
6887 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
6889 case llvm::Triple::UEFI:
6890 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
6892 case llvm::Triple::Win32:
6893 switch (
Target.getEnvironment()) {
6895 if (
Target.isOSBinFormatELF())
6896 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6897 else if (
Target.isOSBinFormatMachO())
6898 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6900 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
6902 case llvm::Triple::GNU:
6903 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
6905 case llvm::Triple::Cygnus:
6906 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
6908 case llvm::Triple::Itanium:
6909 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
6912 case llvm::Triple::MSVC:
6913 case llvm::Triple::UnknownEnvironment:
6914 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
6915 .starts_with_insensitive(
"bfd"))
6916 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
6920 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
6924 case llvm::Triple::PS4:
6925 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
6927 case llvm::Triple::PS5:
6928 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
6930 case llvm::Triple::Hurd:
6931 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
6933 case llvm::Triple::LiteOS:
6934 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
6936 case llvm::Triple::ZOS:
6937 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
6939 case llvm::Triple::Vulkan:
6940 case llvm::Triple::ShaderModel:
6941 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
6946 switch (
Target.getArch()) {
6947 case llvm::Triple::tce:
6948 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
6950 case llvm::Triple::tcele:
6951 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
6953 case llvm::Triple::hexagon:
6954 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
6957 case llvm::Triple::lanai:
6958 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
6960 case llvm::Triple::xcore:
6961 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
6963 case llvm::Triple::wasm32:
6964 case llvm::Triple::wasm64:
6965 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
6967 case llvm::Triple::avr:
6968 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
6970 case llvm::Triple::msp430:
6971 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
6973 case llvm::Triple::riscv32:
6974 case llvm::Triple::riscv64:
6975 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6977 case llvm::Triple::ve:
6978 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
6980 case llvm::Triple::spirv32:
6981 case llvm::Triple::spirv64:
6982 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
6984 case llvm::Triple::csky:
6985 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
6989 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
6990 else if (
Target.isOSBinFormatELF())
6991 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
6992 else if (
Target.isAppleMachO())
6993 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
6994 else if (
Target.isOSBinFormatMachO())
6995 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
6997 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7007 if (JA.
size() != 1 ||
7022 if (JA.
size() != 1 ||
7036 if (Args.hasArg(options::OPT_emit_static_lib))
7047 unsigned &Micro,
bool &HadExtra) {
7050 Major = Minor = Micro = 0;
7054 if (Str.consumeInteger(10, Major))
7058 if (!Str.consume_front(
"."))
7061 if (Str.consumeInteger(10, Minor))
7065 if (!Str.consume_front(
"."))
7068 if (Str.consumeInteger(10, Micro))
7086 unsigned CurDigit = 0;
7087 while (CurDigit < Digits.size()) {
7089 if (Str.consumeInteger(10, Digit))
7091 Digits[CurDigit] = Digit;
7094 if (!Str.consume_front(
"."))
7103llvm::opt::Visibility
7104Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7117const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7133 llvm_unreachable(
"Unhandled Mode");
7137 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7142 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7143 options::OPT_fno_save_optimization_record,
false))
7147 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7148 options::OPT_fno_save_optimization_record,
false))
7152 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7153 options::OPT_fno_save_optimization_record,
false))
7157 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7158 options::OPT_fno_save_optimization_record,
false))
7165 static StringRef OptName =
7167 llvm::StringRef Opt;
7168 for (StringRef Arg : Args) {
7169 if (!Arg.starts_with(OptName))
7175 return Opt.consume_front(OptName) ? Opt :
"";
7182 llvm::BumpPtrAllocator &Alloc,
7183 llvm::vfs::FileSystem *FS) {
7192 for (
const char *F : Args) {
7193 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7195 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7196 RSPQuoting = Windows;
7202 bool MarkEOLs = ClangCLMode;
7204 llvm::cl::TokenizerCallback Tokenizer;
7205 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7206 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7208 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7210 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7213 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7214 ECtx.setMarkEOLs(MarkEOLs);
7218 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7222 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7223 [](
const char *A) {
return A !=
nullptr; });
7224 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7227 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7228 Args.resize(newEnd - Args.begin());
7232 return llvm::Error::success();
7236 return SavedStrings.insert(S).first->getKeyData();
7270 llvm::StringSet<> &SavedStrings) {
7273 if (Edit[0] ==
'^') {
7274 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7275 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7276 Args.insert(Args.begin() + 1, Str);
7277 }
else if (Edit[0] ==
'+') {
7278 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7279 OS <<
"### Adding argument " << Str <<
" at end\n";
7280 Args.push_back(Str);
7281 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7282 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7283 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7284 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7285 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7287 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7289 if (Args[i] ==
nullptr)
7291 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7293 if (Repl != Args[i]) {
7294 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7298 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7299 auto Option = Edit.substr(1);
7300 for (
unsigned i = 1; i < Args.size();) {
7301 if (Option == Args[i]) {
7302 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7303 Args.erase(Args.begin() + i);
7304 if (Edit[0] ==
'X') {
7305 if (i < Args.size()) {
7306 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7307 Args.erase(Args.begin() + i);
7309 OS <<
"### Invalid X edit, end of command line!\n";
7314 }
else if (Edit[0] ==
'O') {
7315 for (
unsigned i = 1; i < Args.size();) {
7316 const char *A = Args[i];
7320 if (A[0] ==
'-' && A[1] ==
'O' &&
7321 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7322 (
'0' <= A[2] && A[2] <=
'9'))))) {
7323 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7324 Args.erase(Args.begin() + i);
7328 OS <<
"### Adding argument " << Edit <<
" at end\n";
7329 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7331 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7336 const char *OverrideStr,
7337 llvm::StringSet<> &SavedStrings,
7338 StringRef EnvVar, raw_ostream *OS) {
7340 OS = &llvm::nulls();
7342 if (OverrideStr[0] ==
'#') {
7344 OS = &llvm::nulls();
7347 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7351 const char *S = OverrideStr;
7353 const char *End = ::strchr(S,
' ');
7355 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
static llvm::SmallVector< std::string > getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind)
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 void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static StringRef getCanonicalArchString(Compilation &C, const llvm::opt::DerivedArgList &Args, StringRef ArchStr, const llvm::Triple &Triple)
Returns the canonical name for the offloading architecture when using a HIP or CUDA architecture.
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 llvm::DenseSet< llvm::StringRef > inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
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 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 bool usesInput(const ArgList &Args, F &&Fn)
static void setZosTargetVersion(const Driver &D, llvm::Triple &Target, StringRef ArgTarget)
static void appendOneArg(InputArgList &Args, const Arg *Opt)
static types::ID CXXHeaderUnitType(ModuleHeaderMode HM)
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static bool hasFlag(SVal val, ProgramStateRef state)
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.
Encodes a location in the source.
Exposes information about the current target.
Action - Represent an abstract compilation step to perform.
void setHostOffloadInfo(unsigned OKinds, const char *OArch)
const char * getOffloadingArch() const
bool isCollapsingWithNextDependentActionLegal() const
Return true if this function can be collapsed with others.
types::ID getType() const
void setCannotBeCollapsedWithNextDependentAction()
Mark this action as not legal to collapse.
std::string getOffloadingKindPrefix() const
Return a string containing the offload kind of the action.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
const ToolChain * getOffloadingToolChain() const
static std::string GetOffloadingFileNamePrefix(OffloadKind Kind, StringRef NormalizedTriple, bool CreatePrefixForHost=false)
Return a string that can be used as prefix in order to generate unique files for each offloading kind...
ActionClass getKind() const
static StringRef GetOffloadKindName(OffloadKind Kind)
Return a string containing a offload kind name.
const char * getClassName() const
OffloadKind getOffloadingDeviceKind() const
input_iterator input_begin()
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch)
Append the host offload info of this action and propagate it to its dependences.
@ BinaryTranslatorJobClass
unsigned getOffloadingHostActiveKinds() const
Options for specifying CUID used by CUDA/HIP for uniquely identifying compilation units.
std::string getCUID(StringRef InputFile, llvm::opt::DerivedArgList &Args) const
Command - An executable path/name and argument vector to execute.
const Action & getSource() const
getSource - Return the Action which caused the creation of this job.
const std::vector< std::string > & getOutputFilenames() const
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
std::optional< llvm::sys::ProcessStatistics > getProcessStatistics() const
const char * getExecutable() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
const ResponseFileSupport & getResponseFileSupport()
Returns the kind of response file supported by the current invocation.
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.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
std::string UserConfigDir
User directory for config files.
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const
BuildUniversalActions - Construct the list of actions to perform for the given arguments,...
void PrintHelp(bool ShowHidden) const
PrintHelp - Print the help text.
bool offloadDeviceOnly() const
bool isSaveTempsEnabled() const
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.
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeProgram(llvm::ArrayRef< llvm::StringRef > Args) const
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
std::string GetTemporaryDirectory(StringRef Prefix) const
GetTemporaryDirectory - Return the pathname of a temporary directory to use as part of compilation; t...
bool IsDXCMode() const
Whether the driver should follow dxc.exe like behavior.
const char * getDefaultImageName() const
Returns the default name for linked images (e.g., "a.out").
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
std::string DyldPrefix
Dynamic loader prefix, if present.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const
ShouldEmitStaticLibrary - Should the linker emit a static library.
std::string DriverTitle
Driver title to use with help.
unsigned CCCPrintBindings
Only print tool bindings, don't build any jobs.
unsigned CCLogDiagnostics
Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics to CCLogDiagnosticsFilename...
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.
unsigned CCPrintInternalStats
Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal performance report to CC_PR...
static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra)
GetReleaseVersion - Parse (([0-9]+)(.
llvm::SmallVector< StringRef > getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, Action::OffloadKind Kind, const ToolChain &TC) const
Returns the set of bound architectures active for this offload kind.
std::string Name
The name the driver was invoked as.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg=nullptr) const
std::string GetClPchPath(Compilation &C, StringRef BaseName) const
Return the pathname of the pch file in clang-cl mode.
std::string ClangExecutable
The original path to the clang executable.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArch={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
const llvm::opt::OptTable & getOpts() const
void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const
BuildActions - Construct the list of actions to perform for the given arguments, which are only done ...
bool offloadHostOnly() const
void generateCompilationDiagnostics(Compilation &C, const Command &FailingCommand, StringRef AdditionalInformation="", CompilationDiagnosticReport *GeneratedReport=nullptr)
generateCompilationDiagnostics - Generate diagnostics information including preprocessed source file(...
bool hasHeaderMode() const
Returns true if the user has indicated a C++20 header unit mode.
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, StringRef CUID, Action *HostAction) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
std::pair< types::ID, const llvm::opt::Arg * > InputTy
An input type and its arguments.
bool isUsingOffloadLTO() const
Returns true if we are performing any kind of offload LTO.
void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs)
CreateOffloadingDeviceToolChains - create all the toolchains required to support offloading devices g...
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const
GetProgramPath - Lookup Name in the list of program search paths.
bool isSaveTempsObj() const
void HandleAutocompletions(StringRef PassedFlags) const
HandleAutocompletions - Handle –autocomplete by searching and printing possible flags,...
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
unsigned CCPrintOptions
Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to CCPrintOptionsFilename or to std...
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)
std::string getTargetTriple() const
bool getCheckInputsExist() const
std::string GetStdModuleManifestPath(const Compilation &C, const ToolChain &TC) const
Lookup the path to the Standard library module manifest.
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
Compilation * BuildCompilation(ArrayRef< const char * > Args)
BuildCompilation - Construct a compilation object for a command line argument vector.
bool embedBitcodeInObject() const
std::string CCPrintStatReportFilename
The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
llvm::opt::InputArgList ParseArgStrings(ArrayRef< const char * > Args, bool UseDriverMode, bool &ContainsError) const
ParseArgStrings - Parse the given list of strings into an ArgList.
bool CCCIsCPP() const
Whether the driver is just the preprocessor.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Type used to communicate device actions.
void add(Action &A, const ToolChain &TC, const char *BoundArch, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
const ActionList & getActions() const
Get each of the individual arrays.
Type used to communicate host actions.
An offload action combines host or/and device actions according to the programming model implementati...
void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
const char * getPhaseName(ID Id)
ID
ID - Ordered values for successive stages in the compilation process which interact with user options...
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
ID getPreprocessedType(ID Id)
getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...
bool isCuda(ID Id)
isCuda - Is this a CUDA input.
bool isLLVMIR(ID Id)
Is this LLVM IR.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
bool isOpenCL(ID Id)
isOpenCL - Is this an "OpenCL" input.
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.
void applyOverrideOptions(SmallVectorImpl< const char * > &Args, const char *OverrideOpts, llvm::StringSet<> &SavedStrings, StringRef EnvVar, raw_ostream *OS=nullptr)
Apply a space separated list of edits to the input argument lists.
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.
SmallVector< InputInfo, 4 > InputInfoList
SmallVector< Action *, 3 > ActionList
ActionList - Type used for lists of actions.
bool isOptimizationLevelFast(const llvm::opt::ArgList &Args)
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.
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.
StringRef getName(const HeaderType T)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
static const OffloadArchToStringMap ArchNames[]
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.
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID)
Sanitize a target ID string for use in a file 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 ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Result
The result type of a method or function.
const FunctionProtoType * T
static bool IsNVIDIAOffloadArch(OffloadArch A)
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
const llvm::opt::OptTable & getDriverOptTable()
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
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.
U cast(CodeGen::Address addr)
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
Contains the files in the compilation diagnostic report generated by generateCompilationDiagnostics.
const char * DriverMode
Corresponding driver mode argument, as '–driver-mode=g++'.
ResponseFileKind ResponseKind
The level of support for response files.