59#include "clang/Config/config.h"
76#include "llvm/ADT/ArrayRef.h"
77#include "llvm/ADT/STLExtras.h"
78#include "llvm/ADT/ScopeExit.h"
79#include "llvm/ADT/SmallSet.h"
80#include "llvm/ADT/SmallVector.h"
81#include "llvm/ADT/StringExtras.h"
82#include "llvm/ADT/StringRef.h"
83#include "llvm/ADT/StringSet.h"
84#include "llvm/ADT/StringSwitch.h"
85#include "llvm/Config/llvm-config.h"
86#include "llvm/MC/TargetRegistry.h"
87#include "llvm/Option/Arg.h"
88#include "llvm/Option/ArgList.h"
89#include "llvm/Option/OptSpecifier.h"
90#include "llvm/Option/OptTable.h"
91#include "llvm/Option/Option.h"
92#include "llvm/Support/CommandLine.h"
93#include "llvm/Support/ErrorHandling.h"
94#include "llvm/Support/ExitCodes.h"
95#include "llvm/Support/FileSystem.h"
96#include "llvm/Support/FileUtilities.h"
97#include "llvm/Support/FormatVariadic.h"
98#include "llvm/Support/IOSandbox.h"
99#include "llvm/Support/JSON.h"
100#include "llvm/Support/MD5.h"
101#include "llvm/Support/MemoryBuffer.h"
102#include "llvm/Support/Path.h"
103#include "llvm/Support/PrettyStackTrace.h"
104#include "llvm/Support/Process.h"
105#include "llvm/Support/Program.h"
106#include "llvm/Support/Regex.h"
107#include "llvm/Support/StringSaver.h"
108#include "llvm/Support/TarWriter.h"
109#include "llvm/Support/VirtualFileSystem.h"
110#include "llvm/Support/raw_ostream.h"
111#include "llvm/TargetParser/Host.h"
112#include "llvm/TargetParser/RISCVISAInfo.h"
125using namespace clang;
128template <
typename F>
static bool usesInput(
const ArgList &Args, F &&Fn) {
129 return llvm::any_of(Args, [&](Arg *A) {
130 return (A->getOption().matches(options::OPT_x) &&
132 (A->getOption().
getKind() == Option::InputClass &&
133 StringRef(A->getValue()).rfind(
'.') != StringRef::npos &&
135 &A->getValue()[StringRef(A->getValue()).rfind(
'.') + 1])));
141 if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
142 StringRef UseCUIDStr = A->getValue();
143 UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
144 .Case(
"hash", Kind::Hash)
145 .Case(
"random", Kind::Random)
146 .Case(
"none", Kind::None)
147 .Default(Kind::Invalid);
148 if (UseCUID == Kind::Invalid)
149 D.Diag(clang::diag::err_drv_invalid_value)
150 << A->getAsString(Args) << UseCUIDStr;
153 FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
154 if (!FixedCUID.empty())
159 llvm::opt::DerivedArgList &Args)
const {
160 std::string CUID = FixedCUID.str();
163 CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
167 llvm::MD5::MD5Result
Hash;
168 Hasher.update(InputFile);
169 for (
auto *A : Args) {
170 if (A->getOption().matches(options::OPT_INPUT))
172 Hasher.update(A->getAsString(Args));
175 CUID = llvm::utohexstr(
Hash.low(),
true);
183 : Diags(Diags), VFS(
std::move(VFS)), Mode(GCCMode),
184 SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
190 TargetTriple(TargetTriple), Saver(Alloc), PrependArg(
nullptr),
191 PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(
true),
192 ProbePrecompiled(
true), SuppressMissingInputWarning(
false) {
195 this->VFS = llvm::vfs::getRealFileSystem();
200 if ((!
SysRoot.empty()) && llvm::sys::path::is_relative(
SysRoot)) {
203 llvm::sys::path::append(P,
SysRoot);
207#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
208 if (llvm::sys::path::is_absolute(CLANG_CONFIG_FILE_SYSTEM_DIR)) {
212 llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR);
213 llvm::sys::path::remove_dots(configFileDir,
true);
217#if defined(CLANG_CONFIG_FILE_USER_DIR)
220 llvm::sys::fs::expand_tilde(CLANG_CONFIG_FILE_USER_DIR, P);
229void Driver::setDriverMode(StringRef
Value) {
230 static StringRef OptName =
231 getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
232 if (
auto M = llvm::StringSwitch<std::optional<DriverMode>>(
Value)
233 .Case(
"gcc", GCCMode)
234 .Case(
"g++", GXXMode)
235 .Case(
"cpp", CPPMode)
237 .Case(
"flang", FlangMode)
238 .Case(
"dxc", DXCMode)
242 Diag(diag::err_drv_unsupported_option_argument) << OptName <<
Value;
247 bool &ContainsError)
const {
248 llvm::PrettyStackTraceString CrashInfo(
"Command line argument parsing");
249 ContainsError =
false;
251 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask(UseDriverMode);
252 unsigned MissingArgIndex, MissingArgCount;
253 InputArgList Args =
getOpts().ParseArgs(ArgStrings, MissingArgIndex,
254 MissingArgCount, VisibilityMask);
257 if (MissingArgCount) {
258 Diag(diag::err_drv_missing_argument)
259 << Args.getArgString(MissingArgIndex) << MissingArgCount;
261 Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
266 for (
const Arg *A : Args) {
268 Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
269 ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
276 if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue(
"")) {
277 Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
278 ContainsError |= Diags.getDiagnosticLevel(
279 diag::warn_drv_empty_joined_argument,
284 for (
const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
286 auto ArgString = A->getAsString(Args);
288 if (
getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) {
290 if (
getOpts().findExact(ArgString, Nearest,
292 DiagID = diag::err_drv_unknown_argument_with_suggestion;
293 Diags.Report(DiagID) << ArgString <<
"-Xflang " + Nearest;
295 DiagID = diag::err_drv_unknown_argument;
296 Diags.Report(DiagID) << ArgString;
299 llvm::opt::Visibility(
301 DiagID = diag::err_drv_unknown_argument_with_suggestion;
302 Diags.Report(DiagID) << ArgString <<
"-Xclang " + Nearest;
304 DiagID =
IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
305 : diag::err_drv_unknown_argument;
306 Diags.Report(DiagID) << ArgString;
310 ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
311 : diag::err_drv_unknown_argument_with_suggestion;
312 Diags.Report(DiagID) << ArgString << Nearest;
314 ContainsError |= Diags.getDiagnosticLevel(DiagID,
SourceLocation()) >
318 for (
const Arg *A : Args.filtered(options::OPT_o)) {
319 if (ArgStrings[A->getIndex()] == A->getSpelling())
323 std::string ArgString = ArgStrings[A->getIndex()];
325 if (
getOpts().findExact(
"-" + ArgString, Nearest, VisibilityMask))
326 Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument)
327 << A->getAsString(Args) << Nearest;
337 Arg **FinalPhaseArg)
const {
338 Arg *PhaseArg =
nullptr;
342 if (
CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
343 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
344 (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
345 (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) ||
352 }
else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
354 DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
355 (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
356 (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
357 options::OPT_fmodule_header_EQ))) {
360 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
361 (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
363 DAL.getLastArg(options::OPT_print_enabled_extensions)) ||
364 (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
365 (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
366 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
367 (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
368 (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
369 (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
370 (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
374 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
378 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
381 }
else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
389 *FinalPhaseArg = PhaseArg;
397 llvm::sys::fs::createTemporaryFile(
"driver-program",
"txt", OutputFile,
398 llvm::sys::fs::OF_Text);
399 llvm::FileRemover OutputRemover(OutputFile.c_str());
400 std::optional<llvm::StringRef> Redirects[] = {
406 std::string ErrorMessage;
407 int SecondsToWait = 60;
408 if (std::optional<std::string> Str =
409 llvm::sys::Process::GetEnv(
"CLANG_TOOLCHAIN_PROGRAM_TIMEOUT")) {
410 if (!llvm::to_integer(*Str, SecondsToWait))
411 return llvm::createStringError(std::error_code(),
412 "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected "
413 "an integer, got '" +
415 SecondsToWait = std::max(SecondsToWait, 0);
417 StringRef Executable = Args[0];
418 if (llvm::sys::ExecuteAndWait(Executable, Args, {}, Redirects, SecondsToWait,
420 return llvm::createStringError(std::error_code(),
421 Executable +
": " + ErrorMessage);
423 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
424 llvm::MemoryBuffer::getFile(OutputFile.c_str());
426 return llvm::createStringError(OutputBuf.getError(),
427 "Failed to read stdout of " + Executable +
428 ": " + OutputBuf.getError().message());
429 return std::move(*OutputBuf);
433 StringRef
Value,
bool Claim) {
434 Arg *A =
new Arg(Opts.getOption(options::OPT_INPUT),
Value,
435 Args.getBaseArgs().MakeIndex(
Value),
Value.data());
436 Args.AddSynthesizedArg(A);
442DerivedArgList *Driver::TranslateInputArgs(
const InputArgList &Args)
const {
443 const llvm::opt::OptTable &Opts =
getOpts();
444 DerivedArgList *DAL =
new DerivedArgList(Args);
446 bool HasNostdlib = Args.hasArg(options::OPT_nostdlib);
447 bool HasNostdlibxx = Args.hasArg(options::OPT_nostdlibxx);
448 bool HasNodefaultlib = Args.hasArg(options::OPT_nodefaultlibs);
449 bool IgnoreUnused =
false;
450 for (Arg *A : Args) {
454 if (A->getOption().matches(options::OPT_start_no_unused_arguments)) {
458 if (A->getOption().matches(options::OPT_end_no_unused_arguments)) {
459 IgnoreUnused =
false;
469 if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
470 A->getOption().matches(options::OPT_Xlinker)) &&
471 A->containsValue(
"--no-demangle")) {
473 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle));
476 for (StringRef Val : A->getValues())
477 if (Val !=
"--no-demangle")
478 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val);
486 if (A->getOption().matches(options::OPT_Wp_COMMA) &&
487 A->getNumValues() > 0 &&
488 (A->getValue(0) == StringRef(
"-MD") ||
489 A->getValue(0) == StringRef(
"-MMD"))) {
491 if (A->getValue(0) == StringRef(
"-MD"))
492 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD));
494 DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD));
495 if (A->getNumValues() == 2)
496 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1));
501 if (A->getOption().matches(options::OPT_l)) {
502 StringRef
Value = A->getValue();
505 if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx &&
507 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx));
512 if (
Value ==
"cc_kext") {
513 DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext));
519 if (A->getOption().matches(options::OPT__DASH_DASH)) {
521 for (StringRef Val : A->getValues())
530 if (
IsDXCMode() && !Args.hasArg(options::OPT_dxc_Fo))
531 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
534 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false))
535 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_static));
539#if defined(HOST_LINK_VERSION)
540 if (!Args.hasArg(options::OPT_mlinker_version_EQ) &&
541 strlen(HOST_LINK_VERSION) > 0) {
542 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ),
544 DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
552 StringRef ArgTarget) {
554 static bool BeSilent =
false;
555 auto IsTooOldToBeSupported = [](
int v,
int r) ->
bool {
return v < 3; };
558 if (ArgTarget.equals_insensitive(
"CURRENT")) {
562 unsigned int Version = 0;
563 unsigned int Release = 0;
564 unsigned int Modification = 0;
566 llvm::Regex ZOsvRegex(
"[zZ][oO][sS][vV]([0-9])[rR]([0-9])");
567 llvm::Regex HexRegex(
570 "([0-9a-fA-F][0-9a-fA-F])"
571 "([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" );
574 if (ZOsvRegex.match(ArgTarget, &Matches)) {
575 Matches[1].getAsInteger(10, Version);
576 Matches[2].getAsInteger(10, Release);
578 if (IsTooOldToBeSupported(Version, Release)) {
580 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
583 }
else if (HexRegex.match(ArgTarget, &Matches)) {
584 Matches[1].getAsInteger(16, Version);
585 Matches[2].getAsInteger(16, Release);
586 Matches[3].getAsInteger(16, Modification);
587 if (IsTooOldToBeSupported(Version, Release)) {
589 D.
Diag(diag::err_zos_target_release_discontinued) << ArgTarget;
595 D.
Diag(diag::err_zos_target_unrecognized_release) << ArgTarget;
600 llvm::VersionTuple
V(Version, Release, Modification);
601 llvm::VersionTuple TV =
Target.getOSVersion();
604 if (TV.empty() ||
V < TV) {
606 Str = llvm::Triple::getOSTypeName(
Target.getOS());
607 Str +=
V.getAsString();
621 StringRef ArchName =
"") {
623 if (
const Arg *A = Args.getLastArg(options::OPT_target))
624 TargetTriple = A->getValue();
626 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
631 if (TargetTriple.contains(
"-unknown-gnu") || TargetTriple.contains(
"-pc-gnu"))
635 if (
Target.isOSBinFormatMachO()) {
637 if (!ArchName.empty()) {
639 return llvm::Triple(
Target.normalize());
643 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
644 StringRef ArchName = A->getValue();
647 }
else if (!ArchName.empty()) {
648 Target.setArchName(ArchName);
654 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mlittle_endian,
655 options::OPT_mbig_endian)) {
656 llvm::Triple T = A->getOption().matches(options::OPT_mlittle_endian)
657 ?
Target.getLittleEndianArchVariant()
658 :
Target.getBigEndianArchVariant();
659 if (T.getArch() != llvm::Triple::UnknownArch) {
660 Target = llvm::Triple(T.normalize());
661 Args.claimAllArgs(options::OPT_mlittle_endian, options::OPT_mbig_endian);
666 if (
Target.getArch() == llvm::Triple::tce)
672 if (!Args.hasArg(options::OPT_target)) {
673 if (std::optional<std::string> ObjectModeValue =
674 llvm::sys::Process::GetEnv(
"OBJECT_MODE")) {
675 StringRef ObjectMode = *ObjectModeValue;
676 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
679 const bool OtherAllowedMode =
680 ObjectMode ==
"32_64" || ObjectMode ==
"any";
681 if (ObjectMode ==
"64") {
682 AT =
Target.get64BitArchVariant().getArch();
683 }
else if (ObjectMode ==
"32") {
684 AT =
Target.get32BitArchVariant().getArch();
685 }
else if (!OtherAllowedMode) {
686 D.
Diag(diag::err_drv_invalid_object_mode) << ObjectMode;
689 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
698 if (
Target.isUEFI() &&
Target.getArch() != llvm::Triple::x86_64)
699 D.
Diag(diag::err_target_unknown_triple) <<
Target.str();
702 if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
704 D.
Diag(diag::err_drv_unsupported_opt_for_target)
705 << A->getAsString(Args) <<
Target.str();
708 Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
709 options::OPT_m32, options::OPT_m16,
710 options::OPT_maix32, options::OPT_maix64);
712 llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
714 if (A->getOption().matches(options::OPT_m64) ||
715 A->getOption().matches(options::OPT_maix64)) {
716 AT =
Target.get64BitArchVariant().getArch();
717 if (
Target.getEnvironment() == llvm::Triple::GNUX32 ||
718 Target.getEnvironment() == llvm::Triple::GNUT64)
719 Target.setEnvironment(llvm::Triple::GNU);
720 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
721 Target.setEnvironment(llvm::Triple::Musl);
722 }
else if (A->getOption().matches(options::OPT_mx32) &&
723 Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
724 AT = llvm::Triple::x86_64;
725 if (
Target.getEnvironment() == llvm::Triple::Musl)
726 Target.setEnvironment(llvm::Triple::MuslX32);
728 Target.setEnvironment(llvm::Triple::GNUX32);
729 }
else if (A->getOption().matches(options::OPT_m32) ||
730 A->getOption().matches(options::OPT_maix32)) {
732 D.
Diag(diag::err_drv_unsupported_opt_for_target)
733 << A->getAsString(Args) <<
Target.str();
735 AT =
Target.get32BitArchVariant().getArch();
736 if (
Target.getEnvironment() == llvm::Triple::GNUX32)
737 Target.setEnvironment(llvm::Triple::GNU);
738 else if (
Target.getEnvironment() == llvm::Triple::MuslX32)
739 Target.setEnvironment(llvm::Triple::Musl);
741 }
else if (A->getOption().matches(options::OPT_m16) &&
742 Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
743 AT = llvm::Triple::x86;
744 Target.setEnvironment(llvm::Triple::CODE16);
747 if (AT != llvm::Triple::UnknownArch && AT !=
Target.getArch()) {
749 if (
Target.isWindowsGNUEnvironment())
757 if ((A = Args.getLastArg(options::OPT_mzos_target_EQ))) {
763 if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu,
false)) {
764 if (
Target.get32BitArchVariant().getArch() != llvm::Triple::x86)
765 D.
Diag(diag::err_drv_unsupported_opt_for_target) <<
"-miamcu"
768 if (A && !A->getOption().matches(options::OPT_m32))
769 D.
Diag(diag::err_drv_argument_not_allowed_with)
770 <<
"-miamcu" << A->getBaseArg().getAsString(Args);
772 Target.setArch(llvm::Triple::x86);
773 Target.setArchName(
"i586");
774 Target.setEnvironmentName(
"");
775 Target.setOS(llvm::Triple::ELFIAMCU);
776 Target.setVendor(llvm::Triple::Intel);
782 if ((A = Args.getLastArg(options::OPT_mabi_EQ))) {
783 StringRef ABIName = A->getValue();
784 if (ABIName ==
"32") {
786 if (
Target.getEnvironment() == llvm::Triple::GNUABI64 ||
787 Target.getEnvironment() == llvm::Triple::GNUABIN32)
788 Target.setEnvironment(llvm::Triple::GNU);
789 }
else if (ABIName ==
"n32") {
791 if (
Target.getEnvironment() == llvm::Triple::GNU ||
792 Target.getEnvironment() == llvm::Triple::GNUT64 ||
793 Target.getEnvironment() == llvm::Triple::GNUABI64)
794 Target.setEnvironment(llvm::Triple::GNUABIN32);
795 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
796 Target.getEnvironment() == llvm::Triple::MuslABI64)
797 Target.setEnvironment(llvm::Triple::MuslABIN32);
798 }
else if (ABIName ==
"64") {
800 if (
Target.getEnvironment() == llvm::Triple::GNU ||
801 Target.getEnvironment() == llvm::Triple::GNUT64 ||
802 Target.getEnvironment() == llvm::Triple::GNUABIN32)
803 Target.setEnvironment(llvm::Triple::GNUABI64);
804 else if (
Target.getEnvironment() == llvm::Triple::Musl ||
805 Target.getEnvironment() == llvm::Triple::MuslABIN32)
806 Target.setEnvironment(llvm::Triple::MuslABI64);
816 if (Args.hasArg(options::OPT_march_EQ) ||
817 Args.hasArg(options::OPT_mcpu_EQ)) {
819 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
821 if (!llvm::errorToBool(ISAInfo.takeError())) {
822 unsigned XLen = (*ISAInfo)->getXLen();
824 if (
Target.isLittleEndian())
825 Target.setArch(llvm::Triple::riscv32);
827 Target.setArch(llvm::Triple::riscv32be);
829 }
else if (XLen == 64) {
830 if (
Target.isLittleEndian())
831 Target.setArch(llvm::Triple::riscv64);
833 Target.setArch(llvm::Triple::riscv64be);
840 if (
Target.getArch() == llvm::Triple::riscv32be ||
841 Target.getArch() == llvm::Triple::riscv64be) {
842 static bool WarnedRISCVBE =
false;
843 if (!WarnedRISCVBE) {
844 D.
Diag(diag::warn_drv_riscv_be_experimental);
845 WarnedRISCVBE =
true;
854 StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
856 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
858 RuntimeName = A->getValue();
860 auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
868 Diag(diag::err_drv_unsupported_option_argument)
869 << A->getSpelling() << A->getValue();
872 Diag(diag::err_drv_unsupported_opt) <<
"-fopenmp";
881 StringRef Program =
C.getArgs().getLastArgValue(
882 options::OPT_offload_arch_tool_EQ,
"offload-arch");
885 if (llvm::ErrorOr<std::string> Executable =
886 llvm::sys::findProgramByName(Program, {
C.getDriver().Dir})) {
889 Args.push_back(
"--only=amdgpu");
891 Args.push_back(
"--only=nvptx");
892 auto StdoutOrErr =
C.getDriver().executeProgram(Args);
895 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
900 if ((*StdoutOrErr)->getBuffer().empty()) {
901 C.getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
907 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
909 GPUArchs.push_back(
Arch.str());
911 C.getDriver().Diag(diag::err_drv_command_failure) <<
"offload-arch";
922 std::set<std::string> Archs;
923 for (Arg *A :
C.getInputArgs()) {
924 for (StringRef
Arch : A->getValues()) {
925 if (A->getOption().matches(options::OPT_offload_arch_EQ)) {
926 if (
Arch ==
"native") {
928 Archs.insert(Str.str());
930 Archs.insert(
Arch.str());
932 }
else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) {
936 Archs.erase(
Arch.str());
942 for (llvm::StringRef
Arch : Archs) {
949 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
954 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
960 C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
965 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
966 <<
"offload" <<
Arch;
970 llvm::Triple Triple =
976 Option Opt =
C.getDriver().getOpts().getOption(options::OPT_Xarch__);
977 unsigned Index =
C.getArgs().getBaseArgs().MakeIndex(
"-Xarch_");
978 Arg *A =
new Arg(Opt,
C.getArgs().getArgString(Index), Index,
979 C.getArgs().MakeArgString(Triple.getArchName()),
980 C.getArgs().MakeArgString(
"--offload-arch=" +
Arch));
982 C.getArgs().append(A);
983 C.getArgs().AddSynthesizedArg(A);
985 auto It = Triples.lower_bound(Triple);
986 if (It == Triples.end() || *It != Triple)
987 Triples.insert(It, Triple);
992 Triples.insert(llvm::Triple(
"amdgcn-amd-amdhsa"));
994 llvm::Triple::ArchType
Arch =
995 C.getDefaultToolChain().getTriple().isArch64Bit()
996 ? llvm::Triple::nvptx64
997 : llvm::Triple::nvptx;
998 Triples.insert(llvm::Triple(
Arch, llvm::Triple::NoSubArch,
999 llvm::Triple::NVIDIA, llvm::Triple::CUDA));
1002 llvm::Triple(
C.getDefaultToolChain().getTriple().isArch64Bit()
1003 ? llvm::Triple::spirv64
1004 : llvm::Triple::spirv32));
1007 C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
1008 C.getArgs().eraseArg(options::OPT_no_offload_arch_EQ);
1015 bool UseLLVMOffload =
C.getInputArgs().hasArg(
1016 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
1018 llvm::any_of(Inputs,
1019 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1024 (llvm::any_of(Inputs,
1025 [](std::pair<types::ID, const llvm::opt::Arg *> &I) {
1028 C.getInputArgs().hasArg(options::OPT_hip_link) ||
1029 C.getInputArgs().hasArg(options::OPT_hipstdpar)) &&
1031 bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl,
1032 options::OPT_fno_sycl,
false);
1033 bool IsOpenMPOffloading =
1035 (
C.getInputArgs().
hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1036 options::OPT_fno_openmp,
false) &&
1037 (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ) ||
1038 (
C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
1039 !(IsCuda || IsHIP))));
1041 llvm::SmallSet<Action::OffloadKind, 4> Kinds;
1042 const std::pair<bool, Action::OffloadKind> ActiveKinds[] = {
1047 for (
const auto &[Active, Kind] : ActiveKinds)
1052 if (Kinds.size() > 1) {
1053 Diag(clang::diag::err_drv_mix_offload)
1060 if (IsCuda || IsHIP)
1067 if (
C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
1068 std::vector<std::string> ArgValues =
1069 C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
1070 for (llvm::StringRef
Target : ArgValues) {
1074 if (ArgValues.empty())
1075 Diag(clang::diag::warn_drv_empty_joined_argument)
1077 .getLastArg(options::OPT_offload_targets_EQ)
1078 ->getAsString(
C.getInputArgs());
1085 llvm::StringMap<StringRef> FoundNormalizedTriples;
1086 for (
const llvm::Triple &
Target : Triples) {
1091 Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
1099 {options::OPT_static_libstdcxx, options::OPT_ffreestanding})
1100 if (Arg *IncompatArg =
C.getInputArgs().getLastArg(ID))
1101 Diag(clang::diag::err_drv_argument_not_allowed_with)
1102 << IncompatArg->getSpelling() <<
"-fsycl";
1107 if (
Target.getArch() == llvm::Triple::ArchType::UnknownArch) {
1108 Diag(diag::err_drv_invalid_or_unsupported_offload_target)
1113 std::string NormalizedName =
Target.normalize();
1114 auto [TripleIt, Inserted] =
1115 FoundNormalizedTriples.try_emplace(NormalizedName,
Target.str());
1117 Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
1118 <<
Target.str() << TripleIt->second;
1122 auto &TC = getOffloadToolChain(
C.getInputArgs(), Kind,
Target,
1123 C.getDefaultToolChain().getTriple());
1127 auto &CudaInstallation =
1129 if (CudaInstallation.isValid())
1130 CudaInstallation.WarnIfUnsupportedVersion();
1133 C.addOffloadDeviceToolChain(&TC, Kind);
1138bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
1143 StringRef PathLIBEnv = StringRef(getenv(
"CLANG_CONFIG_PATH")).trim();
1147 if (!PathLIBEnv.empty()) {
1148 llvm::sys::path::append(CustomizationFile, PathLIBEnv);
1149 if (llvm::sys::fs::is_directory(PathLIBEnv))
1150 llvm::sys::path::append(CustomizationFile,
"/clang.cfg");
1151 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1152 return readConfigFile(CustomizationFile, ExpCtx);
1153 Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
1158 llvm::sys::path::append(CustomizationFile, BaseDir +
"/etc/clang.cfg");
1159 if (llvm::sys::fs::is_regular_file(CustomizationFile))
1160 return readConfigFile(CustomizationFile, ExpCtx);
1170 unsigned Index = Args.MakeIndex(Opt->getSpelling());
1171 Arg *
Copy =
new Arg(Opt->getOption(), Args.getArgString(Index), Index);
1172 Copy->getValues() = Opt->getValues();
1173 if (Opt->isClaimed())
1175 Copy->setOwnsValues(Opt->getOwnsValues());
1176 Opt->setOwnsValues(
false);
1178 if (Opt->getAlias()) {
1179 const Arg *Alias = Opt->getAlias();
1180 unsigned Index = Args.MakeIndex(Alias->getSpelling());
1181 auto AliasCopy = std::make_unique<Arg>(Alias->getOption(),
1182 Args.getArgString(Index), Index);
1183 AliasCopy->getValues() = Alias->getValues();
1184 AliasCopy->setOwnsValues(
false);
1185 if (Alias->isClaimed())
1187 Copy->setAlias(std::move(AliasCopy));
1191bool Driver::readConfigFile(StringRef
FileName,
1192 llvm::cl::ExpansionContext &ExpCtx) {
1196 Diag(diag::err_drv_cannot_open_config_file)
1197 <<
FileName << Status.getError().message();
1200 if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
1201 Diag(diag::err_drv_cannot_open_config_file)
1202 <<
FileName <<
"not a regular file";
1207 SmallVector<const char *, 32> NewCfgFileArgs;
1208 if (llvm::Error Err = ExpCtx.readConfigFile(
FileName, NewCfgFileArgs)) {
1209 Diag(diag::err_drv_cannot_read_config_file)
1215 SmallVector<const char *, 32> NewCfgHeadArgs, NewCfgTailArgs;
1216 for (
const char *Opt : NewCfgFileArgs) {
1218 if (Opt[0] ==
'$' && Opt[1])
1219 NewCfgTailArgs.push_back(Opt + 1);
1221 NewCfgHeadArgs.push_back(Opt);
1225 llvm::SmallString<128> CfgFileName(
FileName);
1226 llvm::sys::path::native(CfgFileName);
1227 bool ContainErrors =
false;
1228 auto NewHeadOptions = std::make_unique<InputArgList>(
1232 auto NewTailOptions = std::make_unique<InputArgList>(
1239 for (Arg *A : *NewHeadOptions)
1241 for (Arg *A : *NewTailOptions)
1244 if (!CfgOptionsHead)
1245 CfgOptionsHead = std::move(NewHeadOptions);
1248 for (
auto *Opt : *NewHeadOptions)
1252 if (!CfgOptionsTail)
1253 CfgOptionsTail = std::move(NewTailOptions);
1256 for (
auto *Opt : *NewTailOptions)
1260 ConfigFiles.push_back(std::string(CfgFileName));
1264bool Driver::loadConfigFiles() {
1265 llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
1266 llvm::cl::tokenizeConfigFile, &
getVFS());
1270 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
1271 SmallString<128> CfgDir;
1273 CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
1274 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1279 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
1280 SmallString<128> CfgDir;
1281 llvm::sys::fs::expand_tilde(
1282 CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ), CfgDir);
1283 if (CfgDir.empty() ||
getVFS().makeAbsolute(CfgDir))
1292 ExpCtx.setSearchDirs(CfgFileSearchDirs);
1295 if (loadDefaultConfigFiles(ExpCtx))
1299 SmallString<128> CfgFilePath;
1301 for (
auto CfgFileName : CLOptions->getAllArgValues(options::OPT_config)) {
1304 if (llvm::sys::path::has_parent_path(CfgFileName)) {
1305 CfgFilePath.assign(CfgFileName);
1306 if (llvm::sys::path::is_relative(CfgFilePath)) {
1307 if (
getVFS().makeAbsolute(CfgFilePath)) {
1308 Diag(diag::err_drv_cannot_open_config_file)
1309 << CfgFilePath <<
"cannot get absolute path";
1313 }
else if (!ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1315 Diag(diag::err_drv_config_file_not_found) << CfgFileName;
1316 for (
const StringRef &SearchDir : CfgFileSearchDirs)
1317 if (!SearchDir.empty())
1318 Diag(diag::note_drv_config_file_searched_in) << SearchDir;
1323 if (readConfigFile(CfgFilePath, ExpCtx))
1334 llvm::Triple Triple, std::string Suffix) {
1336 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1340 VersionTuple OSVersion = Triple.getOSVersion();
1341 if (!OSVersion.getMinor().has_value())
1344 std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str();
1348 if (OSVersion.getMajor() != 0) {
1349 Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor()));
1350 if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath))
1356 Triple.setOSName(BaseOSName);
1357 return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath);
1360bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
1363 if (
const char *NoConfigEnv = ::getenv(
"CLANG_NO_DEFAULT_CONFIG")) {
1367 if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
1370 std::string RealMode = getExecutableForDriverMode(Mode);
1371 llvm::Triple Triple;
1380 if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
1381 PrefixTriple.isOSUnknown())
1382 Triple = std::move(PrefixTriple);
1386 llvm::Triple RealTriple =
1388 if (Triple.str().empty()) {
1389 Triple = RealTriple;
1390 assert(!Triple.str().empty());
1395 if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
1409 SmallString<128> CfgFilePath;
1411 "-" + RealMode +
".cfg"))
1412 return readConfigFile(CfgFilePath, ExpCtx);
1416 if (TryModeSuffix) {
1419 return readConfigFile(CfgFilePath, ExpCtx);
1424 std::string CfgFileName = RealMode +
".cfg";
1425 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) {
1426 if (readConfigFile(CfgFilePath, ExpCtx))
1428 }
else if (TryModeSuffix) {
1430 if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath) &&
1431 readConfigFile(CfgFilePath, ExpCtx))
1437 return readConfigFile(CfgFilePath, ExpCtx);
1445 llvm::PrettyStackTraceString CrashInfo(
"Compilation construction");
1454 if (!DriverMode.empty())
1455 setDriverMode(DriverMode);
1461 CLOptions = std::make_unique<InputArgList>(
1466 ContainsError = loadConfigFiles();
1467 bool HasConfigFileHead = !ContainsError && CfgOptionsHead;
1468 bool HasConfigFileTail = !ContainsError && CfgOptionsTail;
1472 HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions);
1474 if (HasConfigFileHead)
1475 for (
auto *Opt : *CLOptions)
1476 if (!Opt->getOption().matches(options::OPT_config))
1480 if (
IsCLMode() && !ContainsError) {
1482 for (
const auto *A : Args.filtered(options::OPT__SLASH_clang)) {
1484 CLModePassThroughArgList.push_back(A->getValue());
1487 if (!CLModePassThroughArgList.empty()) {
1490 auto CLModePassThroughOptions = std::make_unique<InputArgList>(
1495 for (
auto *Opt : *CLModePassThroughOptions)
1501 if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
1502 if (VFS->setCurrentWorkingDirectory(WD->getValue()))
1503 Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
1506 if (!Diags.isIgnored(diag::warn_missing_include_dirs,
SourceLocation())) {
1507 for (
auto IncludeDir : Args.getAllArgValues(options::OPT_I_Group)) {
1508 if (!VFS->exists(IncludeDir))
1509 Diag(diag::warn_missing_include_dirs) << IncludeDir;
1514 bool CCCPrintPhases;
1517 Args.ClaimAllArgs(options::OPT_canonical_prefixes);
1518 Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);
1521 Args.ClaimAllArgs(options::OPT_fintegrated_cc1);
1522 Args.ClaimAllArgs(options::OPT_fno_integrated_cc1);
1525 Args.ClaimAllArgs(options::OPT_pipe);
1533 CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
1535 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
1536 CCCGenericGCCName = A->getValue();
1539 if (
const Arg *A = Args.getLastArg(options::OPT_fproc_stat_report_EQ)) {
1543 if (Args.hasArg(options::OPT_fproc_stat_report))
1550 llvm::Triple T(TargetTriple);
1551 T.setOS(llvm::Triple::Win32);
1552 T.setVendor(llvm::Triple::PC);
1553 T.setEnvironment(llvm::Triple::MSVC);
1554 T.setObjectFormat(llvm::Triple::COFF);
1555 if (Args.hasArg(options::OPT__SLASH_arm64EC))
1556 T.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64ec);
1557 TargetTriple = T.str();
1560 if (
const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
1561 StringRef TargetProfile = A->getValue();
1564 TargetTriple = *Triple;
1566 Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
1570 if (Args.hasArg(options::OPT_spirv)) {
1571 const llvm::StringMap<llvm::Triple::SubArchType> ValidTargets = {
1572 {
"vulkan1.2", llvm::Triple::SPIRVSubArch_v15},
1573 {
"vulkan1.3", llvm::Triple::SPIRVSubArch_v16}};
1574 llvm::Triple T(TargetTriple);
1577 auto TargetInfo = ValidTargets.find(
"vulkan1.3");
1579 if (
const Arg *A = Args.getLastArg(options::OPT_fspv_target_env_EQ)) {
1580 TargetInfo = ValidTargets.find(A->getValue());
1582 Diag(diag::err_drv_invalid_value)
1583 << A->getAsString(Args) << A->getValue();
1589 T.setArch(llvm::Triple::spirv,
TargetInfo->getValue());
1590 TargetTriple = T.str();
1594 Diag(diag::err_drv_dxc_missing_target_profile);
1598 if (
const Arg *A = Args.getLastArg(options::OPT_target))
1599 TargetTriple = A->getValue();
1600 if (
const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
1601 Dir = A->getValue();
1602 for (
const Arg *A : Args.filtered(options::OPT_B)) {
1606 if (std::optional<std::string> CompilerPathValue =
1607 llvm::sys::Process::GetEnv(
"COMPILER_PATH")) {
1608 StringRef CompilerPath = *CompilerPathValue;
1609 while (!CompilerPath.empty()) {
1610 std::pair<StringRef, StringRef> Split =
1611 CompilerPath.split(llvm::sys::EnvPathSeparator);
1612 PrefixDirs.push_back(std::string(Split.first));
1613 CompilerPath = Split.second;
1616 if (
const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
1618 if (
const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))
1621 if (
const Arg *A = Args.getLastArg(options::OPT_resource_dir))
1624 if (
const Arg *A = Args.getLastArg(options::OPT_save_temps_EQ)) {
1625 SaveTemps = llvm::StringSwitch<SaveTempsMode>(A->getValue())
1626 .Case(
"cwd", SaveTempsCwd)
1627 .Case(
"obj", SaveTempsObj)
1628 .Default(SaveTempsCwd);
1631 if (
const Arg *A = Args.getLastArg(options::OPT_offload_host_only,
1632 options::OPT_offload_device_only,
1633 options::OPT_offload_host_device)) {
1634 if (A->getOption().matches(options::OPT_offload_host_only))
1635 Offload = OffloadHost;
1636 else if (A->getOption().matches(options::OPT_offload_device_only))
1637 Offload = OffloadDevice;
1639 Offload = OffloadHostDevice;
1643 if (Arg *A = Args.getLastArg(options::OPT_fembed_bitcode_EQ)) {
1644 StringRef
Name = A->getValue();
1645 unsigned Model = llvm::StringSwitch<unsigned>(
Name)
1646 .Case(
"off", EmbedNone)
1647 .Case(
"all", EmbedBitcode)
1648 .Case(
"bitcode", EmbedBitcode)
1649 .Case(
"marker", EmbedMarker)
1652 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1655 BitcodeEmbed =
static_cast<BitcodeEmbedMode
>(Model);
1659 if (Arg *A = Args.getLastArg(options::OPT_MJ))
1660 llvm::sys::fs::remove(A->getValue());
1666 const Arg *Std = Args.getLastArg(options::OPT_std_EQ);
1668 !Args.hasArg(options::OPT_fmodules) && Std &&
1669 (Std->containsValue(
"c++20") || Std->containsValue(
"c++2a") ||
1670 Std->containsValue(
"c++23") || Std->containsValue(
"c++2b") ||
1671 Std->containsValue(
"c++26") || Std->containsValue(
"c++2c") ||
1672 Std->containsValue(
"c++2d") || Std->containsValue(
"c++latest"));
1675 if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
1676 options::OPT_fmodule_header)) {
1678 ModulesModeCXX20 =
true;
1679 if (A->getOption().matches(options::OPT_fmodule_header))
1682 StringRef ArgName = A->getValue();
1683 unsigned Kind = llvm::StringSwitch<unsigned>(ArgName)
1688 Diags.Report(diag::err_drv_invalid_value)
1689 << A->getAsString(Args) << ArgName;
1695 std::unique_ptr<llvm::opt::InputArgList> UArgs =
1696 std::make_unique<InputArgList>(std::move(Args));
1706 llvm::map_range(MultilibMacroDefinesStr, [&UArgs](
const auto &S) {
1707 return UArgs->MakeArgString(Twine(
"-D") + Twine(S));
1709 bool MLContainsError;
1710 auto MultilibMacroDefineList =
1712 MLMacroDefinesChar,
false, MLContainsError));
1713 if (!MLContainsError) {
1714 for (
auto *Opt : *MultilibMacroDefineList) {
1721 DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
1725 if (!Triple.isWasm()) {
1726 StringRef TripleVersionName = Triple.getEnvironmentVersionString();
1727 StringRef TripleObjectFormat =
1728 Triple.getObjectFormatTypeName(Triple.getObjectFormat());
1729 if (Triple.getEnvironmentVersion().empty() && TripleVersionName !=
"" &&
1730 TripleVersionName != TripleObjectFormat) {
1731 Diags.Report(diag::err_drv_triple_version_invalid)
1733 ContainsError =
true;
1738 if ((TC.
getTriple().getArch() != llvm::Triple::aarch64 ||
1739 TC.
getTriple().getSubArch() != llvm::Triple::AArch64SubArch_arm64ec) &&
1740 UArgs->hasArg(options::OPT__SLASH_arm64EC)) {
1748 if (TC.
getTriple().getOS() == llvm::Triple::UnknownOS &&
1749 TC.
getTriple().getVendor() == llvm::Triple::UnknownVendor) {
1751 case llvm::Triple::arm:
1752 case llvm::Triple::armeb:
1753 case llvm::Triple::thumb:
1754 case llvm::Triple::thumbeb:
1755 if (TC.
getTriple().getEnvironmentName() ==
"elf") {
1756 Diag(diag::warn_target_unrecognized_env)
1758 << (TC.
getTriple().getArchName().str() +
"-none-eabi");
1761 case llvm::Triple::aarch64:
1762 case llvm::Triple::aarch64_be:
1763 case llvm::Triple::aarch64_32:
1764 if (TC.
getTriple().getEnvironmentName().starts_with(
"eabi")) {
1765 Diag(diag::warn_target_unrecognized_env)
1767 << (TC.
getTriple().getArchName().str() +
"-none-elf");
1784 BuildInputs(
C->getDefaultToolChain(), *TranslatedArgs, Inputs);
1785 if (HasConfigFileTail && Inputs.size()) {
1788 DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
1789 for (Arg *A : *CfgOptionsTail)
1790 TranslatedLinkerIns.append(A);
1791 BuildInputs(
C->getDefaultToolChain(), TranslatedLinkerIns, Inputs);
1798 bool UseModulesDriver =
C->getArgs().hasFlag(
1799 options::OPT_fmodules_driver, options::OPT_fno_modules_driver,
false);
1801 if (UseModulesDriver) {
1802 Diags.Report(diag::remark_performing_driver_managed_module_build);
1810 const auto StdModuleManifestPath =
1813 if (!llvm::sys::fs::exists(StdModuleManifestPath))
1814 Diags.Report(diag::remark_modules_manifest_not_found);
1816 Diags.Report(diag::remark_using_modules_manifest)
1817 << StdModuleManifestPath;
1818 if (
auto ManifestOrErr =
1820 ModulesManifest = std::move(*ManifestOrErr);
1822 llvm::erase_if(ModulesManifest.
Modules, [](
const auto &ModuleEntry) {
1823 return !ModuleEntry.IsStdlib;
1828 llvm::handleAllErrors(
1829 ManifestOrErr.takeError(),
1830 [&](llvm::json::ParseError &Err) {
1831 Diags.Report(diag::err_modules_manifest_failed_parse)
1834 [&](llvm::FileError &Err) {
1835 Diags.Report(diag::err_cannot_open_file)
1836 << Err.getFileName() << Err.messageWithoutFileInfo();
1844 if (TC.
getTriple().isOSBinFormatMachO())
1849 if (CCCPrintPhases) {
1856 if (UseModulesDriver)
1863 llvm::opt::ArgStringList ASL;
1864 for (
const auto *A : Args) {
1868 while (A->getAlias())
1870 A->render(Args, ASL);
1873 for (
auto I = ASL.begin(), E = ASL.end(); I != E; ++I) {
1874 if (I != ASL.begin())
1876 llvm::sys::printArg(OS, *I,
true);
1881bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
1882 SmallString<128> &CrashDiagDir) {
1883 using namespace llvm::sys;
1884 assert(llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin() &&
1885 "Only knows about .crash files on Darwin");
1887 auto BypassSandbox = sandbox::scopedDisable();
1892 path::home_directory(CrashDiagDir);
1893 if (CrashDiagDir.starts_with(
"/var/root"))
1895 path::append(CrashDiagDir,
"Library/Logs/DiagnosticReports");
1903 fs::file_status FileStatus;
1904 TimePoint<> LastAccessTime;
1905 SmallString<128> CrashFilePath;
1908 for (fs::directory_iterator
File(CrashDiagDir, EC), FileEnd;
1909 File != FileEnd && !EC;
File.increment(EC)) {
1913 if (fs::status(
File->path(), FileStatus))
1915 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> CrashFile =
1916 llvm::MemoryBuffer::getFile(
File->path());
1921 StringRef
Data = CrashFile.get()->getBuffer();
1922 if (!
Data.starts_with(
"Process:"))
1925 size_t ParentProcPos =
Data.find(
"Parent Process:");
1926 if (ParentProcPos == StringRef::npos)
1928 size_t LineEnd =
Data.find_first_of(
"\n", ParentProcPos);
1929 if (LineEnd == StringRef::npos)
1931 StringRef ParentProcess =
Data.slice(ParentProcPos+15, LineEnd).trim();
1932 int OpenBracket = -1, CloseBracket = -1;
1933 for (
size_t i = 0, e = ParentProcess.size(); i < e; ++i) {
1934 if (ParentProcess[i] ==
'[')
1936 if (ParentProcess[i] ==
']')
1942 if (OpenBracket < 0 || CloseBracket < 0 ||
1943 ParentProcess.slice(OpenBracket + 1, CloseBracket)
1944 .getAsInteger(10, CrashPID) || CrashPID != PID) {
1954 const auto FileAccessTime = FileStatus.getLastModificationTime();
1955 if (FileAccessTime > LastAccessTime) {
1956 CrashFilePath.assign(
File->path());
1957 LastAccessTime = FileAccessTime;
1962 if (!CrashFilePath.empty()) {
1963 EC = fs::copy_file(CrashFilePath, ReproCrashFilename);
1973 "\n********************\n\n"
1974 "PLEASE ATTACH THE FOLLOWING CRASH REPRODUCER FILES TO THE BUG REPORT:";
1982 if (
C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
1985 bool HasCrashTar =
C.getArgs().hasArg(options::OPT_fcrash_diagnostics_tar);
1988 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_EQ)) {
1989 Level = llvm::StringSwitch<unsigned>(A->getValue())
1991 .Case(
"compiler", 1)
2003 ArgStringList SavedTemps;
2005 C.getDefaultToolChain().GetLinkerPath(&IsLLD);
2006 if (!IsLLD || Level < 2)
2013 SavedTemps = std::move(
C.getTempFiles());
2014 assert(!
C.getTempFiles().size());
2031 C.initCompilationForDiagnostics();
2036 Command NewLLDInvocation = Cmd;
2037 llvm::opt::ArgStringList ArgList = NewLLDInvocation.
getArguments();
2038 StringRef ReproduceOption =
2039 C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment()
2042 ArgList.push_back(Saver.save(Twine(ReproduceOption) + TmpName).data());
2046 NewLLDInvocation.
Execute({std::nullopt, {
""}, {
""}},
nullptr,
nullptr);
2048 Diag(clang::diag::note_drv_command_failed_diag_msg) << TmpName;
2049 Diag(clang::diag::note_drv_command_failed_diag_msg)
2050 <<
"\n\n********************";
2052 Report->TemporaryFiles.push_back(TmpName);
2060 ArgStringList IRInputs;
2061 for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
2062 bool IgnoreInput =
false;
2068 IRInputs.push_back(it->second->getValue());
2072 }
else if (!strcmp(it->second->getValue(),
"-")) {
2073 Diag(clang::diag::note_drv_command_failed_diag_msg)
2074 <<
"Error generating preprocessed source(s) - "
2075 "ignoring input from stdin.";
2080 it = Inputs.erase(it);
2087 if (Inputs.empty() && IRInputs.empty()) {
2088 Diag(clang::diag::note_drv_command_failed_diag_msg)
2089 <<
"Error generating preprocessed source(s) - "
2090 "no preprocessable inputs.";
2097 for (
const Arg *A :
C.getArgs()) {
2098 if (A->getOption().matches(options::OPT_arch)) {
2099 StringRef ArchName = A->getValue();
2106 if (FailingArch.empty()) {
2107 Diag(clang::diag::note_drv_command_failed_diag_msg)
2108 <<
"Error generating preprocessed source(s) - cannot generate "
2109 "preprocessed source with multiple -arch options.";
2112 C.getArgs().eraseArg(options::OPT_arch);
2113 C.getArgs().AddJoinedArg(
nullptr,
getOpts().getOption(options::OPT_arch),
2118 if (!Inputs.empty()) {
2121 const ToolChain &TC =
C.getDefaultToolChain();
2122 if (TC.
getTriple().isOSBinFormatMachO())
2131 Diag(clang::diag::note_drv_command_failed_diag_msg)
2132 <<
"Error generating preprocessed source(s).";
2137 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2140 if (!FailingCommands.empty()) {
2141 Diag(clang::diag::note_drv_command_failed_diag_msg)
2142 <<
"Error generating preprocessed source(s).";
2146 const ArgStringList &TempFiles =
C.getTempFiles();
2147 if (TempFiles.empty()) {
2148 Diag(clang::diag::note_drv_command_failed_diag_msg)
2149 <<
"Error generating preprocessed source(s).";
2155 const ArgStringList &Files =
C.getTempFiles();
2160 for (
auto const *Input : IRInputs) {
2164 StringRef extension = llvm::sys::path::extension(Input);
2165 if (!extension.empty())
2166 extension = extension.drop_front();
2168 std::error_code EC = llvm::sys::fs::createTemporaryFile(
2169 llvm::sys::path::stem(Input), extension, FD, Path);
2171 Diag(clang::diag::note_drv_command_failed_diag_msg)
2172 <<
"Error generating run script: " <<
"Failed copying IR input files"
2173 <<
" " << EC.message();
2177 EC = llvm::sys::fs::copy_file(Input, FD);
2179 Diag(clang::diag::note_drv_command_failed_diag_msg)
2180 <<
"Error generating run script: " <<
"Failed copying IR input files"
2181 <<
" " << EC.message();
2185 TempFiles.push_back(std::string(Path.begin(), Path.end()));
2192 for (std::string &TempFile : TempFiles) {
2194 Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
2196 Report->TemporaryFiles.push_back(TempFile);
2197 if (ReproCrashFilename.empty()) {
2198 ReproCrashFilename = TempFile;
2199 llvm::sys::path::replace_extension(ReproCrashFilename,
".crash");
2201 if (StringRef(TempFile).ends_with(
".cache")) {
2204 VFS = llvm::sys::path::filename(TempFile);
2205 llvm::sys::path::append(VFS,
"vfs",
"vfs.yaml");
2209 for (
const char *TempFile : SavedTemps)
2210 TempFiles.push_back(TempFile);
2216 llvm::sys::path::replace_extension(Script,
"sh");
2218 llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::CD_CreateNew,
2219 llvm::sys::fs::FA_Write,
2220 llvm::sys::fs::OF_Text);
2222 Diag(clang::diag::note_drv_command_failed_diag_msg)
2223 <<
"Error generating run script: " << Script <<
" " << EC.message();
2226 <<
"# Driver args: ";
2228 ScriptOS <<
"# Original command: ";
2229 Cmd.
Print(ScriptOS,
"\n",
true);
2230 Cmd.
Print(ScriptOS,
"\n",
true, &CrashInfo);
2231 if (!AdditionalInformation.empty())
2232 ScriptOS <<
"\n# Additional information: " << AdditionalInformation
2235 Report->TemporaryFiles.push_back(std::string(Script));
2236 TempFiles.push_back(std::string(Script));
2239 Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
2242 if (Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_tar)) {
2243 StringRef CrashDiagnosticsTar = A->getValue();
2245 llvm::TarWriter::create(CrashDiagnosticsTar,
2246 llvm::sys::path::stem(CrashDiagnosticsTar));
2248 Diag(clang::diag::note_drv_command_failed_diag_msg)
2249 << (std::string(
"Error creating reproducer tarball: ") +
2250 llvm::toString(TarOrErr.takeError()));
2252 std::unique_ptr<llvm::TarWriter> &Tar = *TarOrErr;
2253 for (
const std::string &TempFile : TempFiles) {
2254 if (llvm::sys::fs::is_directory(TempFile)) {
2256 for (llvm::sys::fs::recursive_directory_iterator I(TempFile, EC), E;
2257 I != E && !EC; I.increment(EC)) {
2258 if (llvm::sys::fs::is_regular_file(I->path())) {
2259 auto BufferOrErr = llvm::MemoryBuffer::getFile(I->path());
2263 llvm::sys::path::filename(TempFile);
2264 StringRef SubPath = I->path();
2265 if (SubPath.consume_front(TempFile)) {
2266 if (!SubPath.empty() &&
2267 llvm::sys::path::is_separator(SubPath.front())) {
2268 SubPath = SubPath.drop_front();
2270 llvm::sys::path::append(PathInTar, SubPath);
2271 Tar->append(PathInTar, (*BufferOrErr)->getBuffer());
2274 Diag(clang::diag::note_drv_command_failed_diag_msg)
2275 << (std::string(
"Error reading file for tarball: ") +
2281 Diag(clang::diag::note_drv_command_failed_diag_msg)
2282 << (std::string(
"Error iterating directory for tarball: ") +
2283 TempFile +
" " + EC.message());
2286 auto BufferOrErr = llvm::MemoryBuffer::getFile(TempFile);
2288 Tar->append(llvm::sys::path::filename(TempFile),
2289 (*BufferOrErr)->getBuffer());
2291 Diag(clang::diag::note_drv_command_failed_diag_msg)
2292 << (std::string(
"Error reading file for tarball: ") + TempFile);
2296 Diag(clang::diag::note_drv_command_failed_diag_msg)
2297 << CrashDiagnosticsTar;
2302 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSDarwin()) {
2304 if (getCrashDiagnosticFile(ReproCrashFilename, CrashDiagDir)) {
2305 Diag(clang::diag::note_drv_command_failed_diag_msg)
2306 << ReproCrashFilename.str();
2308 llvm::sys::path::append(CrashDiagDir,
Name);
2309 CrashDiagDir +=
"_<YYYY-MM-DD-HHMMSS>_<hostname>.crash";
2310 Diag(clang::diag::note_drv_command_failed_diag_msg)
2311 <<
"Crash backtrace is located in";
2312 Diag(clang::diag::note_drv_command_failed_diag_msg)
2313 << CrashDiagDir.str();
2314 Diag(clang::diag::note_drv_command_failed_diag_msg)
2315 <<
"(choose the .crash file that corresponds to your crash)";
2319 Diag(clang::diag::note_drv_command_failed_diag_msg)
2320 <<
"\n\n********************";
2330 llvm::sys::commandLineFitsWithinSystemLimits(Cmd.
getExecutable(),
2341 if (
C.getArgs().hasArg(options::OPT_fdriver_only)) {
2342 if (
C.getArgs().hasArg(options::OPT_v))
2343 C.getJobs().Print(llvm::errs(),
"\n",
true);
2345 C.ExecuteJobs(
C.getJobs(), FailingCommands,
true);
2348 if (!FailingCommands.empty() || Diags.hasErrorOccurred())
2355 if (
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
2356 C.getJobs().Print(llvm::errs(),
"\n",
true);
2357 return Diags.hasErrorOccurred() ? 1 : 0;
2361 if (Diags.hasErrorOccurred())
2365 for (
auto &Job :
C.getJobs())
2366 setUpResponseFiles(
C, Job);
2368 C.ExecuteJobs(
C.getJobs(), FailingCommands);
2371 if (FailingCommands.empty())
2377 for (
const auto &CmdPair : FailingCommands) {
2378 int CommandRes = CmdPair.first;
2379 const Command *FailingCommand = CmdPair.second;
2384 C.CleanupFileMap(
C.getResultFiles(), JA,
true);
2388 C.CleanupFileMap(
C.getFailureResultFiles(), JA,
true);
2393 if (CommandRes == EX_IOERR) {
2413 if (CommandRes > 128 && CommandRes != 255)
2417 Diag(clang::diag::err_drv_command_signalled)
2420 Diag(clang::diag::err_drv_command_failed)
2428 llvm::opt::Visibility VisibilityMask = getOptionVisibilityMask();
2430 std::string Usage = llvm::formatv(
"{0} [options] file...",
Name).str();
2444 const ToolChain &TC =
C.getDefaultToolChain();
2448 if (Arg *A =
C.getArgs().getLastArg(options::OPT_mthread_model)) {
2451 OS <<
"Thread model: " << A->getValue();
2457 OS <<
"InstalledDir: " <<
Dir <<
'\n';
2462 if (!llvm::cl::getCompilerBuildConfig().empty())
2463 llvm::cl::printBuildConfig(OS);
2466 for (
auto ConfigFile : ConfigFiles)
2467 OS <<
"Configuration file: " << ConfigFile <<
'\n';
2480 if (PassedFlags ==
"")
2484 std::vector<std::string> SuggestedCompletions;
2485 std::vector<std::string> Flags;
2497 const bool HasSpace = PassedFlags.ends_with(
",");
2501 StringRef TargetFlags = PassedFlags;
2502 while (TargetFlags !=
"") {
2504 std::tie(CurFlag, TargetFlags) = TargetFlags.split(
",");
2505 Flags.push_back(std::string(CurFlag));
2510 if (llvm::is_contained(Flags,
"-Xclang") || llvm::is_contained(Flags,
"-cc1"))
2513 const llvm::opt::OptTable &Opts =
getOpts();
2515 Cur = Flags.at(Flags.size() - 1);
2517 if (Flags.size() >= 2) {
2518 Prev = Flags.at(Flags.size() - 2);
2519 SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur);
2522 if (SuggestedCompletions.empty())
2523 SuggestedCompletions = Opts.suggestValueCompletions(Cur,
"");
2530 if (SuggestedCompletions.empty() && HasSpace && !Flags.empty()) {
2531 llvm::outs() <<
'\n';
2537 if (SuggestedCompletions.empty() && !Cur.ends_with(
"=")) {
2541 SuggestedCompletions = Opts.findByPrefix(
2542 Cur, VisibilityMask,
2549 if (S.starts_with(Cur))
2550 SuggestedCompletions.push_back(std::string(S));
2557 llvm::sort(SuggestedCompletions, [](StringRef A, StringRef B) {
2558 if (
int X = A.compare_insensitive(B))
2560 return A.compare(B) > 0;
2563 llvm::outs() << llvm::join(SuggestedCompletions,
"\n") <<
'\n';
2570 if (
C.getArgs().hasArg(options::OPT_dumpmachine)) {
2571 llvm::outs() <<
C.getDefaultToolChain().getTripleString() <<
'\n';
2575 if (
C.getArgs().hasArg(options::OPT_dumpversion)) {
2578 llvm::outs() << CLANG_VERSION_STRING <<
"\n";
2582 if (
C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
2587 if (
C.getArgs().hasArg(options::OPT_help) ||
2588 C.getArgs().hasArg(options::OPT__help_hidden)) {
2589 PrintHelp(
C.getArgs().hasArg(options::OPT__help_hidden));
2593 if (
C.getArgs().hasArg(options::OPT__version)) {
2600 bool ListExtractors =
C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
2601 bool ListFormats =
C.getArgs().hasArg(options::OPT__ssaf_list_formats);
2602 if (ListExtractors || ListFormats) {
2610 if (
C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
2615 if (
C.getArgs().hasArg(options::OPT_v) ||
2616 C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
2617 C.getArgs().hasArg(options::OPT_print_supported_cpus) ||
2618 C.getArgs().hasArg(options::OPT_print_supported_extensions) ||
2619 C.getArgs().hasArg(options::OPT_print_enabled_extensions)) {
2621 SuppressMissingInputWarning =
true;
2624 if (
C.getArgs().hasArg(options::OPT_v)) {
2626 llvm::errs() <<
"System configuration file directory: "
2629 llvm::errs() <<
"User configuration file directory: "
2633 const ToolChain &TC =
C.getDefaultToolChain();
2635 if (
C.getArgs().hasArg(options::OPT_v))
2638 if (
C.getArgs().hasArg(options::OPT_print_resource_dir)) {
2643 if (
C.getArgs().hasArg(options::OPT_print_search_dirs)) {
2644 llvm::outs() <<
"programs: =";
2645 bool separator =
false;
2649 llvm::outs() << llvm::sys::EnvPathSeparator;
2650 llvm::outs() << Path;
2655 llvm::outs() << llvm::sys::EnvPathSeparator;
2656 llvm::outs() << Path;
2659 llvm::outs() <<
"\n";
2662 StringRef sysroot =
C.getSysRoot();
2666 llvm::outs() << llvm::sys::EnvPathSeparator;
2669 llvm::outs() << sysroot << Path.substr(1);
2671 llvm::outs() << Path;
2673 llvm::outs() <<
"\n";
2677 if (
C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) {
2683 if (
C.getArgs().hasArg(options::OPT_print_runtime_dir)) {
2684 for (
auto RuntimePath :
2686 if (RuntimePath &&
getVFS().exists(*RuntimePath)) {
2687 llvm::outs() << *RuntimePath <<
'\n';
2691 llvm::outs() <<
"(runtime dir is not present)" <<
'\n';
2695 if (
C.getArgs().hasArg(options::OPT_print_diagnostic_options)) {
2697 for (std::size_t I = 0; I != Flags.size(); I += 2)
2698 llvm::outs() <<
" " << Flags[I] <<
"\n " << Flags[I + 1] <<
"\n\n";
2704 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_file_name_EQ)) {
2705 llvm::outs() <<
GetFilePath(A->getValue(), TC) <<
"\n";
2709 if (Arg *A =
C.getArgs().getLastArg(options::OPT_print_prog_name_EQ)) {
2710 StringRef ProgName = A->getValue();
2713 if (! ProgName.empty())
2716 llvm::outs() <<
"\n";
2720 if (Arg *A =
C.getArgs().getLastArg(options::OPT_autocomplete)) {
2721 StringRef PassedFlags = A->getValue();
2726 if (
C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
2736 C.getArgsForToolChain(&TC,
BoundArch(Triple.getArchName()),
2741 llvm::outs() << TC.
getCompilerRT(
C.getArgs(),
"builtins") <<
"\n";
2744 llvm::outs() <<
GetFilePath(
"libgcc.a", TC) <<
"\n";
2750 if (
C.getArgs().hasArg(options::OPT_print_multi_lib)) {
2757 if (
C.getArgs().hasArg(options::OPT_print_multi_flags)) {
2760 std::set<llvm::StringRef> SortedFlags;
2761 for (
const auto &FlagEntry : ExpandedFlags)
2762 SortedFlags.insert(FlagEntry.getKey());
2763 for (
auto Flag : SortedFlags)
2764 llvm::outs() << Flag <<
'\n';
2768 if (
C.getArgs().hasArg(options::OPT_print_multi_directory)) {
2771 llvm::outs() <<
".\n";
2774 assert(Suffix.front() ==
'/');
2775 llvm::outs() << Suffix.substr(1) <<
"\n";
2781 if (
C.getArgs().hasArg(options::OPT_print_target_triple)) {
2786 if (
C.getArgs().hasArg(options::OPT_print_effective_triple)) {
2788 llvm::outs() << Triple.getTriple() <<
"\n";
2792 if (
C.getArgs().hasArg(options::OPT_print_targets)) {
2793 llvm::TargetRegistry::printRegisteredTargetsForVersion(llvm::outs());
2810 std::map<Action *, unsigned> &Ids,
2812 if (
auto It = Ids.find(A); It != Ids.end())
2816 llvm::raw_string_ostream os(str);
2818 auto getSibIndent = [](
int K) -> Twine {
2822 Twine SibIndent =
Indent + getSibIndent(Kind);
2826 os <<
"\"" << IA->getInputArg().getValue() <<
"\"";
2828 os <<
'"' << BIA->getArch().ArchName <<
'"' <<
", {"
2829 <<
PrintActions1(
C, *BIA->input_begin(), Ids, SibIndent, SibKind) <<
"}";
2830 }
else if (
OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
2832 OA->doOnEachDependence([&](
Action *A,
const ToolChain *TC, BoundArch BA) {
2833 assert(TC &&
"Unknown host toolchain");
2848 os <<
" {" <<
PrintActions1(
C, A, Ids, SibIndent, SibKind) <<
"}";
2856 const char *Prefix =
"{";
2857 for (
Action *PreRequisite : *AL) {
2858 os << Prefix <<
PrintActions1(
C, PreRequisite, Ids, SibIndent, SibKind);
2869 std::string offload_str;
2870 llvm::raw_string_ostream offload_os(offload_str);
2874 offload_os <<
", (" << S;
2881 auto getSelfIndent = [](
int K) -> Twine {
2885 unsigned Id = Ids.size();
2887 llvm::errs() <<
Indent + getSelfIndent(Kind) << Id <<
": " << os.str() <<
", "
2896 std::map<Action *, unsigned> Ids;
2897 for (
Action *A :
C.getActions())
2913 DerivedArgList &Args =
C.getArgs();
2915 llvm::PrettyStackTraceString CrashInfo(
"Building universal build actions");
2920 for (Arg *A : Args) {
2921 if (A->getOption().matches(options::OPT_arch)) {
2924 llvm::Triple::ArchType
Arch =
2926 if (
Arch == llvm::Triple::UnknownArch) {
2927 Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
2932 if (
ArchNames.insert(A->getValue()).second)
2933 Archs.push_back(A->getValue());
2947 for (
Action* Act : SingleActions) {
2955 Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
2959 for (
unsigned i = 0, e = Archs.size(); i != e; ++i)
2964 if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
2965 Actions.append(Inputs.begin(), Inputs.end());
2967 Actions.push_back(
C.MakeAction<
LipoJobAction>(Inputs, Act->getType()));
2970 Arg *A = Args.getLastArg(options::OPT_g_Group);
2971 bool enablesDebugInfo = A && !A->getOption().matches(options::OPT_g0) &&
2972 !A->getOption().matches(options::OPT_gstabs);
2973 bool enablesPseudoProbe =
2974 Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
2975 options::OPT_fno_pseudo_probe_for_profiling,
false);
2976 bool enablesDebugInfoForProfiling =
2977 Args.hasFlag(options::OPT_fdebug_info_for_profiling,
2978 options::OPT_fno_debug_info_for_profiling,
false);
2979 if ((enablesDebugInfo ||
willEmitRemarks(Args) || enablesPseudoProbe ||
2980 enablesDebugInfoForProfiling) &&
2988 if (Act->getType() == types::TY_Image) {
2990 Inputs.push_back(Actions.back());
2997 if (Args.hasArg(options::OPT_verify_debug_info)) {
2998 Action *LastAction = Actions.pop_back_val();
3000 LastAction, types::TY_Nothing));
3007 bool TypoCorrect)
const {
3019 if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader ||
3020 (ModulesModeCXX20 && Ty == types::TY_CXXHeader))
3032 std::string Nearest;
3033 if (
getOpts().findNearest(
Value, Nearest, getOptionVisibilityMask()) <= 1) {
3034 Diag(clang::diag::err_drv_no_such_file_with_suggestion)
3035 <<
Value << Nearest;
3074 if (
IsCLMode() && Ty == types::TY_Object && !
Value.starts_with(
"/"))
3077 Diag(clang::diag::err_drv_no_such_file) <<
Value;
3085 return types::TY_CXXUHeader;
3087 return types::TY_CXXSHeader;
3091 llvm_unreachable(
"should not be called in this case");
3093 return types::TY_CXXHUHeader;
3099 const llvm::opt::OptTable &Opts =
getOpts();
3103 types::ID InputType = types::TY_Nothing;
3104 Arg *InputTypeArg =
nullptr;
3107 if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
3108 options::OPT__SLASH_TP)) {
3109 InputTypeArg = TCTP;
3110 InputType = TCTP->getOption().matches(options::OPT__SLASH_TC)
3115 bool ShowNote =
false;
3117 Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
3119 Diag(clang::diag::warn_drv_overriding_option)
3120 <<
Previous->getSpelling() << A->getSpelling();
3126 Diag(clang::diag::note_drv_t_option_is_global);
3131 Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
3132 Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
3133 if (LastXArg && LastInputArg &&
3134 LastInputArg->getIndex() < LastXArg->getIndex())
3135 Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue();
3138 bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false);
3140 for (Arg *A : Args) {
3141 if (A->getOption().
getKind() == Option::InputClass) {
3142 const char *
Value = A->getValue();
3146 if (InputType == types::TY_Nothing) {
3149 InputTypeArg->claim();
3152 if (strcmp(
Value,
"-") == 0) {
3154 Ty = types::TY_Fortran;
3156 Ty = types::TY_HLSL;
3157 }
else if (IsSYCL) {
3167 if (!Args.hasArgNoClaim(options::OPT_E) && !
CCCIsCPP())
3168 Diag(
IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
3169 : clang::diag::err_drv_unknown_stdin_type);
3178 if (
const char *Ext = strrchr(
Value,
'.'))
3187 Ty = types::TY_HLSL;
3189 Ty = types::TY_Object;
3200 if (Ty != OldTy && !(OldTy == types::TY_CHeader &&
hasHeaderMode()))
3201 Diag(clang::diag::warn_drv_treating_input_as_cxx)
3202 << getTypeName(OldTy) << getTypeName(Ty);
3207 if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) &&
3208 Ty == types::TY_Object)
3209 Ty = types::TY_LLVM_BC;
3217 if (Ty != types::TY_Object) {
3218 if (Args.hasArg(options::OPT_ObjC))
3219 Ty = types::TY_ObjC;
3220 else if (Args.hasArg(options::OPT_ObjCXX))
3221 Ty = types::TY_ObjCXX;
3228 if ((Ty == types::TY_CXXHeader || Ty == types::TY_CHeader) &&
3232 assert(InputTypeArg &&
"InputType set w/o InputTypeArg");
3233 if (!InputTypeArg->getOption().matches(options::OPT_x)) {
3236 const char *Ext = strrchr(
Value,
'.');
3238 Ty = types::TY_Object;
3242 InputTypeArg->claim();
3246 if ((Ty == types::TY_C || Ty == types::TY_CXX) &&
3247 Args.hasArgNoClaim(options::OPT_hipstdpar))
3251 Inputs.push_back(std::make_pair(Ty, A));
3253 }
else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
3254 StringRef
Value = A->getValue();
3257 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3258 Inputs.push_back(std::make_pair(types::TY_C, InputArg));
3261 }
else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
3262 StringRef
Value = A->getValue();
3265 Arg *InputArg =
makeInputArg(Args, Opts, A->getValue());
3266 Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
3272 Inputs.push_back(std::make_pair(types::TY_Object, A));
3274 }
else if (A->getOption().matches(options::OPT_x)) {
3283 Diag(clang::diag::err_drv_unknown_language) << A->getValue();
3284 InputType = types::TY_Object;
3291 }
else if (A->getOption().getID() == options::OPT_U) {
3292 assert(A->getNumValues() == 1 &&
"The /U option has one value.");
3293 StringRef Val = A->getValue(0);
3294 if (Val.find_first_of(
"/\\") != StringRef::npos) {
3296 Diag(diag::warn_slash_u_filename) << Val;
3297 Diag(diag::note_use_dashdash);
3301 if (
CCCIsCPP() && Inputs.empty()) {
3305 Inputs.push_back(std::make_pair(types::TY_C, A));
3312class OffloadingActionBuilder final {
3314 bool IsValid =
false;
3320 std::map<const Arg *, unsigned> InputArgToOffloadKindMap;
3323 std::map<Action *, const Arg *> HostActionToInputArgMap;
3326 class DeviceActionBuilder {
3330 enum ActionBuilderReturnCode {
3348 const ToolChain *FatBinaryToolChain =
nullptr;
3351 DerivedArgList &Args;
3360 DeviceActionBuilder(
Compilation &
C, DerivedArgList &Args,
3363 :
C(
C), Args(Args), Inputs(Inputs),
3364 AssociatedOffloadKind(AssociatedOffloadKind) {}
3365 virtual ~DeviceActionBuilder() {}
3370 virtual ActionBuilderReturnCode
3371 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3374 return ABRT_Inactive;
3379 virtual ActionBuilderReturnCode addDeviceDependences(Action *HostAction) {
3380 return ABRT_Inactive;
3384 virtual void appendTopLevelActions(
ActionList &AL) {}
3387 virtual void appendLinkDeviceActions(
ActionList &AL) {}
3390 virtual Action* appendLinkHostActions(
ActionList &AL) {
return nullptr; }
3393 virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {}
3397 virtual bool initialize() {
return false; }
3400 virtual bool canUseBundlerUnbundler()
const {
return false; }
3404 bool isValid() {
return !ToolChains.empty(); }
3408 return AssociatedOffloadKind;
3414 class CudaActionBuilderBase :
public DeviceActionBuilder {
3418 bool CompileHostOnly =
false;
3419 bool CompileDeviceOnly =
false;
3421 bool EmitAsm =
false;
3424 SmallVector<BoundArch, 4> GpuArchList;
3430 Action *CudaFatBinary =
nullptr;
3433 bool IsActive =
false;
3436 bool Relocatable =
false;
3439 OffloadArch DefaultOffloadArch = OffloadArch::Unknown;
3442 const CUIDOptions &CUIDOpts;
3445 CudaActionBuilderBase(Compilation &
C, DerivedArgList &Args,
3447 : DeviceActionBuilder(
C, Args, Inputs, OFKind),
3448 CUIDOpts(
C.getDriver().getCUIDOpts()) {
3450 CompileDeviceOnly =
C.getDriver().offloadDeviceOnly();
3451 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
3452 options::OPT_fno_gpu_rdc,
false);
3455 ActionBuilderReturnCode addDeviceDependences(Action *HostAction)
override {
3462 if (
auto *IA = dyn_cast<InputAction>(HostAction)) {
3465 if (!(IA->getType() == types::TY_CUDA ||
3466 IA->getType() == types::TY_HIP ||
3467 IA->getType() == types::TY_PP_HIP)) {
3470 return ABRT_Inactive;
3477 IA->setId(CUIDOpts.
getCUID(IA->getInputArg().getValue(), Args));
3479 if (CompileHostOnly)
3480 return ABRT_Success;
3483 auto Ty = IA->getType() == types::TY_HIP ? types::TY_HIP_DEVICE
3484 : types::TY_CUDA_DEVICE;
3485 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3486 CudaDeviceActions.push_back(
3487 C.MakeAction<InputAction>(IA->getInputArg(), Ty, IA->getId()));
3490 return ABRT_Success;
3494 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
3498 if (UA->getType() == types::TY_Object && !Relocatable)
3499 return ABRT_Inactive;
3501 CudaDeviceActions.clear();
3503 std::string
FileName = IA->getInputArg().getAsString(Args);
3509 const StringRef LibFileExt =
".lib";
3510 if (IA->getType() == types::TY_Object &&
3511 (!llvm::sys::path::has_extension(
FileName) ||
3513 llvm::sys::path::extension(
FileName).drop_front()) !=
3515 llvm::sys::path::extension(
FileName) == LibFileExt))
3516 return ABRT_Inactive;
3518 for (
auto [
Arch, ToolChain] : llvm::zip(GpuArchList, ToolChains)) {
3519 CudaDeviceActions.push_back(UA);
3520 UA->registerDependentActionInfo(ToolChain,
Arch,
3521 AssociatedOffloadKind);
3524 return ABRT_Success;
3527 return IsActive ? ABRT_Success : ABRT_Inactive;
3530 void appendTopLevelActions(
ActionList &AL)
override {
3532 auto AddTopLevel = [&](Action *A, BoundArch BA,
const ToolChain *TC) {
3533 OffloadAction::DeviceDependences Dep;
3534 Dep.
add(*A, *TC, BA, AssociatedOffloadKind);
3535 AL.push_back(
C.MakeAction<OffloadAction>(Dep, A->
getType()));
3539 if (CudaFatBinary) {
3540 AddTopLevel(CudaFatBinary, {}, FatBinaryToolChain);
3541 CudaDeviceActions.clear();
3542 CudaFatBinary =
nullptr;
3546 if (CudaDeviceActions.empty())
3552 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3553 "Expecting one action per GPU architecture.");
3554 assert(ToolChains.size() == GpuArchList.size() &&
3555 "Expecting to have a toolchain per GPU architecture");
3556 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I)
3557 AddTopLevel(CudaDeviceActions[I], GpuArchList[I], ToolChains[I]);
3559 CudaDeviceActions.clear();
3562 bool initialize()
override {
3577 assert(HostTC &&
"No toolchain for host compilation.");
3582 C.getDriver().Diag(diag::err_drv_cuda_host_arch)
3587 std::set<std::pair<BoundArch, const ToolChain *>> GpuArchs;
3589 for (
auto &I : llvm::make_range(
C.getOffloadToolChains(Kind))) {
3591 C.getDriver().getOffloadArchs(
C,
C.getArgs(), Kind, *I.second))
3592 GpuArchs.insert({
Arch, I.second});
3596 for (
auto [
Arch, TC] : GpuArchs) {
3597 GpuArchList.push_back(
Arch);
3598 ToolChains.push_back(TC);
3601 FatBinaryToolChain = ToolChains.front();
3602 CompileHostOnly =
C.getDriver().offloadHostOnly();
3603 EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
3604 EmitAsm = Args.getLastArg(options::OPT_S);
3612 class CudaActionBuilder final :
public CudaActionBuilderBase {
3614 CudaActionBuilder(Compilation &
C, DerivedArgList &Args,
3616 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_Cuda) {
3617 DefaultOffloadArch = OffloadArch::CudaDefault;
3620 ActionBuilderReturnCode
3621 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3623 PhasesTy &Phases)
override {
3625 return ABRT_Inactive;
3629 if (CudaDeviceActions.empty())
3630 return ABRT_Success;
3632 assert(CudaDeviceActions.size() == GpuArchList.size() &&
3633 "Expecting one action per GPU architecture.");
3634 assert(!CompileHostOnly &&
3635 "Not expecting CUDA actions in host-only compilation.");
3645 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3648 for (
auto Ph : Phases) {
3653 if (Ph > FinalPhase)
3656 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3671 Action *AssembleAction = CudaDeviceActions[I];
3672 assert(AssembleAction->
getType() == types::TY_Object);
3673 assert(AssembleAction->
getInputs().size() == 1);
3679 OffloadAction::DeviceDependences DDep;
3681 DeviceActions.push_back(
3682 C.MakeAction<OffloadAction>(DDep, A->
getType()));
3687 if (!DeviceActions.empty()) {
3689 C.MakeAction<LinkJobAction>(DeviceActions, types::TY_CUDA_FATBIN);
3691 if (!CompileDeviceOnly) {
3692 DA.
add(*CudaFatBinary, *FatBinaryToolChain, {},
3696 CudaFatBinary =
nullptr;
3701 CudaDeviceActions.clear();
3705 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3710 return ABRT_Success;
3714 "instructions should only occur "
3715 "before the backend phase!");
3718 for (Action *&A : CudaDeviceActions)
3719 A =
C.getDriver().ConstructPhaseAction(
C, Args, CurPhase, A);
3721 return ABRT_Success;
3726 class HIPActionBuilder final :
public CudaActionBuilderBase {
3728 SmallVector<ActionList, 8> DeviceLinkerInputs;
3734 std::optional<bool> BundleOutput;
3735 std::optional<bool> EmitReloc;
3738 HIPActionBuilder(Compilation &
C, DerivedArgList &Args,
3740 : CudaActionBuilderBase(
C, Args, Inputs, Action::OFK_HIP) {
3742 DefaultOffloadArch = OffloadArch::HIPDefault;
3744 if (Args.hasArg(options::OPT_fhip_emit_relocatable,
3745 options::OPT_fno_hip_emit_relocatable)) {
3746 EmitReloc = Args.hasFlag(options::OPT_fhip_emit_relocatable,
3747 options::OPT_fno_hip_emit_relocatable, false);
3751 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
3752 <<
"-fhip-emit-relocatable"
3756 if (!CompileDeviceOnly) {
3757 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
3758 <<
"-fhip-emit-relocatable"
3759 <<
"--offload-device-only";
3764 if (Args.hasArg(options::OPT_gpu_bundle_output,
3765 options::OPT_no_gpu_bundle_output))
3766 BundleOutput = Args.hasFlag(options::OPT_gpu_bundle_output,
3767 options::OPT_no_gpu_bundle_output,
true) &&
3768 (!EmitReloc || !*EmitReloc);
3771 bool canUseBundlerUnbundler()
const override {
return true; }
3773 ActionBuilderReturnCode
3774 getDeviceDependences(OffloadAction::DeviceDependences &DA,
3776 PhasesTy &Phases)
override {
3778 return ABRT_Inactive;
3784 if (CudaDeviceActions.empty())
3785 return ABRT_Success;
3788 CudaDeviceActions.size() == GpuArchList.size()) &&
3789 "Expecting one action per GPU architecture.");
3790 assert(!CompileHostOnly &&
3791 "Not expecting HIP actions in host-only compilation.");
3793 bool ShouldLink = !EmitReloc || !*EmitReloc;
3796 !EmitAsm && ShouldLink) {
3802 bool ExplicitOffloadLTO = Args.hasArg(options::OPT_foffload_lto,
3803 options::OPT_foffload_lto_EQ);
3804 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3805 if (ExplicitOffloadLTO &&
3806 ToolChains[I]->isUsingLTO(Args, AssociatedOffloadKind)) {
3810 AL.push_back(CudaDeviceActions[I]);
3813 CudaDeviceActions[I] =
3814 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3820 if (ToolChains[I]->
getTriple().isSPIRV() ||
3821 (ToolChains[I]->
getTriple().isAMDGCN() &&
3822 GpuArchList[I].ArchName == StringRef(
"amdgcnspirv"))) {
3826 types::ID Output = Args.hasArg(options::OPT_S)
3828 : types::TY_LLVM_BC;
3830 C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
3836 auto AssembleAction =
C.getDriver().ConstructPhaseAction(
3838 AssociatedOffloadKind);
3839 AL.push_back(AssembleAction);
3842 CudaDeviceActions[I] =
3843 C.MakeAction<LinkJobAction>(AL, types::TY_Image);
3852 OffloadAction::DeviceDependences DDep;
3853 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3854 AssociatedOffloadKind);
3855 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3856 DDep, CudaDeviceActions[I]->getType());
3859 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3861 CudaFatBinary =
C.MakeAction<LinkJobAction>(CudaDeviceActions,
3862 types::TY_HIP_FATBIN);
3864 if (!CompileDeviceOnly) {
3865 DA.
add(*CudaFatBinary, *FatBinaryToolChain, {},
3866 AssociatedOffloadKind);
3869 CudaFatBinary =
nullptr;
3874 CudaDeviceActions.clear();
3877 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3880 return ABRT_Success;
3886 DeviceLinkerInputs.resize(CudaDeviceActions.
size());
3887 auto LI = DeviceLinkerInputs.begin();
3888 for (
auto *A : CudaDeviceActions) {
3895 CudaDeviceActions.clear();
3896 return CompileDeviceOnly ? ABRT_Ignore_Host : ABRT_Success;
3900 for (
unsigned I = 0, E = CudaDeviceActions.size(); I != E; ++I)
3901 CudaDeviceActions[I] =
C.getDriver().ConstructPhaseAction(
3902 C, Args, CurPhase, CudaDeviceActions[I], AssociatedOffloadKind,
3903 ToolChains[I]->getLTOMode(Args, AssociatedOffloadKind));
3905 if (CompileDeviceOnly && CurPhase == FinalPhase && BundleOutput &&
3907 for (
unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
3908 OffloadAction::DeviceDependences DDep;
3909 DDep.
add(*CudaDeviceActions[I], *ToolChains[I], GpuArchList[I],
3910 AssociatedOffloadKind);
3911 CudaDeviceActions[I] =
C.MakeAction<OffloadAction>(
3912 DDep, CudaDeviceActions[I]->getType());
3915 C.MakeAction<OffloadBundlingJobAction>(CudaDeviceActions);
3916 CudaDeviceActions.clear();
3919 return (CompileDeviceOnly &&
3920 (CurPhase == FinalPhase ||
3926 void appendLinkDeviceActions(
ActionList &AL)
override {
3927 if (DeviceLinkerInputs.size() == 0)
3930 assert(DeviceLinkerInputs.size() == GpuArchList.size() &&
3931 "Linker inputs and GPU arch list sizes do not match.");
3937 for (
auto &LI : DeviceLinkerInputs) {
3939 types::ID Output = Args.hasArg(options::OPT_emit_llvm)
3943 auto *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LI, Output);
3946 OffloadAction::DeviceDependences DeviceLinkDeps;
3947 DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[I], GpuArchList[I],
3948 AssociatedOffloadKind);
3949 Actions.push_back(
C.MakeAction<OffloadAction>(
3950 DeviceLinkDeps, DeviceLinkAction->getType()));
3953 DeviceLinkerInputs.clear();
3956 if (Args.hasArg(options::OPT_emit_llvm)) {
3964 OffloadAction::DeviceDependences DDeps;
3965 if (!CompileDeviceOnly || !BundleOutput || *BundleOutput) {
3966 auto *TopDeviceLinkAction =
C.MakeAction<LinkJobAction>(
3968 CompileDeviceOnly ? types::TY_HIP_FATBIN : types::TY_Object);
3969 DDeps.
add(*TopDeviceLinkAction, *FatBinaryToolChain, {},
3970 AssociatedOffloadKind);
3973 C.MakeAction<OffloadAction>(DDeps, TopDeviceLinkAction->getType()));
3979 Action* appendLinkHostActions(
ActionList &AL)
override {
return AL.back(); }
3981 void appendLinkDependences(OffloadAction::DeviceDependences &DA)
override {}
3989 SmallVector<DeviceActionBuilder *, 4> SpecializedBuilders;
3995 bool ShouldUseBundler;
3998 OffloadingActionBuilder(
Compilation &
C, DerivedArgList &Args,
4006 SpecializedBuilders.push_back(
new CudaActionBuilder(
C, Args, Inputs));
4009 SpecializedBuilders.push_back(
new HIPActionBuilder(
C, Args, Inputs));
4017 unsigned ValidBuilders = 0u;
4018 unsigned ValidBuildersSupportingBundling = 0u;
4019 for (
auto *SB : SpecializedBuilders) {
4020 IsValid = IsValid && !SB->initialize();
4023 if (SB->isValid()) {
4025 if (SB->canUseBundlerUnbundler())
4026 ++ValidBuildersSupportingBundling;
4030 ValidBuilders && ValidBuilders == ValidBuildersSupportingBundling;
4032 ShouldUseBundler = Args.hasFlag(options::OPT_gpu_bundle_output,
4033 options::OPT_no_gpu_bundle_output,
true);
4036 ~OffloadingActionBuilder() {
4037 for (
auto *SB : SpecializedBuilders)
4042 void recordHostAction(
Action *HostAction,
const Arg *InputArg) {
4043 assert(HostAction &&
"Invalid host action");
4044 assert(InputArg &&
"Invalid input argument");
4045 auto Loc = HostActionToInputArgMap.try_emplace(HostAction, InputArg).first;
4046 assert(Loc->second == InputArg &&
4047 "host action mapped to multiple input arguments");
4056 addDeviceDependencesToHostAction(
Action *HostAction,
const Arg *InputArg,
4058 DeviceActionBuilder::PhasesTy &Phases) {
4062 if (SpecializedBuilders.empty())
4065 assert(HostAction &&
"Invalid host action!");
4066 recordHostAction(HostAction, InputArg);
4071 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4072 unsigned InactiveBuilders = 0u;
4073 unsigned IgnoringBuilders = 0u;
4074 for (
auto *SB : SpecializedBuilders) {
4075 if (!SB->isValid()) {
4080 SB->getDeviceDependences(DDeps, CurPhase, FinalPhase, Phases);
4085 if (RetCode == DeviceActionBuilder::ABRT_Ignore_Host)
4090 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4091 OffloadKind |= SB->getAssociatedOffloadKind();
4096 if (IgnoringBuilders &&
4097 SpecializedBuilders.size() == (InactiveBuilders + IgnoringBuilders))
4114 bool addHostDependenceToDeviceActions(
Action *&HostAction,
4115 const Arg *InputArg) {
4119 recordHostAction(HostAction, InputArg);
4128 InputArg->getOption().getKind() == llvm::opt::Option::InputClass &&
4130 HostAction->
getType() == types::TY_PP_HIP)) {
4131 auto UnbundlingHostAction =
4136 HostAction = UnbundlingHostAction;
4137 recordHostAction(HostAction, InputArg);
4140 assert(HostAction &&
"Invalid host action!");
4143 auto &OffloadKind = InputArgToOffloadKindMap[InputArg];
4144 for (
auto *SB : SpecializedBuilders) {
4148 auto RetCode = SB->addDeviceDependences(HostAction);
4152 assert(RetCode != DeviceActionBuilder::ABRT_Ignore_Host &&
4153 "Host dependence not expected to be ignored.!");
4157 if (RetCode != DeviceActionBuilder::ABRT_Inactive)
4158 OffloadKind |= SB->getAssociatedOffloadKind();
4163 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction))
4173 const Arg *InputArg) {
4175 recordHostAction(HostAction, InputArg);
4179 for (
auto *SB : SpecializedBuilders) {
4182 SB->appendTopLevelActions(OffloadAL);
4189 if (CanUseBundler && ShouldUseBundler && HostAction &&
4190 HostAction->
getType() != types::TY_Nothing && !OffloadAL.empty()) {
4192 OffloadAL.push_back(HostAction);
4196 assert(HostAction == AL.back() &&
"Host action not in the list??");
4198 recordHostAction(HostAction, InputArg);
4199 AL.back() = HostAction;
4201 AL.append(OffloadAL.begin(), OffloadAL.end());
4211 void appendDeviceLinkActions(
ActionList &AL) {
4212 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4215 SB->appendLinkDeviceActions(AL);
4219 Action *makeHostLinkAction() {
4222 appendDeviceLinkActions(DeviceAL);
4223 if (DeviceAL.empty())
4228 for (DeviceActionBuilder *SB : SpecializedBuilders) {
4231 HA = SB->appendLinkHostActions(DeviceAL);
4248 for (
auto *SB : SpecializedBuilders) {
4252 SB->appendLinkDependences(DDeps);
4256 unsigned ActiveOffloadKinds = 0u;
4257 for (
auto &I : InputArgToOffloadKindMap)
4258 ActiveOffloadKinds |= I.second;
4270 for (
auto *A : HostAction->
inputs()) {
4271 auto ArgLoc = HostActionToInputArgMap.find(A);
4272 if (ArgLoc == HostActionToInputArgMap.end())
4274 auto OFKLoc = InputArgToOffloadKindMap.find(ArgLoc->second);
4275 if (OFKLoc == InputArgToOffloadKindMap.end())
4287 {}, ActiveOffloadKinds);
4293void Driver::handleArguments(
Compilation &
C, DerivedArgList &Args,
4298 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fo)) {
4299 StringRef
V = A->getValue();
4300 if (Inputs.size() > 1 && !
V.empty() &&
4301 !llvm::sys::path::is_separator(
V.back())) {
4303 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4304 << A->getSpelling() <<
V;
4305 Args.eraseArg(options::OPT__SLASH_Fo);
4310 if (Arg *A = Args.getLastArg(options::OPT__SLASH_Fa)) {
4311 StringRef
V = A->getValue();
4312 if (Inputs.size() > 1 && !
V.empty() &&
4313 !llvm::sys::path::is_separator(
V.back())) {
4315 Diag(clang::diag::err_drv_out_file_argument_with_multiple_sources)
4316 << A->getSpelling() <<
V;
4317 Args.eraseArg(options::OPT__SLASH_Fa);
4322 if (Arg *A = Args.getLastArg(options::OPT__SLASH_o)) {
4323 if (A->getValue()[0] ==
'\0') {
4325 Diag(clang::diag::err_drv_missing_argument) << A->getSpelling() << 1;
4326 Args.eraseArg(options::OPT__SLASH_o);
4331 Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
4332 Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
4333 if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
4334 Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
4335 Args.eraseArg(options::OPT__SLASH_Yc);
4336 Args.eraseArg(options::OPT__SLASH_Yu);
4337 YcArg = YuArg =
nullptr;
4339 if (YcArg && Inputs.size() > 1) {
4340 Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
4341 Args.eraseArg(options::OPT__SLASH_Yc);
4349 if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
4350 Args.AddFlagArg(
nullptr,
getOpts().getOption(options::OPT_hip_link));
4351 Args.AddFlagArg(
nullptr,
4352 getOpts().getOption(options::OPT_frtlib_add_rpath));
4356 if (Args.hasArg(options::OPT_emit_llvm) &&
4357 !Args.hasArg(options::OPT_hip_link) &&
4358 !
C.getDefaultToolChain().getTriple().isSPIRV())
4359 Diag(clang::diag::err_drv_emit_llvm_link);
4360 if (
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment() &&
4361 C.getDefaultToolChain().isUsingLTO(Args) &&
4362 !Args.getLastArgValue(options::OPT_fuse_ld_EQ)
4363 .starts_with_insensitive(
"lld"))
4364 Diag(clang::diag::err_drv_lto_without_lld);
4370 if (!Args.hasArg(options::OPT_dumpdir)) {
4371 Arg *FinalOutput = Args.getLastArg(options::OPT_o, options::OPT__SLASH_o);
4372 Arg *Arg = Args.MakeSeparateArg(
4373 nullptr,
getOpts().getOption(options::OPT_dumpdir),
4375 (FinalOutput ? FinalOutput->getValue()
4387 Args.eraseArg(options::OPT__SLASH_Fp);
4388 Args.eraseArg(options::OPT__SLASH_Yc);
4389 Args.eraseArg(options::OPT__SLASH_Yu);
4390 YcArg = YuArg =
nullptr;
4393 if (Args.hasArg(options::OPT_include_pch) &&
4394 Args.hasArg(options::OPT_ignore_pch)) {
4398 Args.eraseArg(options::OPT_include_pch);
4401 bool LinkOnly =
phases::Link == FinalPhase && Inputs.size() > 0;
4402 for (
auto &I : Inputs) {
4404 const Arg *InputArg = I.second;
4409 LinkOnly = LinkOnly &&
phases::Link == InitialPhase && PL.size() == 1;
4413 if (InitialPhase > FinalPhase) {
4414 if (InputArg->isClaimed())
4421 if (Args.hasArg(options::OPT_Qunused_arguments))
4427 Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
4428 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase);
4432 (Args.getLastArg(options::OPT__SLASH_EP,
4433 options::OPT__SLASH_P) ||
4434 Args.getLastArg(options::OPT_E) ||
4435 Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
4437 Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
4438 << InputArg->getAsString(Args) << !!FinalPhaseArg
4439 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4441 Diag(clang::diag::warn_drv_input_file_unused)
4442 << InputArg->getAsString(Args) <<
getPhaseName(InitialPhase)
4444 << (FinalPhaseArg ? FinalPhaseArg->getOption().
getName() :
"");
4453 Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg,
HeaderType);
4454 auto HostLTO =
C.getDefaultToolChain().getLTOMode(Args);
4459 Actions.push_back(ClangClPch);
4471 Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
4472 Args.ClaimAllArgs(options::OPT_cl_compile_Group);
4481 const llvm::opt::DerivedArgList &Args,
4484 !Args.hasArg(options::OPT_S) || Args.hasArg(options::OPT_emit_llvm) ||
4486 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false))
4489 bool HasAMDGCNHIPDevice =
false;
4491 for (
auto It = HIPTCs.first; It != HIPTCs.second; ++It) {
4493 const llvm::Triple &Tr = TC->
getTriple();
4496 HasAMDGCNHIPDevice =
true;
4498 return HasAMDGCNHIPDevice;
4503 llvm::PrettyStackTraceString CrashInfo(
"Building compilation actions");
4505 if (!SuppressMissingInputWarning && Inputs.empty()) {
4506 Diag(clang::diag::err_drv_no_input_files);
4510 handleArguments(
C, Args, Inputs, Actions);
4512 bool UseNewOffloadingDriver = Args.hasFlag(
4513 options::OPT_offload_new_driver, options::OPT_no_offload_new_driver,
4517 std::unique_ptr<OffloadingActionBuilder> OffloadBuilder =
4518 !UseNewOffloadingDriver
4519 ? std::make_unique<OffloadingActionBuilder>(
C, Args, Inputs)
4527 for (
auto &I : Inputs) {
4529 const Arg *InputArg = I.second;
4542 CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4550 if (!UseNewOffloadingDriver)
4551 if (OffloadBuilder->addHostDependenceToDeviceActions(Current, InputArg))
4557 if (!UseNewOffloadingDriver)
4558 Current = OffloadBuilder->addDeviceDependencesToHostAction(
4559 Current, InputArg, Phase, PL.back(), FullPL);
4565 assert(Phase == PL.back() &&
"linking must be final compilation step.");
4568 if (!(
C.getInputArgs().hasArg(options::OPT_hip_link) &&
4569 (
C.getInputArgs().hasArg(options::OPT_emit_llvm))) &&
4571 LinkerInputs.push_back(Current);
4581 assert(Phase == PL.back() &&
"merging must be final compilation step.");
4582 MergerInputs.push_back(Current);
4599 C.getDefaultToolChain().getLTOMode(Args));
4602 if (NewCurrent == Current)
4605 if (
auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
4608 Current = NewCurrent;
4612 if (UseNewOffloadingDriver)
4614 &HIPAsmDeviceActions);
4617 else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
4621 if (Current->
getType() == types::TY_Nothing)
4627 if (Current && !HIPAsmDeviceActions.empty()) {
4628 assert(UseNewOffloadingDriver &&
"unexpected HIP asm bundle list");
4630 BundleInputs.append(HIPAsmDeviceActions);
4631 BundleInputs.push_back(Current);
4637 Actions.push_back(Current);
4640 if (!UseNewOffloadingDriver)
4641 OffloadBuilder->appendTopLevelActions(Actions, Current, InputArg);
4649 if (LinkerInputs.empty()) {
4652 if (!UseNewOffloadingDriver)
4653 OffloadBuilder->appendDeviceLinkActions(Actions);
4656 if (!LinkerInputs.empty()) {
4657 if (!UseNewOffloadingDriver)
4658 if (
Action *Wrapper = OffloadBuilder->makeHostLinkAction())
4659 LinkerInputs.push_back(Wrapper);
4664 }
else if (UseNewOffloadingDriver ||
4665 Args.hasArg(options::OPT_offload_link)) {
4673 bool LinkingIR = Args.hasArg(options::OPT_emit_llvm) &&
4674 C.getDefaultToolChain().getTriple().isSPIRV();
4675 types::ID LT = LinkingIR && !Diags.hasErrorOccurred() ? types::TY_LLVM_BC
4679 if (!UseNewOffloadingDriver)
4680 LA = OffloadBuilder->processHostLinkAction(LA);
4681 Actions.push_back(LA);
4685 if (!MergerInputs.empty())
4689 if (Args.hasArg(options::OPT_emit_interface_stubs)) {
4696 for (
auto &I : Inputs) {
4698 const Arg *InputArg = I.second;
4703 if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
4704 InputType == types::TY_Asm)
4709 for (
auto Phase : PhaseList) {
4713 "IFS Pipeline can only consist of Compile followed by IfsMerge.");
4718 if (InputType == types::TY_Object)
4725 assert(Phase == PhaseList.back() &&
4726 "merging must be final compilation step.");
4727 MergerInputs.push_back(Current);
4736 Actions.push_back(Current);
4740 if (!MergerInputs.empty())
4745 for (
auto Opt : {options::OPT_print_supported_cpus,
4746 options::OPT_print_supported_extensions,
4747 options::OPT_print_enabled_extensions}) {
4754 if (Arg *A = Args.getLastArg(Opt)) {
4755 if (Opt == options::OPT_print_supported_extensions &&
4756 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4757 !
C.getDefaultToolChain().getTriple().isAArch64() &&
4758 !
C.getDefaultToolChain().getTriple().isARM()) {
4759 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4760 <<
"--print-supported-extensions";
4763 if (Opt == options::OPT_print_enabled_extensions &&
4764 !
C.getDefaultToolChain().getTriple().isRISCV() &&
4765 !
C.getDefaultToolChain().getTriple().isAArch64()) {
4766 C.getDriver().Diag(diag::err_opt_not_valid_on_target)
4767 <<
"--print-enabled-extensions";
4774 *A,
IsFlangMode() ? types::TY_Fortran : types::TY_C);
4777 for (
auto &I : Inputs)
4782 llvm::Triple TargetTriple(
C.getDriver().getTargetTriple());
4783 if (TargetTriple.getOS() == llvm::Triple::Vulkan ||
4784 TargetTriple.getOS() == llvm::Triple::ShaderModel) {
4790 if (TC.requiresObjcopy(Args)) {
4791 Action *LastAction = Actions.back();
4793 if (LastAction->
getType() == types::TY_Object) {
4801 auto ValInfo = TC.getValidationInfo(Args);
4802 if (ValInfo.NeedsValidation) {
4803 Action *LastAction = Actions.back();
4804 if (LastAction->
getType() == types::TY_Object) {
4806 ValInfo.ProducesOutput ? types::TY_DX_CONTAINER : types::TY_Object;
4813 if (TC.requiresBinaryTranslation(Args)) {
4814 Action *LastAction = Actions.back();
4818 if (LastAction->
getType() == types::TY_DX_CONTAINER ||
4819 LastAction->
getType() == types::TY_Object)
4821 LastAction, types::TY_DX_CONTAINER));
4826 Args.ClaimAllArgs(options::OPT_cl_ignored_Group);
4832 const llvm::opt::DerivedArgList &Args,
4834 const llvm::Triple &Triple) {
4839 if (Triple.isNVPTX() &&
4841 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4842 <<
"CUDA" << ArchStr;
4844 }
else if (Triple.isAMDGPU() &&
4846 C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch)
4847 <<
"HIP" << ArchStr;
4855 llvm::StringMap<bool> Features;
4858 C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << ArchStr;
4870static std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
4872 llvm::Triple Triple) {
4873 if (!Triple.isAMDGPU())
4874 return std::nullopt;
4876 std::set<StringRef> ArchSet;
4877 llvm::copy(Archs, std::inserter(ArchSet, ArchSet.begin()));
4881llvm::SmallVector<BoundArch>
4885 if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
4886 Args.hasArgNoClaim(options::OPT_offload_arch_EQ,
4887 options::OPT_no_offload_arch_EQ)) {
4888 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
4890 << (Args.hasArgNoClaim(options::OPT_offload_arch_EQ)
4892 :
"--no-offload-arch");
4895 llvm::DenseSet<StringRef> Archs;
4896 for (
auto *Arg :
C.getArgsForToolChain(&TC, {}, Kind)) {
4899 if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) {
4900 for (StringRef
Arch : Arg->getValues()) {
4901 if (
Arch ==
"native" ||
Arch.empty()) {
4906 << llvm::toString(GPUsOrErr.takeError()) <<
"--offload-arch";
4910 for (
auto ArchStr : *GPUsOrErr) {
4912 C, Args, Args.MakeArgString(ArchStr), TC.
getTriple());
4913 if (!CanonicalStr.empty())
4914 Archs.insert(CanonicalStr);
4919 StringRef CanonicalStr =
4921 if (!CanonicalStr.empty())
4922 Archs.insert(CanonicalStr);
4927 }
else if (Arg->getOption().matches(options::OPT_no_offload_arch_EQ)) {
4928 for (StringRef
Arch : Arg->getValues()) {
4929 if (
Arch ==
"all") {
4934 Archs.erase(ArchStr);
4940 if (
auto ConflictingArchs =
4942 C.getDriver().Diag(clang::diag::err_drv_bad_offload_arch_combo)
4943 << ConflictingArchs->first << ConflictingArchs->second;
4946 if (Archs.empty()) {
4956 Archs.insert(StringRef());
4959 if (
auto *Arg =
C.getArgsForToolChain(&TC, {}, Kind)
4960 .getLastArg(options::OPT_march_EQ)) {
4961 Archs.insert(Arg->getValue());
4966 << TC.
getArchName() << llvm::toString(ArchsOrErr.takeError())
4967 <<
"--offload-arch";
4968 }
else if (!ArchsOrErr->empty()) {
4969 for (
auto Arch : *ArchsOrErr)
4970 Archs.insert(Args.MakeArgStringRef(
Arch));
4972 Archs.insert(StringRef());
4977 Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
4978 Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
4985 Result.reserve(Sorted.size());
4986 for (StringRef
Arch : Sorted)
4993 const InputTy &Input, StringRef CUID,
5003 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false);
5005 bool HIPRelocatableObj =
5007 Args.hasFlag(options::OPT_fhip_emit_relocatable,
5008 options::OPT_fno_hip_emit_relocatable,
false);
5010 if (!HIPNoRDC && HIPRelocatableObj)
5011 C.getDriver().Diag(diag::err_opt_not_valid_with_opt)
5012 <<
"-fhip-emit-relocatable"
5016 C.getDriver().Diag(diag::err_opt_not_valid_without_opt)
5017 <<
"-fhip-emit-relocatable"
5018 <<
"--offload-device-only";
5036 auto TCRange =
C.getOffloadToolChains(Kind);
5037 for (
auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
5038 ToolChains.push_back(TI->second);
5040 if (ToolChains.empty())
5044 const Arg *InputArg = Input.second;
5053 for (
const ToolChain *TC : ToolChains) {
5055 TCAndArchs.push_back(std::make_pair(TC,
Arch));
5056 DeviceActions.push_back(
5057 C.MakeAction<
InputAction>(*InputArg, InputType, CUID));
5061 if (DeviceActions.empty())
5067 HostAction->
getType() != types::TY_Nothing &&
5077 assert(Phase == PL.back() &&
"linking must be final compilation step.");
5086 auto *TCAndArch = TCAndArchs.begin();
5087 for (
Action *&A : DeviceActions) {
5088 if (A->
getType() == types::TY_Nothing)
5095 TCAndArch->first->getLTOMode(Args, Kind));
5099 HostAction->
getType() != types::TY_Nothing) {
5106 TCAndArch->second, Kind);
5108 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5118 for (
Action *&A : DeviceActions) {
5123 OffloadTriple && OffloadTriple->isSPIRV() &&
5124 (OffloadTriple->getOS() == llvm::Triple::OSType::AMDHSA ||
5125 OffloadTriple->getOS() == llvm::Triple::OSType::ChipStar);
5127 if ((A->
getType() != types::TY_Object && !IsHIPSPV &&
5128 A->
getType() != types::TY_LTO_BC) ||
5135 auto *TCAndArch = TCAndArchs.begin();
5136 for (
Action *A : DeviceActions) {
5137 DDeps.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5139 DDep.
add(*A, *TCAndArch->first, TCAndArch->second, Kind);
5144 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5146 DDep.
add(*Input, *TCAndArch->first, TCAndArch->second, Kind);
5155 bool ShouldBundleHIP =
5156 Args.hasFlag(options::OPT_gpu_bundle_output,
5157 options::OPT_no_gpu_bundle_output,
false) ||
5158 (!Args.getLastArg(options::OPT_no_gpu_bundle_output) && HIPNoRDC &&
5160 return A->
getType() != types::TY_Image;
5167 if (OffloadActions.empty())
5172 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false)) {
5176 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_CUDA_FATBIN);
5183 C.MakeAction<
LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
5184 DDep.
add(*FatbinAction,
5187 }
else if (HIPNoRDC) {
5190 if (HIPAsmBundleDeviceOut &&
5192 for (
Action *OA : OffloadActions)
5193 HIPAsmBundleDeviceOut->push_back(OA);
5207 DDep.
add(*PackagerAction,
5216 {},
C.getActiveOffloadKinds());
5225 bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](
Action *A) {
5226 return A->
getType() == types::TY_Nothing;
5230 {}, SingleDeviceOutput ? DDep : DDeps);
5231 return C.MakeAction<
OffloadAction>(HDep, SingleDeviceOutput ? DDep : DDeps);
5237 llvm::PrettyStackTraceString CrashInfo(
"Constructing phase actions");
5247 if (Args.hasArg(options::OPT_sycl_link) && Phase !=
phases::Link)
5253 llvm_unreachable(
"link action invalid here.");
5255 llvm_unreachable(
"ifsmerge action invalid here.");
5260 if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
5261 !Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
5262 OutputTy = types::TY_Dependencies;
5267 if (!Args.hasFlag(options::OPT_frewrite_includes,
5268 options::OPT_fno_rewrite_includes,
false) &&
5269 !Args.hasFlag(options::OPT_frewrite_imports,
5270 options::OPT_fno_rewrite_imports,
false) &&
5271 !Args.hasFlag(options::OPT_fdirectives_only,
5272 options::OPT_fno_directives_only,
false) &&
5276 "Cannot preprocess this input type!");
5282 if (Args.hasArg(options::OPT_extract_api))
5287 if (Input->
getType() == types::TY_CXXStdModule ||
5288 Input->
getType() == types::TY_PP_CXXStdModule)
5290 Input, getPrecompiledType(Input->
getType()));
5298 if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5299 (Input->
getType() == driver::types::TY_CXXModule ||
5300 Input->
getType() == driver::types::TY_PP_CXXModule) &&
5301 !Args.getLastArg(options::OPT__precompile) &&
5302 !Args.getLastArg(options::OPT__precompile_reduced_bmi))
5307 "Cannot precompile this input type!");
5311 const char *ModName =
nullptr;
5312 if (OutputTy == types::TY_PCH) {
5313 if (Arg *A = Args.getLastArg(options::OPT_fmodule_name_EQ))
5314 ModName = A->getValue();
5316 OutputTy = types::TY_ModuleFile;
5319 if (Args.hasArg(options::OPT_fsyntax_only)) {
5321 OutputTy = types::TY_Nothing;
5327 if (Args.hasArg(options::OPT_fsyntax_only))
5329 if (Args.hasArg(options::OPT_rewrite_objc))
5331 if (Args.hasArg(options::OPT_rewrite_legacy_objc))
5333 types::TY_RewrittenLegacyObjC);
5334 if (Args.hasArg(options::OPT__analyze))
5336 if (Args.hasArg(options::OPT_emit_ast))
5338 if (Args.hasArg(options::OPT_emit_cir))
5340 if (Args.hasArg(options::OPT_module_file_info))
5342 if (Args.hasArg(options::OPT_verify_pch))
5344 if (Args.hasArg(options::OPT_extract_api))
5351 if (!IsDeviceOffload) {
5353 if (Args.hasArg(options::OPT_ffat_lto_objects) &&
5354 !Args.hasArg(options::OPT_emit_llvm))
5355 Output = types::TY_PP_Asm;
5356 else if (Args.hasArg(options::OPT_S))
5357 Output = types::TY_LTO_IR;
5359 Output = types::TY_LTO_BC;
5363 if (Args.hasArg(options::OPT_emit_llvm)) {
5365 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
5367 !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
5371 Output = types::TY_PP_Asm;
5372 }
else if (Args.hasArg(options::OPT_S)) {
5373 Output = types::TY_LTO_IR;
5375 Output = types::TY_LTO_BC;
5379 if (Args.hasArg(options::OPT_emit_llvm) ||
5382 Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
5391 const llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
5392 if (
Target.isOSWindows() && Args.hasArg(options::OPT_marm64x)) {
5403 llvm_unreachable(
"invalid phase in ConstructPhaseAction");
5425 return Triple.isAMDGPU() || Triple.isNVPTX() || Triple.isSPIROrSPIRV();
5445 if (!OffloadJobs.isValid())
5446 D.
Diag(diag::err_drv_invalid_int_value)
5447 << OffloadJobs.A->getAsString(Args) << OffloadJobs.Value;
5449 OffloadJobs.A->claim();
5453 bool FoundCandidate =
false;
5454 for (
auto &Job :
C.getJobs()) {
5458 Job.setOffloadDeviceParallelJobGroup(
5460 FoundCandidate =
true;
5468 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
5470 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
5490 unsigned NumOutputs = 0;
5491 unsigned NumIfsOutputs = 0;
5492 for (
const Action *A :
C.getActions()) {
5502 (A->
getInputs().front()->getType() == types::TY_CXXStdModule ||
5503 A->
getInputs().front()->getType() == types::TY_PP_CXXStdModule))
5506 if (A->
getType() != types::TY_Nothing &&
5508 (A->
getType() == clang::driver::types::TY_IFS_CPP &&
5510 0 == NumIfsOutputs++) ||
5515 A->
getType() == types::TY_Nothing &&
5516 !
C.getArgs().hasArg(options::OPT_fsyntax_only))
5517 NumOutputs += A->
size();
5520 if (NumOutputs > 1) {
5521 Diag(clang::diag::err_drv_output_argument_with_multiple_files);
5522 FinalOutput =
nullptr;
5526 const llvm::Triple &RawTriple =
C.getDefaultToolChain().getTriple();
5530 if (RawTriple.isOSBinFormatMachO())
5531 for (
const Arg *A :
C.getArgs())
5532 if (A->getOption().matches(options::OPT_arch))
5536 std::map<std::pair<const Action *, std::string>,
InputInfoList> CachedResults;
5537 for (
Action *A :
C.getActions()) {
5544 const char *LinkingOutput =
nullptr;
5547 LinkingOutput = FinalOutput->getValue();
5556 C.getArgs().hasArgNoClaim(options::OPT_marm64x),
5557 LinkingOutput, CachedResults,
5564 for (
auto &J :
C.getJobs())
5565 J.InProcess =
false;
5570 C.setPostCallback([=](
const Command &Cmd,
int Res) {
5571 std::optional<llvm::sys::ProcessStatistics> ProcStat =
5576 const char *LinkingOutput =
nullptr;
5578 LinkingOutput = FinalOutput->getValue();
5585 using namespace llvm;
5588 <<
"output=" << LinkingOutput;
5589 outs() <<
", total="
5590 <<
format(
"%.3f", ProcStat->TotalTime.count() / 1000.) <<
" ms"
5592 <<
format(
"%.3f", ProcStat->UserTime.count() / 1000.) <<
" ms"
5593 <<
", mem=" << ProcStat->PeakMemory <<
" Kb\n";
5597 llvm::raw_string_ostream Out(Buffer);
5598 llvm::sys::printArg(Out, llvm::sys::path::filename(Cmd.
getExecutable()),
5601 llvm::sys::printArg(Out, LinkingOutput,
true);
5602 Out <<
',' << ProcStat->TotalTime.count() <<
','
5603 << ProcStat->UserTime.count() <<
',' << ProcStat->PeakMemory
5608 llvm::sys::fs::OF_Append |
5609 llvm::sys::fs::OF_Text);
5614 llvm::errs() <<
"ERROR: Cannot lock file "
5616 <<
toString(L.takeError()) <<
"\n";
5627 bool ReportUnusedArguments =
5628 !Diags.hasErrorOccurred() &&
5629 !
C.getArgs().hasArg(options::OPT_Qunused_arguments);
5632 (void)
C.getArgs().hasArg(options::OPT_fdriver_only);
5634 (void)
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
5637 (void)
C.getArgs().hasArg(options::OPT_driver_mode);
5638 (void)
C.getArgs().hasArg(options::OPT_rsp_quoting);
5640 bool HasAssembleJob = llvm::any_of(
C.getJobs(), [](
auto &J) {
5644 return strstr(J.getCreator().getShortName(),
"assembler");
5646 for (Arg *A :
C.getArgs()) {
5650 if (!A->isClaimed()) {
5656 const Option &Opt = A->getOption();
5657 if (Opt.getKind() == Option::FlagClass) {
5658 bool DuplicateClaimed =
false;
5660 for (
const Arg *AA :
C.getArgs().filtered(&Opt)) {
5661 if (AA->isClaimed()) {
5662 DuplicateClaimed =
true;
5667 if (DuplicateClaimed)
5673 if (!
IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
5675 !A->isIgnoredTargetSpecific() && !HasAssembleJob &&
5680 !
C.getActions().empty()) {
5681 Diag(diag::err_drv_unsupported_opt_for_target)
5683 }
else if (ReportUnusedArguments) {
5684 Diag(clang::diag::warn_drv_unused_argument)
5685 << A->getAsString(
C.getArgs());
5695class ToolSelector final {
5706 bool IsHostSelector;
5717 bool CanBeCollapsed =
true) {
5719 if (Inputs.size() != 1)
5722 Action *CurAction = *Inputs.begin();
5723 if (CanBeCollapsed &&
5729 if (
auto *OA = dyn_cast<OffloadAction>(CurAction)) {
5733 if (!IsHostSelector) {
5734 if (OA->hasSingleDeviceDependence(
true)) {
5736 OA->getSingleDeviceDependence(
true);
5737 if (CanBeCollapsed &&
5740 SavedOffloadAction.push_back(OA);
5741 return dyn_cast<JobAction>(CurAction);
5743 }
else if (OA->hasHostDependence()) {
5744 CurAction = OA->getHostDependence();
5745 if (CanBeCollapsed &&
5748 SavedOffloadAction.push_back(OA);
5749 return dyn_cast<JobAction>(CurAction);
5754 return dyn_cast<JobAction>(CurAction);
5758 bool canCollapseAssembleAction()
const {
5759 return TC.useIntegratedAs() && !SaveTemps &&
5760 !
C.getArgs().hasArg(options::OPT_via_file_asm) &&
5761 !
C.getArgs().hasArg(options::OPT__SLASH_FA) &&
5762 !
C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
5763 !
C.getArgs().hasArg(options::OPT_dxc_Fc);
5767 bool canCollapsePreprocessorAction()
const {
5768 return !
C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
5769 !
C.getArgs().hasArg(options::OPT_traditional_cpp) && !SaveTemps &&
5770 !
C.getArgs().hasArg(options::OPT_rewrite_objc);
5775 struct JobActionInfo final {
5777 const JobAction *JA =
nullptr;
5785 static void AppendCollapsedOffloadAction(
ActionList &CollapsedOffloadAction,
5786 ArrayRef<JobActionInfo> &ActionInfo,
5787 unsigned ElementNum) {
5788 assert(ElementNum <= ActionInfo.size() &&
"Invalid number of elements.");
5789 for (
unsigned I = 0; I < ElementNum; ++I)
5790 CollapsedOffloadAction.append(ActionInfo[I].SavedOffloadAction.begin(),
5791 ActionInfo[I].SavedOffloadAction.end());
5804 combineAssembleBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5807 if (ActionInfo.size() < 3 || !canCollapseAssembleAction())
5809 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5810 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5811 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[2].JA);
5812 if (!AJ || !BJ || !CJ)
5816 const Tool *T = TC.SelectTool(*CJ);
5829 const Tool *BT = TC.SelectTool(*BJ);
5837 Inputs = CJ->getInputs();
5838 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5842 const Tool *combineAssembleBackend(ArrayRef<JobActionInfo> ActionInfo,
5845 if (ActionInfo.size() < 2 || !canCollapseAssembleAction())
5847 auto *AJ = dyn_cast<AssembleJobAction>(ActionInfo[0].JA);
5848 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[1].JA);
5853 const Tool *T = TC.SelectTool(*BJ);
5860 Inputs = BJ->getInputs();
5861 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5865 const Tool *combineBackendCompile(ArrayRef<JobActionInfo> ActionInfo,
5868 if (ActionInfo.size() < 2)
5870 auto *BJ = dyn_cast<BackendJobAction>(ActionInfo[0].JA);
5871 auto *CJ = dyn_cast<CompileJobAction>(ActionInfo[1].JA);
5875 auto HasBitcodeInput = [](
const JobActionInfo &AI) {
5876 for (
auto &Input : AI.JA->getInputs())
5887 bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5888 if (SaveTemps && !InputIsBitcode)
5892 const Tool *T = TC.SelectTool(*CJ);
5905 Inputs = CJ->getInputs();
5906 AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
5915 void combineWithPreprocessor(
const Tool *T,
ActionList &Inputs,
5923 for (Action *A : Inputs) {
5924 auto *PJ = getPrevDependentAction({A}, PreprocessJobOffloadActions);
5926 NewInputs.push_back(A);
5932 CollapsedOffloadAction.append(PreprocessJobOffloadActions.begin(),
5933 PreprocessJobOffloadActions.end());
5934 NewInputs.append(PJ->input_begin(), PJ->input_end());
5940 ToolSelector(
const JobAction *BaseAction,
const ToolChain &TC,
5942 : TC(TC),
C(
C), BaseAction(BaseAction), SaveTemps(SaveTemps),
5944 assert(BaseAction &&
"Invalid base action.");
5960 SmallVector<JobActionInfo, 5> ActionChain(1);
5961 ActionChain.back().JA = BaseAction;
5962 while (ActionChain.back().JA) {
5963 const Action *CurAction = ActionChain.back().JA;
5966 ActionChain.resize(ActionChain.size() + 1);
5967 JobActionInfo &AI = ActionChain.back();
5971 getPrevDependentAction(CurAction->
getInputs(), AI.SavedOffloadAction);
5975 ActionChain.pop_back();
5983 const Tool *T = combineAssembleBackendCompile(ActionChain, Inputs,
5984 CollapsedOffloadAction);
5986 T = combineAssembleBackend(ActionChain, Inputs, CollapsedOffloadAction);
5988 T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
5994 combineWithPreprocessor(T, Inputs, CollapsedOffloadAction);
6007 std::string TriplePlusArch = TC->
getTriple().normalize();
6009 TriplePlusArch +=
"-";
6012 TriplePlusArch +=
"-";
6014 return TriplePlusArch;
6019 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6020 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6023 std::pair<const Action *, std::string> ActionTC = {
6025 auto CachedResult = CachedResults.find(ActionTC);
6026 if (CachedResult != CachedResults.end()) {
6027 return CachedResult->second;
6030 C, A, TC, BA, AtTopLevel, MultipleArchs, LinkingOutput, CachedResults,
6031 TargetDeviceOffloadKind);
6032 CachedResults[ActionTC] =
Result;
6037 const JobAction *JA,
const char *BaseInput,
6040 Args.getLastArg(options::OPT_ftime_trace, options::OPT_ftime_trace_EQ);
6051 if (!
Arch.empty()) {
6052 OffloadingPrefix +=
"-";
6053 OffloadingPrefix +=
Arch.ArchName;
6056 C.getDriver().isSaveTempsEnabled()) {
6063 if (A->getOption().matches(options::OPT_ftime_trace_EQ)) {
6064 Path = A->getValue();
6065 if (llvm::sys::fs::is_directory(Path)) {
6067 ? llvm::sys::path::stem(
Result.getFilename())
6068 : llvm::sys::path::stem(BaseInput));
6069 Tmp += OffloadingPrefix;
6071 llvm::sys::path::append(Path, Tmp);
6074 if (Arg *DumpDir = Args.getLastArgNoClaim(options::OPT_dumpdir)) {
6077 Path = DumpDir->getValue();
6078 Path += llvm::sys::path::stem(BaseInput);
6079 Path += OffloadingPrefix;
6081 }
else if (!OffloadingPrefix.empty()) {
6085 TraceName += OffloadingPrefix;
6086 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))
6087 Path = llvm::sys::path::parent_path(FinalOutput->getValue());
6088 llvm::sys::path::append(Path, TraceName);
6091 Path =
Result.getFilename();
6092 llvm::sys::path::replace_extension(Path,
"json");
6095 const char *ResultFile =
C.getArgs().MakeArgString(Path);
6096 C.addTimeTraceFile(ResultFile, JA);
6097 C.addResultFile(ResultFile, JA);
6102 bool AtTopLevel,
bool MultipleArchs,
const char *LinkingOutput,
6103 std::map<std::pair<const Action *, std::string>,
InputInfoList>
6106 llvm::PrettyStackTraceString CrashInfo(
"Building compilation jobs");
6110 BoundArch SavedBoundArch =
C.getCurrentBoundArch();
6111 C.setCurrentBoundArch(BA);
6112 auto RestoreBoundArch =
6113 llvm::scope_exit([&] {
C.setCurrentBoundArch(SavedBoundArch); });
6116 bool BuildingForOffloadDevice = TargetDeviceOffloadKind !=
Action::OFK_None;
6117 if (
const OffloadAction *OA = dyn_cast<OffloadAction>(A)) {
6149 if (OA->hasSingleDeviceDependence() || !OA->hasHostDependence()) {
6151 OA->doOnEachDeviceDependence([&](Action *DepA,
const ToolChain *DepTC,
6152 BoundArch DepBoundArch) {
6154 !DepBoundArch.
empty(),
6155 LinkingOutput, CachedResults,
6165 OA->doOnEachDependence(
6166 BuildingForOffloadDevice,
6167 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
6169 C, DepA, DepTC, DepBoundArch,
false,
6170 !DepBoundArch.
empty(), LinkingOutput,
6174 A = BuildingForOffloadDevice
6175 ? OA->getSingleDeviceDependence(
true)
6176 : OA->getHostDependence();
6180 std::pair<const Action *, std::string> ActionTC = {
6181 OA->getHostDependence(),
6183 auto It = CachedResults.find(ActionTC);
6184 if (It != CachedResults.end()) {
6186 Inputs.append(OffloadDependencesInputInfo);
6191 if (
const InputAction *IA = dyn_cast<InputAction>(A)) {
6194 const Arg &Input = IA->getInputArg();
6196 if (Input.getOption().matches(options::OPT_INPUT)) {
6197 const char *
Name = Input.getValue();
6200 return {InputInfo(A, &Input,
"")};
6203 if (
const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
6204 const ToolChain *TC;
6205 BoundArch ArchName = BAA->
getArch();
6207 if (!ArchName.
empty())
6208 TC = &getToolChain(
C.getArgs(),
6212 TC = &
C.getDefaultToolChain();
6215 MultipleArchs, LinkingOutput, CachedResults,
6216 TargetDeviceOffloadKind);
6227 const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
6230 return {InputInfo()};
6234 for (
const auto *OA : CollapsedOffloadActions)
6236 BuildingForOffloadDevice,
6237 [&](Action *DepA,
const ToolChain *DepTC, BoundArch DepBoundArch) {
6239 C, DepA, DepTC, DepBoundArch,
false,
6240 !DepBoundArch.
empty(), LinkingOutput,
6246 for (
const Action *Input : Inputs) {
6250 bool SubJobAtTopLevel =
6253 C, Input, TC, BA, SubJobAtTopLevel, MultipleArchs, LinkingOutput,
6258 const char *BaseInput = InputInfos[0].getBaseInput();
6259 for (
auto &Info : InputInfos) {
6260 if (Info.isFilename()) {
6261 BaseInput = Info.getBaseInput();
6268 if (JA->
getType() == types::TY_dSYM)
6269 BaseInput = InputInfos[0].getFilename();
6272 if (!OffloadDependencesInputInfo.empty())
6273 InputInfos.append(OffloadDependencesInputInfo.begin(),
6274 OffloadDependencesInputInfo.end());
6277 llvm::Triple EffectiveTriple;
6279 const ArgList &Args =
6281 if (InputInfos.size() != 1) {
6286 EffectiveTriple = llvm::Triple(
6289 RegisterEffectiveTriple TripleRAII(ToolTC, EffectiveTriple);
6294 if (
auto *UA = dyn_cast<OffloadUnbundlingJobAction>(JA)) {
6298 for (
auto &UI : UA->getDependentActionsInfo()) {
6300 "Unbundling with no offloading??");
6307 UI.DependentOffloadKind, UI.DependentToolChain->getTripleString(),
6309 auto CurI = InputInfo(
6318 UnbundlingResults.push_back(CurI);
6327 Arch = BoundArch(UI.DependentBoundArch);
6332 UI.DependentOffloadKind)}] = {
6338 std::pair<const Action *, std::string> ActionTC = {
6340 assert(CachedResults.find(ActionTC) != CachedResults.end() &&
6341 "Result does not exist??");
6342 Result = CachedResults[ActionTC].front();
6343 }
else if (JA->
getType() == types::TY_Nothing)
6344 Result = {InputInfo(A, BaseInput)};
6355 MultipleArchs, OffloadingPrefix),
6363 <<
'"' <<
" - \"" << T->
getName() <<
"\", inputs: [";
6364 for (
unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
6365 llvm::errs() << InputInfos[i].getAsString();
6367 llvm::errs() <<
", ";
6369 if (UnbundlingResults.empty())
6370 llvm::errs() <<
"], output: " <<
Result.getAsString() <<
"\n";
6372 llvm::errs() <<
"], outputs: [";
6373 for (
unsigned i = 0, e = UnbundlingResults.size(); i != e; ++i) {
6374 llvm::errs() << UnbundlingResults[i].getAsString();
6376 llvm::errs() <<
", ";
6378 llvm::errs() <<
"] \n";
6381 if (UnbundlingResults.empty())
6385 Args, LinkingOutput);
6391 llvm::Triple
Target(llvm::Triple::normalize(TargetTriple));
6392 return Target.isOSWindows() ?
"a.exe" :
"a.out";
6404 if (ArgValue.empty()) {
6406 Filename = BaseName;
6407 }
else if (llvm::sys::path::is_separator(Filename.back())) {
6409 llvm::sys::path::append(Filename, BaseName);
6412 if (!llvm::sys::path::has_extension(ArgValue)) {
6417 Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
6422 llvm::sys::path::replace_extension(Filename, Extension);
6425 return Args.MakeArgString(Filename.c_str());
6440 StringRef Suffix,
bool MultipleArchs,
6441 StringRef BoundArchStr,
6442 bool NeedUniqueDirectory)
const {
6444 Arg *A =
C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
6445 std::optional<std::string> CrashDirectory =
6447 ? std::string(A->getValue())
6448 : llvm::sys::Process::GetEnv(
"CLANG_CRASH_DIAGNOSTICS_DIR");
6449 if (CrashDirectory) {
6450 if (!
getVFS().exists(*CrashDirectory))
6451 llvm::sys::fs::create_directories(*CrashDirectory);
6453 llvm::sys::path::append(Path, Prefix);
6454 const char *Middle = !Suffix.empty() ?
"-%%%%%%." :
"-%%%%%%";
6455 if (std::error_code EC =
6456 llvm::sys::fs::createUniqueFile(Path + Middle + Suffix, TmpName)) {
6457 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6461 if (MultipleArchs && !BoundArchStr.empty()) {
6462 if (NeedUniqueDirectory) {
6464 llvm::sys::path::append(TmpName, Twine(Prefix) +
"-" + BoundArchStr +
6475 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6490 const char *BaseInput) {
6492 (
C.getArgs().hasArg(options::OPT_fmodule_output) ||
6493 C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
6498 return C.addResultFile(
C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
6503 bool AtTopLevel,
bool MultipleArchs,
6504 StringRef OffloadingPrefix)
const {
6507 llvm::PrettyStackTraceString CrashInfo(
"Computing output path");
6509 auto CreateTempOutputPath = [&](StringRef Prefix) {
6510 const char *Suffix =
6515 const llvm::Triple Triple(
C.getDriver().getTargetTriple());
6516 const bool NeedUniqueDirectory =
6519 Triple.isOSDarwin();
6521 NeedUniqueDirectory);
6526 (JA.
getInputs().front()->getType() == types::TY_CXXStdModule ||
6527 JA.
getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
6528 StringRef Filename = llvm::sys::path::filename(BaseInput);
6529 StringRef Stem = llvm::sys::path::stem(Filename);
6530 return CreateTempOutputPath(Stem);
6535 if (Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o))
6536 return C.addResultFile(FinalOutput->getValue(), &JA);
6540 if (
C.getArgs().hasArg(options::OPT__SLASH_P)) {
6542 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6544 if (Arg *A =
C.getArgs().getLastArg(options::OPT__SLASH_Fi))
6545 NameArg = A->getValue();
6546 return C.addResultFile(
6556 if (JA.
getType() == types::TY_ModuleFile &&
6557 C.getArgs().getLastArg(options::OPT_module_file_info)) {
6561 if (JA.
getType() == types::TY_PP_Asm &&
6562 C.getArgs().hasArg(options::OPT_dxc_Fc)) {
6563 StringRef FcValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fc);
6566 return C.addResultFile(
C.getArgs().MakeArgString(FcValue), &JA);
6569 if ((JA.
getType() == types::TY_Object &&
6570 C.getArgs().hasArg(options::OPT_dxc_Fo)) ||
6571 JA.
getType() == types::TY_DX_CONTAINER) {
6572 StringRef FoValue =
C.getArgs().getLastArgValue(options::OPT_dxc_Fo);
6573 assert((
C.getDefaultToolChain().getTriple().isDXIL() ||
6574 C.getDefaultToolChain().getTriple().isSPIRV()) &&
6575 "expected DXIL or SPIR-V triple for HLSL output path");
6580 if (TC.isLastOutputProducingJob(
C.getArgs(), JA.
getKind()) &&
6582 return C.addResultFile(
C.getArgs().MakeArgString(FoValue), &JA);
6583 StringRef
Name = llvm::sys::path::filename(BaseInput);
6584 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6590 if (JA.
getType() == types::TY_PP_Asm &&
6591 (
C.getArgs().hasArg(options::OPT__SLASH_FA) ||
6592 C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
6594 StringRef BaseName = llvm::sys::path::filename(BaseInput);
6595 StringRef FaValue =
C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
6596 return C.addResultFile(
6601 if (JA.
getType() == types::TY_API_INFO &&
6602 C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
6603 C.getArgs().hasArg(options::OPT_o))
6604 Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
6605 <<
C.getArgs().getLastArgValue(options::OPT_o);
6612 bool SpecifiedModuleOutput =
6613 C.getArgs().hasArg(options::OPT_fmodule_output) ||
6614 C.getArgs().hasArg(options::OPT_fmodule_output_EQ);
6615 if (MultipleArchs && SpecifiedModuleOutput)
6616 Diag(clang::diag::err_drv_module_output_with_multiple_arch);
6621 JA.
getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6622 assert(
C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
6628 !
C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
6630 StringRef
Name = llvm::sys::path::filename(BaseInput);
6631 return CreateTempOutputPath(
Name.split(
'.').first);
6640 ExternalPath +=
C.getArgs().getLastArg(options::OPT_dsym_dir)->getValue();
6645 llvm::sys::path::append(ExternalPath, llvm::sys::path::Style::posix,
6646 llvm::sys::path::filename(BasePath));
6647 BaseName = ExternalPath;
6649 BaseName = BasePath;
6651 BaseName = llvm::sys::path::filename(BasePath);
6654 const char *NamedOutput;
6656 if ((JA.
getType() == types::TY_Object || JA.
getType() == types::TY_LTO_BC ||
6657 JA.
getType() == types::TY_LLVM_BC ||
6658 JA.
getType() == types::TY_LLVM_IR) &&
6659 C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
6663 .getLastArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)
6667 }
else if (JA.
getType() == types::TY_Image &&
6668 C.getArgs().hasArg(options::OPT__SLASH_Fe,
6669 options::OPT__SLASH_o)) {
6673 .getLastArg(options::OPT__SLASH_Fe, options::OPT__SLASH_o)
6677 }
else if (JA.
getType() == types::TY_Image) {
6687 !
C.getArgs().hasFlag(options::OPT_fgpu_rdc,
6688 options::OPT_fno_gpu_rdc,
false);
6690 if (UseOutExtension) {
6692 llvm::sys::path::replace_extension(Output,
"");
6694 Output += OffloadingPrefix;
6695 if (MultipleArchs && !BoundArchStr.empty()) {
6697 Output.append(BoundArchStr);
6699 if (UseOutExtension)
6701 NamedOutput =
C.getArgs().MakeArgString(Output.c_str());
6704 NamedOutput =
C.getArgs().MakeArgString(
GetClPchPath(
C, BaseName));
6705 }
else if ((JA.
getType() == types::TY_Plist || JA.
getType() == types::TY_AST) &&
6706 C.getArgs().hasArg(options::OPT__SLASH_o)) {
6709 .getLastArg(options::OPT__SLASH_o)
6714 const char *Suffix =
6716 assert(Suffix &&
"All types used for output should have a suffix.");
6718 std::string::size_type End = std::string::npos;
6720 End = BaseName.rfind(
'.');
6722 Suffixed += OffloadingPrefix;
6723 if (MultipleArchs && !BoundArchStr.empty()) {
6725 Suffixed.append(BoundArchStr);
6730 auto IsAMDRDCInCompilePhase = [](
const JobAction &JA,
6731 const llvm::opt::DerivedArgList &Args) {
6738 (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
6740 Args.hasFlag(options::OPT_offload_new_driver,
6741 options::OPT_no_offload_new_driver,
true))) ||
6748 bool IsLinkerWrapper =
6750 bool IsEmitBitcode = JA.
getType() == types::TY_LLVM_BC &&
6751 (
C.getArgs().hasArg(options::OPT_emit_llvm) ||
6752 IsAMDRDCInCompilePhase(JA,
C.getArgs()));
6754 if (!AtTopLevel && (IsLinkerWrapper || IsEmitBitcode))
6758 NamedOutput =
C.getArgs().MakeArgString(Suffixed.c_str());
6762 if (!AtTopLevel &&
isSaveTempsObj() &&
C.getArgs().hasArg(options::OPT_o) &&
6763 JA.
getType() != types::TY_PCH) {
6764 Arg *FinalOutput =
C.getArgs().getLastArg(options::OPT_o);
6766 llvm::sys::path::remove_filename(TempPath);
6767 StringRef OutputFileName = llvm::sys::path::filename(NamedOutput);
6768 llvm::sys::path::append(TempPath, OutputFileName);
6769 NamedOutput =
C.getArgs().MakeArgString(TempPath.c_str());
6775 bool SameFile =
false;
6777 llvm::sys::fs::current_path(
Result);
6778 llvm::sys::path::append(
Result, BaseName);
6779 llvm::sys::fs::equivalent(BaseInput,
Result.c_str(), SameFile);
6782 StringRef
Name = llvm::sys::path::filename(BaseInput);
6783 std::pair<StringRef, StringRef> Split =
Name.split(
'.');
6787 return C.addTempFile(
C.getArgs().MakeArgString(TmpName));
6793 llvm::sys::path::remove_filename(BasePath);
6794 if (BasePath.empty())
6795 BasePath = NamedOutput;
6797 llvm::sys::path::append(BasePath, NamedOutput);
6798 return C.addResultFile(
C.getArgs().MakeArgString(BasePath.c_str()), &JA);
6801 return C.addResultFile(NamedOutput, &JA);
6807 -> std::optional<std::string> {
6810 for (
const auto &
Dir : P) {
6814 llvm::sys::path::append(P,
Name);
6815 if (llvm::sys::fs::exists(Twine(P)))
6816 return std::string(P);
6818 return std::nullopt;
6825 llvm::sys::path::append(R,
Name);
6826 if (llvm::sys::fs::exists(Twine(R)))
6827 return std::string(R);
6830 llvm::sys::path::append(P,
Name);
6831 if (llvm::sys::fs::exists(Twine(P)))
6832 return std::string(P);
6836 if (std::optional<std::string> IntrPath =
6839 llvm::sys::path::append(P,
Name);
6840 if (llvm::sys::fs::exists(P))
6841 return std::string(P);
6846 llvm::sys::path::append(D,
"..",
Name);
6847 if (llvm::sys::fs::exists(Twine(D)))
6848 return std::string(D);
6857 llvm::sys::path::append(R2,
"..",
"..",
Name);
6858 if (llvm::sys::fs::exists(Twine(R2)))
6859 return std::string(R2);
6861 return std::string(
Name);
6864void Driver::generatePrefixedToolNames(
6868 Names.emplace_back((TargetTriple +
"-" +
Tool).str());
6869 Names.emplace_back(
Tool);
6873 llvm::sys::path::append(Dir, Name);
6874 if (llvm::sys::fs::can_execute(Twine(Dir)))
6876 llvm::sys::path::remove_filename(Dir);
6882 generatePrefixedToolNames(
Name, TC, TargetSpecificExecutables);
6887 if (llvm::sys::fs::is_directory(PrefixDir)) {
6890 return std::string(P);
6893 if (llvm::sys::fs::can_execute(Twine(P)))
6894 return std::string(P);
6899 for (
const auto &TargetSpecificExecutable : TargetSpecificExecutables) {
6907 for (
const auto &Path : List) {
6910 return std::string(P);
6914 if (llvm::ErrorOr<std::string> P =
6915 llvm::sys::findProgramByName(TargetSpecificExecutable))
6919 return std::string(
Name);
6924 std::string error =
"<NOT PRESENT>";
6926 if (
C.getArgs().hasArg(options::OPT_nostdlib))
6931 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6948 llvm::sys::path::remove_filename(path);
6949 llvm::sys::path::append(path,
"libc++.modules.json");
6950 if (TC.
getVFS().exists(path))
6951 return static_cast<std::string
>(path);
6956 if (std::optional<std::string> result = evaluate(
"libc++.so"); result)
6959 return evaluate(
"libc++.a").value_or(error);
6963 auto evaluate = [&](
const char *library) -> std::optional<std::string> {
6967 llvm::sys::path::remove_filename(path);
6968 llvm::sys::path::append(path,
"libstdc++.modules.json");
6969 if (TC.
getVFS().exists(path))
6970 return static_cast<std::string
>(path);
6975 if (std::optional<std::string> result = evaluate(
"libstdc++.so"); result)
6978 return evaluate(
"libstdc++.a").value_or(error);
6987 std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
6989 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
6993 return std::string(Path);
6998 std::error_code EC = llvm::sys::fs::createUniqueDirectory(Prefix, Path);
7000 Diag(clang::diag::err_unable_to_make_temp) << EC.message();
7004 return std::string(Path);
7009 if (Arg *FpArg =
C.getArgs().getLastArg(options::OPT__SLASH_Fp)) {
7013 Output = FpArg->getValue();
7017 if (!llvm::sys::path::has_extension(Output))
7020 if (Arg *YcArg =
C.getArgs().getLastArg(options::OPT__SLASH_Yc))
7021 Output = YcArg->getValue();
7024 llvm::sys::path::replace_extension(Output,
".pch");
7026 return std::string(Output);
7029const ToolChain &Driver::getOffloadToolChain(
7031 const llvm::Triple &
Target,
const llvm::Triple &AuxTarget)
const {
7032 std::unique_ptr<ToolChain> &TC =
7033 ToolChains[
Target.str() +
"/" + AuxTarget.str()];
7034 std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str()];
7036 assert(HostTC &&
"Host toolchain for offloading doesn't exit?");
7039 switch (
Target.getOS()) {
7040 case llvm::Triple::CUDA:
7041 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7044 case llvm::Triple::AMDHSA:
7049 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
7050 HostTC.get(), Kind);
7058 switch (
Target.getArch()) {
7059 case llvm::Triple::amdgpu:
7060 case llvm::Triple::r600:
7061 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args,
7062 HostTC.get(), Kind);
7064 case llvm::Triple::spir:
7065 case llvm::Triple::spir64:
7066 case llvm::Triple::spirv:
7067 case llvm::Triple::spirv32:
7068 case llvm::Triple::spirv64:
7071 TC = std::make_unique<toolchains::SYCLToolChain>(*
this,
Target, *HostTC,
7075 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target,
7079 TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*
this,
Target,
7083 TC = std::make_unique<toolchains::CudaToolChain>(*
this,
Target, *HostTC,
7097 return getToolChain(Args,
Target);
7101const ToolChain &Driver::getToolChain(
const ArgList &Args,
7102 const llvm::Triple &
Target)
const {
7104 auto &TC = ToolChains[
Target.str()];
7106 switch (
Target.getOS()) {
7107 case llvm::Triple::AIX:
7108 TC = std::make_unique<toolchains::AIX>(*
this,
Target, Args);
7110 case llvm::Triple::Haiku:
7111 TC = std::make_unique<toolchains::Haiku>(*
this,
Target, Args);
7113 case llvm::Triple::Darwin:
7114 case llvm::Triple::MacOSX:
7115 case llvm::Triple::IOS:
7116 case llvm::Triple::TvOS:
7117 case llvm::Triple::WatchOS:
7118 case llvm::Triple::XROS:
7119 case llvm::Triple::DriverKit:
7120 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7122 case llvm::Triple::DragonFly:
7123 TC = std::make_unique<toolchains::DragonFly>(*
this,
Target, Args);
7125 case llvm::Triple::OpenBSD:
7126 TC = std::make_unique<toolchains::OpenBSD>(*
this,
Target, Args);
7128 case llvm::Triple::NetBSD:
7129 TC = std::make_unique<toolchains::NetBSD>(*
this,
Target, Args);
7131 case llvm::Triple::FreeBSD:
7133 TC = std::make_unique<toolchains::PPCFreeBSDToolChain>(*
this,
Target,
7136 TC = std::make_unique<toolchains::FreeBSD>(*
this,
Target, Args);
7138 case llvm::Triple::Linux:
7139 case llvm::Triple::ELFIAMCU:
7140 if (
Target.getArch() == llvm::Triple::hexagon)
7141 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7143 else if ((
Target.getVendor() == llvm::Triple::MipsTechnologies) &&
7144 !
Target.hasEnvironment())
7145 TC = std::make_unique<toolchains::MipsLLVMToolChain>(*
this,
Target,
7148 TC = std::make_unique<toolchains::PPCLinuxToolChain>(*
this,
Target,
7150 else if (
Target.getArch() == llvm::Triple::ve)
7151 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7152 else if (
Target.isOHOSFamily())
7153 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7154 else if (
Target.isWALI())
7155 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7157 TC = std::make_unique<toolchains::LFILinux>(*
this,
Target, Args);
7159 TC = std::make_unique<toolchains::Linux>(*
this,
Target, Args);
7161 case llvm::Triple::Fuchsia:
7162 TC = std::make_unique<toolchains::Fuchsia>(*
this,
Target, Args);
7164 case llvm::Triple::Managarm:
7165 TC = std::make_unique<toolchains::Managarm>(*
this,
Target, Args);
7167 case llvm::Triple::Serenity:
7168 TC = std::make_unique<toolchains::Serenity>(*
this,
Target, Args);
7170 case llvm::Triple::Solaris:
7171 TC = std::make_unique<toolchains::Solaris>(*
this,
Target, Args);
7173 case llvm::Triple::CUDA:
7174 TC = std::make_unique<toolchains::NVPTXToolChain>(*
this,
Target, Args);
7176 case llvm::Triple::AMDHSA: {
7177 if (
Target.getArch() == llvm::Triple::spirv64) {
7178 TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*
this,
Target,
7184 TC = std::make_unique<toolchains::AMDGPUToolChain>(
7186 ShouldLinkDeviceLibs);
7190 case llvm::Triple::AMDPAL:
7191 case llvm::Triple::Mesa3D:
7192 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7194 case llvm::Triple::UEFI:
7195 TC = std::make_unique<toolchains::UEFI>(*
this,
Target, Args);
7197 case llvm::Triple::Win32:
7198 switch (
Target.getEnvironment()) {
7200 if (
Target.isOSBinFormatELF())
7201 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7202 else if (
Target.isOSBinFormatMachO())
7203 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7205 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7207 case llvm::Triple::GNU:
7208 TC = std::make_unique<toolchains::MinGW>(*
this,
Target, Args);
7210 case llvm::Triple::Cygnus:
7211 TC = std::make_unique<toolchains::Cygwin>(*
this,
Target, Args);
7213 case llvm::Triple::Itanium:
7214 TC = std::make_unique<toolchains::CrossWindowsToolChain>(*
this,
Target,
7217 case llvm::Triple::MSVC:
7218 case llvm::Triple::UnknownEnvironment:
7219 if (Args.getLastArgValue(options::OPT_fuse_ld_EQ)
7220 .starts_with_insensitive(
"bfd"))
7221 TC = std::make_unique<toolchains::CrossWindowsToolChain>(
7225 std::make_unique<toolchains::MSVCToolChain>(*
this,
Target, Args);
7229 case llvm::Triple::PS4:
7230 TC = std::make_unique<toolchains::PS4CPU>(*
this,
Target, Args);
7232 case llvm::Triple::PS5:
7233 TC = std::make_unique<toolchains::PS5CPU>(*
this,
Target, Args);
7235 case llvm::Triple::Hurd:
7236 TC = std::make_unique<toolchains::Hurd>(*
this,
Target, Args);
7238 case llvm::Triple::LiteOS:
7239 TC = std::make_unique<toolchains::OHOS>(*
this,
Target, Args);
7241 case llvm::Triple::ZOS:
7242 TC = std::make_unique<toolchains::ZOS>(*
this,
Target, Args);
7244 case llvm::Triple::Vulkan:
7245 case llvm::Triple::ShaderModel:
7246 if ((
Target.getArch() == llvm::Triple::spirv32 ||
7247 Target.getArch() == llvm::Triple::spirv64) &&
7249 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7251 TC = std::make_unique<toolchains::HLSLToolChain>(*
this,
Target, Args);
7253 case llvm::Triple::ChipStar:
7254 TC = std::make_unique<toolchains::HIPSPVToolChain>(*
this,
Target, Args);
7259 switch (
Target.getArch()) {
7260 case llvm::Triple::tce:
7261 TC = std::make_unique<toolchains::TCEToolChain>(*
this,
Target, Args);
7263 case llvm::Triple::tcele:
7264 TC = std::make_unique<toolchains::TCELEToolChain>(*
this,
Target, Args);
7266 case llvm::Triple::tcele64:
7268 std::make_unique<toolchains::TCELE64ToolChain>(*
this,
Target, Args);
7270 case llvm::Triple::hexagon:
7271 TC = std::make_unique<toolchains::HexagonToolChain>(*
this,
Target,
7274 case llvm::Triple::lanai:
7275 TC = std::make_unique<toolchains::LanaiToolChain>(*
this,
Target, Args);
7277 case llvm::Triple::xcore:
7278 TC = std::make_unique<toolchains::XCoreToolChain>(*
this,
Target, Args);
7280 case llvm::Triple::wasm32:
7281 case llvm::Triple::wasm64:
7282 TC = std::make_unique<toolchains::WebAssembly>(*
this,
Target, Args);
7284 case llvm::Triple::avr:
7285 TC = std::make_unique<toolchains::AVRToolChain>(*
this,
Target, Args);
7287 case llvm::Triple::msp430:
7288 TC = std::make_unique<toolchains::MSP430ToolChain>(*
this,
Target, Args);
7290 case llvm::Triple::riscv32:
7291 case llvm::Triple::riscv64:
7292 case llvm::Triple::riscv32be:
7293 case llvm::Triple::riscv64be:
7294 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7296 case llvm::Triple::ve:
7297 TC = std::make_unique<toolchains::VEToolChain>(*
this,
Target, Args);
7299 case llvm::Triple::spirv32:
7300 case llvm::Triple::spirv64:
7301 TC = std::make_unique<toolchains::SPIRVToolChain>(*
this,
Target, Args);
7303 case llvm::Triple::csky:
7304 TC = std::make_unique<toolchains::CSKYToolChain>(*
this,
Target, Args);
7306 case llvm::Triple::amdgpu:
7307 case llvm::Triple::r600:
7308 TC = std::make_unique<toolchains::AMDGPUToolChain>(*
this,
Target, Args);
7312 TC = std::make_unique<toolchains::BareMetal>(*
this,
Target, Args);
7313 else if (
Target.isOSBinFormatELF())
7314 TC = std::make_unique<toolchains::Generic_ELF>(*
this,
Target, Args);
7315 else if (
Target.isAppleFirmware())
7316 TC = std::make_unique<toolchains::DarwinClang>(*
this,
Target, Args);
7317 else if (
Target.isAppleMachO())
7318 TC = std::make_unique<toolchains::AppleMachO>(*
this,
Target, Args);
7319 else if (
Target.isOSBinFormatMachO())
7320 TC = std::make_unique<toolchains::MachO>(*
this,
Target, Args);
7322 TC = std::make_unique<toolchains::Generic_GCC>(*
this,
Target, Args);
7332 if (JA.
size() != 1 ||
7347 if (JA.
size() != 1 ||
7361 if (Args.hasArg(options::OPT_emit_static_lib))
7372 unsigned &Micro,
bool &HadExtra) {
7375 Major = Minor = Micro = 0;
7379 if (Str.consumeInteger(10, Major))
7383 if (!Str.consume_front(
"."))
7386 if (Str.consumeInteger(10, Minor))
7390 if (!Str.consume_front(
"."))
7393 if (Str.consumeInteger(10, Micro))
7411 unsigned CurDigit = 0;
7412 while (CurDigit < Digits.size()) {
7414 if (Str.consumeInteger(10, Digit))
7416 Digits[CurDigit] = Digit;
7419 if (!Str.consume_front(
"."))
7428llvm::opt::Visibility
7429Driver::getOptionVisibilityMask(
bool UseDriverMode)
const {
7441const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
7457 llvm_unreachable(
"Unhandled Mode");
7461 return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group,
false);
7466 if (Args.hasFlag(options::OPT_fsave_optimization_record,
7467 options::OPT_fno_save_optimization_record,
false))
7471 if (Args.hasFlag(options::OPT_fsave_optimization_record_EQ,
7472 options::OPT_fno_save_optimization_record,
false))
7476 if (Args.hasFlag(options::OPT_foptimization_record_file_EQ,
7477 options::OPT_fno_save_optimization_record,
false))
7481 if (Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
7482 options::OPT_fno_save_optimization_record,
false))
7489 static StringRef OptName =
7491 llvm::StringRef Opt;
7492 for (StringRef Arg : Args) {
7493 if (!Arg.starts_with(OptName))
7499 return Opt.consume_front(OptName) ? Opt :
"";
7506 llvm::BumpPtrAllocator &Alloc,
7507 llvm::vfs::FileSystem *FS) {
7516 for (
const char *F : Args) {
7517 if (strcmp(F,
"--rsp-quoting=posix") == 0)
7519 else if (strcmp(F,
"--rsp-quoting=windows") == 0)
7520 RSPQuoting = Windows;
7526 bool MarkEOLs = ClangCLMode;
7528 llvm::cl::TokenizerCallback Tokenizer;
7529 if (RSPQuoting == Windows || (RSPQuoting ==
Default && ClangCLMode))
7530 Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
7532 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
7534 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with(
"-cc1"))
7537 llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
7538 ECtx.setMarkEOLs(MarkEOLs);
7542 if (llvm::Error Err = ECtx.expandResponseFiles(Args))
7546 auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
7547 [](
const char *A) {
return A !=
nullptr; });
7548 if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with(
"-cc1")) {
7551 auto newEnd = std::remove(Args.begin(), Args.end(),
nullptr);
7552 Args.resize(newEnd - Args.begin());
7556 return llvm::Error::success();
7560 return SavedStrings.insert(S).first->getKeyData();
7594 llvm::StringSet<> &SavedStrings) {
7597 if (Edit[0] ==
'^') {
7598 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7599 OS <<
"### Adding argument " << Str <<
" at beginning\n";
7600 Args.insert(Args.begin() + 1, Str);
7601 }
else if (Edit[0] ==
'+') {
7602 const char *Str =
GetStableCStr(SavedStrings, Edit.substr(1));
7603 OS <<
"### Adding argument " << Str <<
" at end\n";
7604 Args.push_back(Str);
7605 }
else if (Edit[0] ==
's' && Edit[1] ==
'/' && Edit.ends_with(
"/") &&
7606 Edit.slice(2, Edit.size() - 1).contains(
'/')) {
7607 StringRef MatchPattern = Edit.substr(2).split(
'/').first;
7608 StringRef ReplPattern = Edit.substr(2).split(
'/').second;
7609 ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1);
7611 for (
unsigned i = 1, e = Args.size(); i != e; ++i) {
7613 if (Args[i] ==
nullptr)
7615 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
7617 if (Repl != Args[i]) {
7618 OS <<
"### Replacing '" << Args[i] <<
"' with '" << Repl <<
"'\n";
7622 }
else if (Edit[0] ==
'x' || Edit[0] ==
'X') {
7623 auto Option = Edit.substr(1);
7624 for (
unsigned i = 1; i < Args.size();) {
7625 if (Option == Args[i]) {
7626 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7627 Args.erase(Args.begin() + i);
7628 if (Edit[0] ==
'X') {
7629 if (i < Args.size()) {
7630 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7631 Args.erase(Args.begin() + i);
7633 OS <<
"### Invalid X edit, end of command line!\n";
7638 }
else if (Edit[0] ==
'O') {
7639 for (
unsigned i = 1; i < Args.size();) {
7640 const char *A = Args[i];
7644 if (A[0] ==
'-' && A[1] ==
'O' &&
7645 (A[2] ==
'\0' || (A[3] ==
'\0' && (A[2] ==
's' || A[2] ==
'z' ||
7646 (
'0' <= A[2] && A[2] <=
'9'))))) {
7647 OS <<
"### Deleting argument " << Args[i] <<
'\n';
7648 Args.erase(Args.begin() + i);
7652 OS <<
"### Adding argument " << Edit <<
" at end\n";
7653 Args.push_back(
GetStableCStr(SavedStrings,
'-' + Edit.str()));
7655 OS <<
"### Unrecognized edit: " << Edit <<
"\n";
7660 const char *OverrideStr,
7661 llvm::StringSet<> &SavedStrings,
7662 StringRef EnvVar, raw_ostream *OS) {
7664 OS = &llvm::nulls();
7666 if (OverrideStr[0] ==
'#') {
7668 OS = &llvm::nulls();
7671 *OS <<
"### " << EnvVar <<
": " << OverrideStr <<
"\n";
7675 const char *S = OverrideStr;
7677 const char *End = ::strchr(S,
' ');
7679 End = S + strlen(S);
static Decl::Kind getKind(const Decl *D)
static std::string getOffloadDeviceCC1ParallelJobGroup(const Command &Job)
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)
std::multiset< llvm::Triple > TripleSet
static void printArgList(raw_ostream &OS, const llvm::opt::ArgList &Args)
static const char BugReportMsg[]
static std::string GetTriplePlusArchString(const ToolChain *TC, BoundArch BA, Action::OffloadKind OffloadKind)
Return a string that uniquely identifies the result of a job.
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 void markOffloadDeviceCC1JobsForParallelExecution(Compilation &C)
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 void handleTimeTrace(Compilation &C, const ArgList &Args, const JobAction *JA, const char *BaseInput, const InputInfo &Result)
static unsigned PrintActions1(const Compilation &C, Action *A, std::map< Action *, unsigned > &Ids, Twine Indent={}, int Kind=TopLevelAction)
static 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 llvm::Triple computeTargetTriple(const Driver &D, StringRef TargetTriple, const ArgList &Args, StringRef ArchName="")
Compute target triple from args.
static const char * GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S)
static bool isOffloadDeviceCC1JobCandidate(Command &Job)
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 void claimAndDiagnoseOffloadJobs(const Driver &D, const ArgList &Args)
static bool shouldBundleHIPAsmWithNewDriver(const Compilation &C, const llvm::opt::DerivedArgList &Args, const Driver &D)
HIP non-RDC -S for AMDGCN: emit host and device assembly separately and bundle with clang-offload-bun...
static TripleSet inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind)
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)
Result
Implement __builtin_bit_cast and related operations.
llvm::MachO::FileType FileType
llvm::MachO::Target Target
static StringRef getTriple(const Command &Job)
This file defines functionality to support driver managed builds for compilations which use Clang mod...
static bool hasFlag(SVal val, ProgramStateRef state)
This file pulls in all built-in SSAF extractor and format registrations by referencing their anchor s...
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.
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.
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...
BoundArch getOffloadingArch() const
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 propagateDeviceOffloadInfo(OffloadKind OKind, BoundArch OArch, const ToolChain *OToolChain)
Set the device offload info of this action and propagate it to its dependences.
void propagateHostOffloadInfo(unsigned OKinds, BoundArch OArch)
Append the host offload info of this action and propagate it to its dependences.
void setHostOffloadInfo(unsigned OKinds, BoundArch OArch)
@ 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.
void setBoundArch(BoundArch BA)
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)
BoundArch getBoundArch() const
Return the bound architecture for this command, if any.
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...
llvm::SmallVector< BoundArch > 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 SysRoot
sysroot, if present
std::string UserConfigDir
User directory for config files.
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.
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.
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeProgram(llvm::ArrayRef< llvm::StringRef > Args) const
Action * BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args, const InputTy &Input, StringRef CUID, Action *HostAction, ActionList *HIPAsmBundleDeviceOut=nullptr) const
BuildOffloadingActions - Construct the list of actions to perform for the offloading toolchain that w...
Action * ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input, Action::OffloadKind TargetDeviceOffloadKind=Action::OFK_None, LTOKind TargetLTOMode=LTOK_None) const
ConstructAction - Construct the appropriate action to do for Phase on the Input, taking in to account...
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
const char * GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, BoundArch BA, bool AtTopLevel, bool MultipleArchs, StringRef NormalizedTriple) const
GetNamedOutputPath - Return the name to use for the output of the action JA.
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]+)(.
std::string Name
The name the driver was invoked as.
Driver(StringRef DriverExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, std::string Title="clang LLVM compiler", IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
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.
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.
InputInfoList BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, BoundArch BA, 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...
void PrintVersion(const Compilation &C, raw_ostream &OS) const
PrintVersion - Print the driver version.
bool ShouldUseFlangCompiler(const JobAction &JA) const
ShouldUseFlangCompiler - Should the flang compiler be used to handle this action.
bool DiagnoseInputExistence(StringRef Value, types::ID Ty, bool TypoCorrect) const
Check that the file referenced by Value exists.
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.
const char * CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix, bool MultipleArchs=false, StringRef BoundArchStr={}, bool NeedUniqueDirectory=false) const
Creates a temp file.
@ 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.
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.
std::string DriverExecutable
The original path to the driver executable.
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.
const ActionList & getActions() const
Get each of the individual arrays.
void add(Action &A, const ToolChain &TC, BoundArch BA, OffloadKind OKind)
Add an action along with the associated toolchain, bound arch, and offload kind.
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, BoundArch BA, OffloadKind Kind)
Register information about a dependent action.
Set a ToolChain's effective triple.
void buildStdModuleManifestInputs(ArrayRef< StdModuleManifest::Module > ManifestEntries, Compilation &C, InputList &Inputs)
Constructs compilation inputs for each module listed in the provided Standard library module manifest...
void runModulesDriver(Compilation &C, ArrayRef< StdModuleManifest::Module > ManifestEntries)
Scans the compilation inputs for module dependencies and adjusts the compilation to build and supply ...
llvm::Expected< StdModuleManifest > readStdModuleManifest(llvm::StringRef ManifestPath, llvm::vfs::FileSystem &VFS)
Reads the Standard library module manifest at ManifestPath.
void diagnoseModulesDriverArgs(llvm::opt::DerivedArgList &DAL, DiagnosticsEngine &Diags)
Emits diagnostics for arguments incompatible with -fmodules-driver.
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.
bool isHLSL(ID Id)
isHLSL - Is this an HLSL input.
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.
LTOKind
Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
ModuleHeaderMode
Whether headers used to construct C++20 module units should be looked up by the path supplied on the ...
llvm::opt::Arg * makeInputArg(llvm::opt::DerivedArgList &Args, const llvm::opt::OptTable &Opts, StringRef Value, bool Claim=true)
Creates and adds a synthesized input argument.
SmallVector< InputInfo, 4 > InputInfoList
std::pair< types::ID, const llvm::opt::Arg * > InputTy
A list of inputs and their types for the given arguments.
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.
llvm::SmallVector< InputTy, 16 > InputList
A list of inputs and their types for the given arguments.
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)
void printAvailableFormats(llvm::raw_ostream &OS)
Print the list of available serialization formats.
void printAvailableTUSummaryExtractors(llvm::raw_ostream &OS)
Print the list of available TUSummaryExtractors.
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)
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)
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
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)
llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple, OffloadArch ID)
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.
Represents a bound architecture for offload / multiple architecture compilation.
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.
The parsed Standard library module manifest.
std::vector< Module > Modules